Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net

Pull networking fixes from David Miller:
 "A pile of fixes in response to yesterday's big merge.  The SCTP HMAC
  thing hasn't been addressed yet, I'll take care of that myself if Neil
  and Vlad don't show signs of life by tomorrow.

   1) Use after free of SKB in tuntap code.  Fix by Eric Dumazet,
      reported by Dave Jones.

   2) NFC LLCP code emits annoying kernel log message, triggerable by
      the user.  From Dave Jones.

   3) Fix several endianness bugs noticed by sparse in the bridging
      code, from Stephen Hemminger.

   4) Ipv6 NDISC code doesn't take padding into account properly, fix
      from YOSHIFUJI Hideaki.

   5) Add missing docs to ethtool_flow_ext struct, from Yan Burman."

* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net:
  bridge: fix icmpv6 endian bug and other sparse warnings
  net: ethool: Document struct ethtool_flow_ext
  ndisc: Fix padding error in link-layer address option.
  tuntap: dont use skb after netif_rx_ni(skb)
  nfc: remove noisy message from llcp_sock_sendmsg
diff --git a/Documentation/ABI/obsolete/sysfs-driver-hid-roccat-koneplus b/Documentation/ABI/obsolete/sysfs-driver-hid-roccat-koneplus
index c2a270b..833fd59 100644
--- a/Documentation/ABI/obsolete/sysfs-driver-hid-roccat-koneplus
+++ b/Documentation/ABI/obsolete/sysfs-driver-hid-roccat-koneplus
@@ -8,3 +8,41 @@
 		When written, this file sets the number of the startup profile
 		and the mouse activates this profile immediately.
 		Please use actual_profile, it does the same thing.
+Users:		http://roccat.sourceforge.net
+
+What:		/sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/koneplus/roccatkoneplus<minor>/firmware_version
+Date:		October 2010
+Contact:	Stefan Achatz <erazor_de@users.sourceforge.net>
+Description:	When read, this file returns the raw integer version number of the
+		firmware reported by the mouse. Using the integer value eases
+		further usage in other programs. To receive the real version
+		number the decimal point has to be shifted 2 positions to the
+		left. E.g. a returned value of 121 means 1.21
+		This file is readonly.
+		Please read binary attribute info which contains firmware version.
+Users:		http://roccat.sourceforge.net
+
+What:		/sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/koneplus/roccatkoneplus<minor>/profile[1-5]_buttons
+Date:		August 2010
+Contact:	Stefan Achatz <erazor_de@users.sourceforge.net>
+Description:	The mouse can store 5 profiles which can be switched by the
+		press of a button. A profile is split in settings and buttons.
+		profile_buttons holds information about button layout.
+		When read, these files return the respective profile buttons.
+		The returned data is 77 bytes in size.
+		This file is readonly.
+		Write control to select profile and read profile_buttons instead.
+Users:		http://roccat.sourceforge.net
+
+What:		/sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/koneplus/roccatkoneplus<minor>/profile[1-5]_settings
+Date:		August 2010
+Contact:	Stefan Achatz <erazor_de@users.sourceforge.net>
+Description:	The mouse can store 5 profiles which can be switched by the
+		press of a button. A profile is split in settings and buttons.
+		profile_settings holds information like resolution, sensitivity
+		and light effects.
+		When read, these files return the respective profile settings.
+		The returned data is 43 bytes in size.
+		This file is readonly.
+		Write control to select profile and read profile_settings instead.
+Users:		http://roccat.sourceforge.net
\ No newline at end of file
diff --git a/Documentation/ABI/obsolete/sysfs-driver-hid-roccat-kovaplus b/Documentation/ABI/obsolete/sysfs-driver-hid-roccat-kovaplus
new file mode 100644
index 0000000..4a98e02
--- /dev/null
+++ b/Documentation/ABI/obsolete/sysfs-driver-hid-roccat-kovaplus
@@ -0,0 +1,66 @@
+What:		/sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/kovaplus/roccatkovaplus<minor>/actual_cpi
+Date:		January 2011
+Contact:	Stefan Achatz <erazor_de@users.sourceforge.net>
+Description:	The integer value of this attribute ranges from 1-4.
+		When read, this attribute returns the number of the active
+		cpi level.
+		This file is readonly.
+		Has never been used. If bookkeeping is done, it's done in userland tools.
+Users:		http://roccat.sourceforge.net
+
+What:		/sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/kovaplus/roccatkovaplus<minor>/actual_sensitivity_x
+Date:		January 2011
+Contact:	Stefan Achatz <erazor_de@users.sourceforge.net>
+Description:	The integer value of this attribute ranges from 1-10.
+		When read, this attribute returns the number of the actual
+		sensitivity in x direction.
+		This file is readonly.
+		Has never been used. If bookkeeping is done, it's done in userland tools.
+Users:		http://roccat.sourceforge.net
+
+What:		/sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/kovaplus/roccatkovaplus<minor>/actual_sensitivity_y
+Date:		January 2011
+Contact:	Stefan Achatz <erazor_de@users.sourceforge.net>
+Description:	The integer value of this attribute ranges from 1-10.
+		When read, this attribute returns the number of the actual
+		sensitivity in y direction.
+		This file is readonly.
+		Has never been used. If bookkeeping is done, it's done in userland tools.
+Users:		http://roccat.sourceforge.net
+
+What:		/sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/kovaplus/roccatkovaplus<minor>/firmware_version
+Date:		January 2011
+Contact:	Stefan Achatz <erazor_de@users.sourceforge.net>
+Description:	When read, this file returns the raw integer version number of the
+		firmware reported by the mouse. Using the integer value eases
+		further usage in other programs. To receive the real version
+		number the decimal point has to be shifted 2 positions to the
+		left. E.g. a returned value of 121 means 1.21
+		This file is readonly.
+		Obsoleted by binary sysfs attribute "info".
+Users:		http://roccat.sourceforge.net
+
+What:		/sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/kovaplus/roccatkovaplus<minor>/profile[1-5]_buttons
+Date:		January 2011
+Contact:	Stefan Achatz <erazor_de@users.sourceforge.net>
+Description:	The mouse can store 5 profiles which can be switched by the
+		press of a button. A profile is split in settings and buttons.
+		profile_buttons holds information about button layout.
+		When read, these files return the respective profile buttons.
+		The returned data is 23 bytes in size.
+		This file is readonly.
+		Write control to select profile and read profile_buttons instead.
+Users:		http://roccat.sourceforge.net
+
+What:		/sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/kovaplus/roccatkovaplus<minor>/profile[1-5]_settings
+Date:		January 2011
+Contact:	Stefan Achatz <erazor_de@users.sourceforge.net>
+Description:	The mouse can store 5 profiles which can be switched by the
+		press of a button. A profile is split in settings and buttons.
+		profile_settings holds information like resolution, sensitivity
+		and light effects.
+		When read, these files return the respective profile settings.
+		The returned data is 16 bytes in size.
+		This file is readonly.
+		Write control to select profile and read profile_settings instead.
+Users:		http://roccat.sourceforge.net
diff --git a/Documentation/ABI/obsolete/sysfs-driver-hid-roccat-pyra b/Documentation/ABI/obsolete/sysfs-driver-hid-roccat-pyra
new file mode 100644
index 0000000..87ac87e
--- /dev/null
+++ b/Documentation/ABI/obsolete/sysfs-driver-hid-roccat-pyra
@@ -0,0 +1,73 @@
+What:		/sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/pyra/roccatpyra<minor>/actual_cpi
+Date:		August 2010
+Contact:	Stefan Achatz <erazor_de@users.sourceforge.net>
+Description:	It is possible to switch the cpi setting of the mouse with the
+		press of a button.
+		When read, this file returns the raw number of the actual cpi
+		setting reported by the mouse. This number has to be further
+		processed to receive the real dpi value.
+
+		VALUE DPI
+		1     400
+		2     800
+		4     1600
+
+		This file is readonly.
+		Has never been used. If bookkeeping is done, it's done in userland tools.
+Users:		http://roccat.sourceforge.net
+
+What:		/sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/pyra/roccatpyra<minor>/actual_profile
+Date:		August 2010
+Contact:	Stefan Achatz <erazor_de@users.sourceforge.net>
+Description:	When read, this file returns the number of the actual profile in
+		range 0-4.
+		This file is readonly.
+		Please use binary attribute "settings" which provides this information.
+Users:		http://roccat.sourceforge.net
+
+What:		/sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/pyra/roccatpyra<minor>/firmware_version
+Date:		August 2010
+Contact:	Stefan Achatz <erazor_de@users.sourceforge.net>
+Description:	When read, this file returns the raw integer version number of the
+		firmware reported by the mouse. Using the integer value eases
+		further usage in other programs. To receive the real version
+		number the decimal point has to be shifted 2 positions to the
+		left. E.g. a returned value of 138 means 1.38
+		This file is readonly.
+		Please use binary attribute "info" which provides this information.
+Users:		http://roccat.sourceforge.net
+
+What:		/sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/pyra/roccatpyra<minor>/profile[1-5]_buttons
+Date:		August 2010
+Contact:	Stefan Achatz <erazor_de@users.sourceforge.net>
+Description:	The mouse can store 5 profiles which can be switched by the
+		press of a button. A profile is split in settings and buttons.
+		profile_buttons holds information about button layout.
+		When read, these files return the respective profile buttons.
+		The returned data is 19 bytes in size.
+		This file is readonly.
+		Write control to select profile and read profile_buttons instead.
+Users:		http://roccat.sourceforge.net
+
+What:		/sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/pyra/roccatpyra<minor>/profile[1-5]_settings
+Date:		August 2010
+Contact:	Stefan Achatz <erazor_de@users.sourceforge.net>
+Description:	The mouse can store 5 profiles which can be switched by the
+		press of a button. A profile is split in settings and buttons.
+		profile_settings holds information like resolution, sensitivity
+		and light effects.
+		When read, these files return the respective profile settings.
+		The returned data is 13 bytes in size.
+		This file is readonly.
+		Write control to select profile and read profile_settings instead.
+Users:		http://roccat.sourceforge.net
+
+What:		/sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/pyra/roccatpyra<minor>/startup_profile
+Date:		August 2010
+Contact:	Stefan Achatz <erazor_de@users.sourceforge.net>
+Description:	The integer value of this attribute ranges from 0-4.
+                When read, this attribute returns the number of the profile
+                that's active when the mouse is powered on.
+		This file is readonly.
+		Please use binary attribute "settings" which provides this information.
+Users:		http://roccat.sourceforge.net
diff --git a/Documentation/ABI/testing/dev-kmsg b/Documentation/ABI/testing/dev-kmsg
index 7e7e07a..bb820be 100644
--- a/Documentation/ABI/testing/dev-kmsg
+++ b/Documentation/ABI/testing/dev-kmsg
@@ -92,7 +92,7 @@
 		The flags field carries '-' by default. A 'c' indicates a
 		fragment of a line. All following fragments are flagged with
 		'+'. Note, that these hints about continuation lines are not
-		neccessarily correct, and the stream could be interleaved with
+		necessarily correct, and the stream could be interleaved with
 		unrelated messages, but merging the lines in the output
 		usually produces better human readable results. A similar
 		logic is used internally when messages are printed to the
diff --git a/Documentation/ABI/testing/sysfs-bus-pci b/Documentation/ABI/testing/sysfs-bus-pci
index dff1f48..1ce5ae3 100644
--- a/Documentation/ABI/testing/sysfs-bus-pci
+++ b/Documentation/ABI/testing/sysfs-bus-pci
@@ -222,3 +222,37 @@
 		satisfied too.  Reading this attribute will show the current
 		value of d3cold_allowed bit.  Writing this attribute will set
 		the value of d3cold_allowed bit.
+
+What:		/sys/bus/pci/devices/.../sriov_totalvfs
+Date:		November 2012
+Contact:	Donald Dutile <ddutile@redhat.com>
+Description:
+		This file appears when a physical PCIe device supports SR-IOV.
+		Userspace applications can read this file to determine the
+		maximum number of Virtual Functions (VFs) a PCIe physical
+		function (PF) can support. Typically, this is the value reported
+		in the PF's SR-IOV extended capability structure's TotalVFs
+		element.  Drivers have the ability at probe time to reduce the
+		value read from this file via the pci_sriov_set_totalvfs()
+		function.
+
+What:		/sys/bus/pci/devices/.../sriov_numvfs
+Date:		November 2012
+Contact:	Donald Dutile <ddutile@redhat.com>
+Description:
+		This file appears when a physical PCIe device supports SR-IOV.
+		Userspace applications can read and write to this file to
+		determine and control the enablement or disablement of Virtual
+		Functions (VFs) on the physical function (PF). A read of this
+		file will return the number of VFs that are enabled on this PF.
+		A number written to this file will enable the specified
+		number of VFs. A userspace application would typically read the
+		file and check that the value is zero, and then write the number
+		of VFs that should be enabled on the PF; the value written
+		should be less than or equal to the value in the sriov_totalvfs
+		file. A userspace application wanting to disable the VFs would
+		write a zero to this file. The core ensures that valid values
+		are written to this file, and returns errors when values are not
+		valid.  For example, writing a 2 to this file when sriov_numvfs
+		is not 0 and not 2 already will return an error. Writing a 10
+		when the value of sriov_totalvfs is 8 will return an error.
diff --git a/Documentation/ABI/testing/sysfs-devices-power b/Documentation/ABI/testing/sysfs-devices-power
index 7fc2997..9d43e76 100644
--- a/Documentation/ABI/testing/sysfs-devices-power
+++ b/Documentation/ABI/testing/sysfs-devices-power
@@ -164,7 +164,7 @@
 Description:
 		The /sys/devices/.../wakeup_prevent_sleep_time_ms attribute
 		contains the total time the device has been preventing
-		opportunistic transitions to sleep states from occuring.
+		opportunistic transitions to sleep states from occurring.
 		This attribute is read-only.  If the device is not enabled to
 		wake up the system from sleep states, this attribute is not
 		present.
diff --git a/Documentation/ABI/testing/sysfs-driver-hid-roccat-isku b/Documentation/ABI/testing/sysfs-driver-hid-roccat-isku
index 189dc43..9eca5a1 100644
--- a/Documentation/ABI/testing/sysfs-driver-hid-roccat-isku
+++ b/Documentation/ABI/testing/sysfs-driver-hid-roccat-isku
@@ -117,6 +117,14 @@
 		which profile and key to read.
 Users:		http://roccat.sourceforge.net
 
+What:		/sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/isku/roccatisku<minor>/reset
+Date:		November 2012
+Contact:	Stefan Achatz <erazor_de@users.sourceforge.net>
+Description:	When written, this file lets one reset the device.
+		The data has to be 3 bytes long.
+		This file is writeonly.
+Users:		http://roccat.sourceforge.net
+
 What:		/sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/isku/roccatisku<minor>/control
 Date:		June 2011
 Contact:	Stefan Achatz <erazor_de@users.sourceforge.net>
diff --git a/Documentation/ABI/testing/sysfs-driver-hid-roccat-koneplus b/Documentation/ABI/testing/sysfs-driver-hid-roccat-koneplus
index 65e6e5d..7bd776f 100644
--- a/Documentation/ABI/testing/sysfs-driver-hid-roccat-koneplus
+++ b/Documentation/ABI/testing/sysfs-driver-hid-roccat-koneplus
@@ -9,15 +9,12 @@
 		and the mouse activates this profile immediately.
 Users:		http://roccat.sourceforge.net
 
-What:		/sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/koneplus/roccatkoneplus<minor>/firmware_version
-Date:		October 2010
+What:		/sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/koneplus/roccatkoneplus<minor>/info
+Date:		November 2012
 Contact:	Stefan Achatz <erazor_de@users.sourceforge.net>
-Description:	When read, this file returns the raw integer version number of the
-		firmware reported by the mouse. Using the integer value eases
-		further usage in other programs. To receive the real version
-		number the decimal point has to be shifted 2 positions to the
-		left. E.g. a returned value of 121 means 1.21
-		This file is readonly.
+Description:	When read, this file returns general data like firmware version.
+		When written, the device can be reset.
+		The data is 8 bytes long.
 Users:		http://roccat.sourceforge.net
 
 What:		/sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/koneplus/roccatkoneplus<minor>/macro
@@ -42,18 +39,8 @@
 		The mouse will reject invalid data.
 		Which profile to write is determined by the profile number
 		contained in the data.
-		This file is writeonly.
-Users:		http://roccat.sourceforge.net
-
-What:		/sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/koneplus/roccatkoneplus<minor>/profile[1-5]_buttons
-Date:		August 2010
-Contact:	Stefan Achatz <erazor_de@users.sourceforge.net>
-Description:	The mouse can store 5 profiles which can be switched by the
-		press of a button. A profile is split in settings and buttons.
-		profile_buttons holds information about button layout.
-		When read, these files return the respective profile buttons.
-		The returned data is 77 bytes in size.
-		This file is readonly.
+		Before reading this file, control has to be written to select
+		which profile to read.
 Users:		http://roccat.sourceforge.net
 
 What:		/sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/koneplus/roccatkoneplus<minor>/profile_settings
@@ -68,19 +55,8 @@
 		The mouse will reject invalid data.
 		Which profile to write is determined by the profile number
 		contained in the data.
-		This file is writeonly.
-Users:		http://roccat.sourceforge.net
-
-What:		/sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/koneplus/roccatkoneplus<minor>/profile[1-5]_settings
-Date:		August 2010
-Contact:	Stefan Achatz <erazor_de@users.sourceforge.net>
-Description:	The mouse can store 5 profiles which can be switched by the
-		press of a button. A profile is split in settings and buttons.
-		profile_settings holds information like resolution, sensitivity
-		and light effects.
-		When read, these files return the respective profile settings.
-		The returned data is 43 bytes in size.
-		This file is readonly.
+		Before reading this file, control has to be written to select
+		which profile to read.
 Users:		http://roccat.sourceforge.net
 
 What:		/sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/koneplus/roccatkoneplus<minor>/sensor
@@ -104,9 +80,9 @@
 Date:		October 2010
 Contact:	Stefan Achatz <erazor_de@users.sourceforge.net>
 Description:	When written a calibration process for the tracking control unit
-		can be initiated/cancelled.
-		The data has to be 3 bytes long.
-		This file is writeonly.
+		can be initiated/cancelled. Also lets one read/write sensor
+		registers.
+		The data has to be 4 bytes long.
 Users:		http://roccat.sourceforge.net
 
 What:		/sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/koneplus/roccatkoneplus<minor>/tcu_image
diff --git a/Documentation/ABI/testing/sysfs-driver-hid-roccat-kovaplus b/Documentation/ABI/testing/sysfs-driver-hid-roccat-kovaplus
index 20f937c..a10404f 100644
--- a/Documentation/ABI/testing/sysfs-driver-hid-roccat-kovaplus
+++ b/Documentation/ABI/testing/sysfs-driver-hid-roccat-kovaplus
@@ -1,12 +1,3 @@
-What:		/sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/kovaplus/roccatkovaplus<minor>/actual_cpi
-Date:		January 2011
-Contact:	Stefan Achatz <erazor_de@users.sourceforge.net>
-Description:	The integer value of this attribute ranges from 1-4.
-		When read, this attribute returns the number of the active
-		cpi level.
-		This file is readonly.
-Users:		http://roccat.sourceforge.net
-
 What:		/sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/kovaplus/roccatkovaplus<minor>/actual_profile
 Date:		January 2011
 Contact:	Stefan Achatz <erazor_de@users.sourceforge.net>
@@ -18,33 +9,12 @@
 		active when the mouse is powered on.
 Users:		http://roccat.sourceforge.net
 
-What:		/sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/kovaplus/roccatkovaplus<minor>/actual_sensitivity_x
-Date:		January 2011
+What:		/sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/kovaplus/roccatkovaplus<minor>/info
+Date:		November 2012
 Contact:	Stefan Achatz <erazor_de@users.sourceforge.net>
-Description:	The integer value of this attribute ranges from 1-10.
-		When read, this attribute returns the number of the actual
-		sensitivity in x direction.
-		This file is readonly.
-Users:		http://roccat.sourceforge.net
-
-What:		/sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/kovaplus/roccatkovaplus<minor>/actual_sensitivity_y
-Date:		January 2011
-Contact:	Stefan Achatz <erazor_de@users.sourceforge.net>
-Description:	The integer value of this attribute ranges from 1-10.
-		When read, this attribute returns the number of the actual
-		sensitivity in y direction.
-		This file is readonly.
-Users:		http://roccat.sourceforge.net
-
-What:		/sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/kovaplus/roccatkovaplus<minor>/firmware_version
-Date:		January 2011
-Contact:	Stefan Achatz <erazor_de@users.sourceforge.net>
-Description:	When read, this file returns the raw integer version number of the
-		firmware reported by the mouse. Using the integer value eases
-		further usage in other programs. To receive the real version
-		number the decimal point has to be shifted 2 positions to the
-		left. E.g. a returned value of 121 means 1.21
-		This file is readonly.
+Description:	When read, this file returns general data like firmware version.
+		When written, the device can be reset.
+		The data is 6 bytes long.
 Users:		http://roccat.sourceforge.net
 
 What:		/sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/kovaplus/roccatkovaplus<minor>/profile_buttons
@@ -58,18 +28,8 @@
 		The mouse will reject invalid data.
 		Which profile to write is determined by the profile number
 		contained in the data.
-		This file is writeonly.
-Users:		http://roccat.sourceforge.net
-
-What:		/sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/kovaplus/roccatkovaplus<minor>/profile[1-5]_buttons
-Date:		January 2011
-Contact:	Stefan Achatz <erazor_de@users.sourceforge.net>
-Description:	The mouse can store 5 profiles which can be switched by the
-		press of a button. A profile is split in settings and buttons.
-		profile_buttons holds information about button layout.
-		When read, these files return the respective profile buttons.
-		The returned data is 23 bytes in size.
-		This file is readonly.
+		Before reading this file, control has to be written to select
+		which profile to read.
 Users:		http://roccat.sourceforge.net
 
 What:		/sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/kovaplus/roccatkovaplus<minor>/profile_settings
@@ -84,17 +44,6 @@
 		The mouse will reject invalid data.
 		Which profile to write is determined by the profile number
 		contained in the data.
-		This file is writeonly.
-Users:		http://roccat.sourceforge.net
-
-What:		/sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/kovaplus/roccatkovaplus<minor>/profile[1-5]_settings
-Date:		January 2011
-Contact:	Stefan Achatz <erazor_de@users.sourceforge.net>
-Description:	The mouse can store 5 profiles which can be switched by the
-		press of a button. A profile is split in settings and buttons.
-		profile_settings holds information like resolution, sensitivity
-		and light effects.
-		When read, these files return the respective profile settings.
-		The returned data is 16 bytes in size.
-		This file is readonly.
+		Before reading this file, control has to be written to select
+		which profile to read.
 Users:		http://roccat.sourceforge.net
diff --git a/Documentation/ABI/testing/sysfs-driver-hid-roccat-lua b/Documentation/ABI/testing/sysfs-driver-hid-roccat-lua
new file mode 100644
index 0000000..31c6c4c
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-driver-hid-roccat-lua
@@ -0,0 +1,7 @@
+What:		/sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/control
+Date:		October 2012
+Contact:	Stefan Achatz <erazor_de@users.sourceforge.net>
+Description:	When written, cpi, button and light settings can be configured.
+		When read, actual cpi setting and sensor data are returned.
+		The data has to be 8 bytes long.
+Users:		http://roccat.sourceforge.net
diff --git a/Documentation/ABI/testing/sysfs-driver-hid-roccat-pyra b/Documentation/ABI/testing/sysfs-driver-hid-roccat-pyra
index 3f8de50..9fa9de3 100644
--- a/Documentation/ABI/testing/sysfs-driver-hid-roccat-pyra
+++ b/Documentation/ABI/testing/sysfs-driver-hid-roccat-pyra
@@ -1,37 +1,9 @@
-What:		/sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/pyra/roccatpyra<minor>/actual_cpi
-Date:		August 2010
+What:		/sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/pyra/roccatpyra<minor>/info
+Date:		November 2012
 Contact:	Stefan Achatz <erazor_de@users.sourceforge.net>
-Description:	It is possible to switch the cpi setting of the mouse with the
-		press of a button.
-		When read, this file returns the raw number of the actual cpi
-		setting reported by the mouse. This number has to be further
-		processed to receive the real dpi value.
-
-		VALUE DPI
-		1     400
-		2     800
-		4     1600
-
-		This file is readonly.
-Users:		http://roccat.sourceforge.net
-
-What:		/sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/pyra/roccatpyra<minor>/actual_profile
-Date:		August 2010
-Contact:	Stefan Achatz <erazor_de@users.sourceforge.net>
-Description:	When read, this file returns the number of the actual profile in
-		range 0-4.
-		This file is readonly.
-Users:		http://roccat.sourceforge.net
-
-What:		/sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/pyra/roccatpyra<minor>/firmware_version
-Date:		August 2010
-Contact:	Stefan Achatz <erazor_de@users.sourceforge.net>
-Description:	When read, this file returns the raw integer version number of the
-		firmware reported by the mouse. Using the integer value eases
-		further usage in other programs. To receive the real version
-		number the decimal point has to be shifted 2 positions to the
-		left. E.g. a returned value of 138 means 1.38
-		This file is readonly.
+Description:	When read, this file returns general data like firmware version.
+		When written, the device can be reset.
+		The data is 6 bytes long.
 Users:		http://roccat.sourceforge.net
 
 What:		/sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/pyra/roccatpyra<minor>/profile_settings
@@ -46,19 +18,8 @@
 		The mouse will reject invalid data.
 		Which profile to write is determined by the profile number
 		contained in the data.
-		This file is writeonly.
-Users:		http://roccat.sourceforge.net
-
-What:		/sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/pyra/roccatpyra<minor>/profile[1-5]_settings
-Date:		August 2010
-Contact:	Stefan Achatz <erazor_de@users.sourceforge.net>
-Description:	The mouse can store 5 profiles which can be switched by the
-		press of a button. A profile is split in settings and buttons.
-		profile_settings holds information like resolution, sensitivity
-		and light effects.
-		When read, these files return the respective profile settings.
-		The returned data is 13 bytes in size.
-		This file is readonly.
+		Before reading this file, control has to be written to select
+		which profile to read.
 Users:		http://roccat.sourceforge.net
 
 What:		/sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/pyra/roccatpyra<minor>/profile_buttons
@@ -72,27 +33,8 @@
 		The mouse will reject invalid data.
 		Which profile to write is determined by the profile number
 		contained in the data.
-		This file is writeonly.
-Users:		http://roccat.sourceforge.net
-
-What:		/sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/pyra/roccatpyra<minor>/profile[1-5]_buttons
-Date:		August 2010
-Contact:	Stefan Achatz <erazor_de@users.sourceforge.net>
-Description:	The mouse can store 5 profiles which can be switched by the
-		press of a button. A profile is split in settings and buttons.
-		profile_buttons holds information about button layout.
-		When read, these files return the respective profile buttons.
-		The returned data is 19 bytes in size.
-		This file is readonly.
-Users:		http://roccat.sourceforge.net
-
-What:		/sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/pyra/roccatpyra<minor>/startup_profile
-Date:		August 2010
-Contact:	Stefan Achatz <erazor_de@users.sourceforge.net>
-Description:	The integer value of this attribute ranges from 0-4.
-                When read, this attribute returns the number of the profile
-                that's active when the mouse is powered on.
-		This file is readonly.
+		Before reading this file, control has to be written to select
+		which profile to read.
 Users:		http://roccat.sourceforge.net
 
 What:		/sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/pyra/roccatpyra<minor>/settings
diff --git a/Documentation/ABI/testing/sysfs-driver-hid-roccat-savu b/Documentation/ABI/testing/sysfs-driver-hid-roccat-savu
index b42922c..f1e02a9 100644
--- a/Documentation/ABI/testing/sysfs-driver-hid-roccat-savu
+++ b/Documentation/ABI/testing/sysfs-driver-hid-roccat-savu
@@ -40,8 +40,8 @@
 Date:		Mai 2012
 Contact:	Stefan Achatz <erazor_de@users.sourceforge.net>
 Description:	When read, this file returns general data like firmware version.
+		When written, the device can be reset.
 		The data is 8 bytes long.
-		This file is readonly.
 Users:		http://roccat.sourceforge.net
 
 What:		/sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/savu/roccatsavu<minor>/macro
@@ -74,4 +74,3 @@
 		This file allows reading and writing of the mouse sensors registers.
 		The data has to be 4 bytes long.
 Users:		http://roccat.sourceforge.net
-
diff --git a/Documentation/ABI/testing/sysfs-driver-ppi b/Documentation/ABI/testing/sysfs-driver-ppi
index 97a003e..7d1435b 100644
--- a/Documentation/ABI/testing/sysfs-driver-ppi
+++ b/Documentation/ABI/testing/sysfs-driver-ppi
@@ -5,7 +5,7 @@
 Description:
 		This folder includes the attributes related with PPI (Physical
 		Presence Interface). Only if TPM is supported by BIOS, this
-		folder makes sence. The folder path can be got by command
+		folder makes sense. The folder path can be got by command
 		'find /sys/ -name 'pcrs''. For the detail information of PPI,
 		please refer to the PPI specification from
 		http://www.trustedcomputinggroup.org/
diff --git a/Documentation/ABI/testing/sysfs-profiling b/Documentation/ABI/testing/sysfs-profiling
index b02d8b8..8a8e466 100644
--- a/Documentation/ABI/testing/sysfs-profiling
+++ b/Documentation/ABI/testing/sysfs-profiling
@@ -1,13 +1,13 @@
-What:		/sys/kernel/profile
+What:		/sys/kernel/profiling
 Date:		September 2008
 Contact:	Dave Hansen <dave@linux.vnet.ibm.com>
 Description:
-		/sys/kernel/profile is the runtime equivalent
+		/sys/kernel/profiling is the runtime equivalent
 		of the boot-time profile= option.
 
 		You can get the same effect running:
 
-			echo 2 > /sys/kernel/profile
+			echo 2 > /sys/kernel/profiling
 
 		as you would by issuing profile=2 on the boot
 		command line.
diff --git a/Documentation/DocBook/writing-an-alsa-driver.tmpl b/Documentation/DocBook/writing-an-alsa-driver.tmpl
index cab4ec5..fb32aea 100644
--- a/Documentation/DocBook/writing-an-alsa-driver.tmpl
+++ b/Documentation/DocBook/writing-an-alsa-driver.tmpl
@@ -433,9 +433,9 @@
   /* chip-specific constructor
    * (see "Management of Cards and Components")
    */
-  static int __devinit snd_mychip_create(struct snd_card *card,
-                                         struct pci_dev *pci,
-                                         struct mychip **rchip)
+  static int snd_mychip_create(struct snd_card *card,
+                               struct pci_dev *pci,
+                               struct mychip **rchip)
   {
           struct mychip *chip;
           int err;
@@ -475,8 +475,8 @@
   }
 
   /* constructor -- see "Constructor" sub-section */
-  static int __devinit snd_mychip_probe(struct pci_dev *pci,
-                               const struct pci_device_id *pci_id)
+  static int snd_mychip_probe(struct pci_dev *pci,
+                              const struct pci_device_id *pci_id)
   {
           static int dev;
           struct snd_card *card;
@@ -526,7 +526,7 @@
   }
 
   /* destructor -- see the "Destructor" sub-section */
-  static void __devexit snd_mychip_remove(struct pci_dev *pci)
+  static void snd_mychip_remove(struct pci_dev *pci)
   {
           snd_card_free(pci_get_drvdata(pci));
           pci_set_drvdata(pci, NULL);
@@ -542,9 +542,8 @@
       <para>
         The real constructor of PCI drivers is the <function>probe</function> callback.
       The <function>probe</function> callback and other component-constructors which are called
-      from the <function>probe</function> callback should be defined with
-      the <parameter>__devinit</parameter> prefix. You 
-      cannot use the <parameter>__init</parameter> prefix for them,
+      from the <function>probe</function> callback cannot be used with
+      the <parameter>__init</parameter> prefix
       because any PCI device could be a hotplug device. 
       </para>
 
@@ -728,7 +727,7 @@
         <informalexample>
           <programlisting>
 <![CDATA[
-  static void __devexit snd_mychip_remove(struct pci_dev *pci)
+  static void snd_mychip_remove(struct pci_dev *pci)
   {
           snd_card_free(pci_get_drvdata(pci));
           pci_set_drvdata(pci, NULL);
@@ -1059,14 +1058,6 @@
       </para>
 
       <para>
-        As further notes, the destructors (both
-      <function>snd_mychip_dev_free</function> and
-      <function>snd_mychip_free</function>) cannot be defined with
-      the <parameter>__devexit</parameter> prefix, because they may be
-      called from the constructor, too, at the false path. 
-      </para>
-
-      <para>
       For a device which allows hotplugging, you can use
       <function>snd_card_free_when_closed</function>.  This one will
       postpone the destruction until all devices are closed.
@@ -1120,9 +1111,9 @@
   }
 
   /* chip-specific constructor */
-  static int __devinit snd_mychip_create(struct snd_card *card,
-                                         struct pci_dev *pci,
-                                         struct mychip **rchip)
+  static int snd_mychip_create(struct snd_card *card,
+                               struct pci_dev *pci,
+                               struct mychip **rchip)
   {
           struct mychip *chip;
           int err;
@@ -1200,7 +1191,7 @@
           .name = KBUILD_MODNAME,
           .id_table = snd_mychip_ids,
           .probe = snd_mychip_probe,
-          .remove = __devexit_p(snd_mychip_remove),
+          .remove = snd_mychip_remove,
   };
 
   /* module initialization */
@@ -1465,11 +1456,6 @@
       </para>
 
       <para>
-      Again, remember that you cannot
-      use the <parameter>__devexit</parameter> prefix for this destructor. 
-      </para>
-
-      <para>
       We didn't implement the hardware disabling part in the above.
       If you need to do this, please note that the destructor may be
       called even before the initialization of the chip is completed.
@@ -1619,7 +1605,7 @@
           .name = KBUILD_MODNAME,
           .id_table = snd_mychip_ids,
           .probe = snd_mychip_probe,
-          .remove = __devexit_p(snd_mychip_remove),
+          .remove = snd_mychip_remove,
   };
 ]]>
           </programlisting>
@@ -1630,11 +1616,7 @@
         The <structfield>probe</structfield> and
       <structfield>remove</structfield> functions have already
       been defined in the previous sections.
-      The <structfield>remove</structfield> function should
-      be defined with the 
-      <function>__devexit_p()</function> macro, so that it's not
-      defined for built-in (and non-hot-pluggable) case. The
-      <structfield>name</structfield> 
+      The <structfield>name</structfield>
       field is the name string of this device. Note that you must not
       use a slash <quote>/</quote> in this string. 
       </para>
@@ -1665,9 +1647,7 @@
       <para>
         Note that these module entries are tagged with
       <parameter>__init</parameter> and 
-      <parameter>__exit</parameter> prefixes, not
-      <parameter>__devinit</parameter> nor
-      <parameter>__devexit</parameter>.
+      <parameter>__exit</parameter> prefixes.
       </para>
 
       <para>
@@ -1918,7 +1898,7 @@
    */
 
   /* create a pcm device */
-  static int __devinit snd_mychip_new_pcm(struct mychip *chip)
+  static int snd_mychip_new_pcm(struct mychip *chip)
   {
           struct snd_pcm *pcm;
           int err;
@@ -1957,7 +1937,7 @@
         <informalexample>
           <programlisting>
 <![CDATA[
-  static int __devinit snd_mychip_new_pcm(struct mychip *chip)
+  static int snd_mychip_new_pcm(struct mychip *chip)
   {
           struct snd_pcm *pcm;
           int err;
@@ -2124,7 +2104,7 @@
           ....
   }
 
-  static int __devinit snd_mychip_new_pcm(struct mychip *chip)
+  static int snd_mychip_new_pcm(struct mychip *chip)
   {
           struct snd_pcm *pcm;
           ....
@@ -3399,7 +3379,7 @@
 	  <title>Definition of a Control</title>
           <programlisting>
 <![CDATA[
-  static struct snd_kcontrol_new my_control __devinitdata = {
+  static struct snd_kcontrol_new my_control = {
           .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
           .name = "PCM Playback Switch",
           .index = 0,
@@ -3415,13 +3395,6 @@
       </para>
 
       <para>
-        Most likely the control is created via
-      <function>snd_ctl_new1()</function>, and in such a case, you can
-      add the <parameter>__devinitdata</parameter> prefix to the
-      definition as above. 
-      </para>
-
-      <para>
         The <structfield>iface</structfield> field specifies the control
       type, <constant>SNDRV_CTL_ELEM_IFACE_XXX</constant>, which
       is usually <constant>MIXER</constant>.
@@ -3847,10 +3820,8 @@
 
       <para>
         <function>snd_ctl_new1()</function> allocates a new
-      <structname>snd_kcontrol</structname> instance (that's why the definition
-      of <parameter>my_control</parameter> can be with
-      the <parameter>__devinitdata</parameter> 
-      prefix), and <function>snd_ctl_add</function> assigns the given
+      <structname>snd_kcontrol</structname> instance,
+      and <function>snd_ctl_add</function> assigns the given
       control component to the card. 
       </para>
     </section>
@@ -3896,7 +3867,7 @@
 <![CDATA[
   static DECLARE_TLV_DB_SCALE(db_scale_my_control, -4050, 150, 0);
 
-  static struct snd_kcontrol_new my_control __devinitdata = {
+  static struct snd_kcontrol_new my_control = {
           ...
           .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
                     SNDRV_CTL_ELEM_ACCESS_TLV_READ,
@@ -5761,8 +5732,8 @@
       <informalexample>
         <programlisting>
 <![CDATA[
-  static int __devinit snd_mychip_probe(struct pci_dev *pci,
-                               const struct pci_device_id *pci_id)
+  static int snd_mychip_probe(struct pci_dev *pci,
+                              const struct pci_device_id *pci_id)
   {
           ....
           struct snd_card *card;
@@ -5787,8 +5758,8 @@
       <informalexample>
         <programlisting>
 <![CDATA[
-  static int __devinit snd_mychip_probe(struct pci_dev *pci,
-                               const struct pci_device_id *pci_id)
+  static int snd_mychip_probe(struct pci_dev *pci,
+                              const struct pci_device_id *pci_id)
   {
           ....
           struct snd_card *card;
@@ -5825,7 +5796,7 @@
           .name = KBUILD_MODNAME,
           .id_table = snd_my_ids,
           .probe = snd_my_probe,
-          .remove = __devexit_p(snd_my_remove),
+          .remove = snd_my_remove,
   #ifdef CONFIG_PM
           .suspend = snd_my_suspend,
           .resume = snd_my_resume,
diff --git a/Documentation/HOWTO b/Documentation/HOWTO
index 59c080f..a9f288f 100644
--- a/Documentation/HOWTO
+++ b/Documentation/HOWTO
@@ -462,7 +462,7 @@
 
 The kernel community works differently than most traditional corporate
 development environments.  Here are a list of things that you can try to
-do to try to avoid problems:
+do to avoid problems:
   Good things to say regarding your proposed changes:
     - "This solves multiple problems."
     - "This deletes 2000 lines of code."
diff --git a/Documentation/PCI/pci-iov-howto.txt b/Documentation/PCI/pci-iov-howto.txt
index fc73ef5..cfaca7e 100644
--- a/Documentation/PCI/pci-iov-howto.txt
+++ b/Documentation/PCI/pci-iov-howto.txt
@@ -2,6 +2,9 @@
 		Copyright (C) 2009 Intel Corporation
 		    Yu Zhao <yu.zhao@intel.com>
 
+		Update: November 2012
+			-- sysfs-based SRIOV enable-/disable-ment
+		Donald Dutile <ddutile@redhat.com>
 
 1. Overview
 
@@ -24,10 +27,21 @@
 
 2.1 How can I enable SR-IOV capability
 
-The device driver (PF driver) will control the enabling and disabling
-of the capability via API provided by SR-IOV core. If the hardware
-has SR-IOV capability, loading its PF driver would enable it and all
-VFs associated with the PF.
+Multiple methods are available for SR-IOV enablement.
+In the first method, the device driver (PF driver) will control the
+enabling and disabling of the capability via API provided by SR-IOV core.
+If the hardware has SR-IOV capability, loading its PF driver would
+enable it and all VFs associated with the PF.  Some PF drivers require
+a module parameter to be set to determine the number of VFs to enable.
+In the second method, a write to the sysfs file sriov_numvfs will
+enable and disable the VFs associated with a PCIe PF.  This method
+enables per-PF, VF enable/disable values versus the first method,
+which applies to all PFs of the same device.  Additionally, the
+PCI SRIOV core support ensures that enable/disable operations are
+valid to reduce duplication in multiple drivers for the same
+checks, e.g., check numvfs == 0 if enabling VFs, ensure
+numvfs <= totalvfs.
+The second method is the recommended method for new/future VF devices.
 
 2.2 How can I use the Virtual Functions
 
@@ -40,13 +54,22 @@
 3.1 SR-IOV API
 
 To enable SR-IOV capability:
+(a) For the first method, in the driver:
 	int pci_enable_sriov(struct pci_dev *dev, int nr_virtfn);
 	'nr_virtfn' is number of VFs to be enabled.
+(b) For the second method, from sysfs:
+	echo 'nr_virtfn' > \
+        /sys/bus/pci/devices/<DOMAIN:BUS:DEVICE.FUNCTION>/sriov_numvfs
 
 To disable SR-IOV capability:
+(a) For the first method, in the driver:
 	void pci_disable_sriov(struct pci_dev *dev);
+(b) For the second method, from sysfs:
+	echo  0 > \
+        /sys/bus/pci/devices/<DOMAIN:BUS:DEVICE.FUNCTION>/sriov_numvfs
 
 To notify SR-IOV core of Virtual Function Migration:
+(a) In the driver:
 	irqreturn_t pci_sriov_migration(struct pci_dev *dev);
 
 3.2 Usage example
@@ -88,6 +111,22 @@
 	...
 }
 
+static int dev_sriov_configure(struct pci_dev *dev, int numvfs)
+{
+	if (numvfs > 0) {
+		...
+		pci_enable_sriov(dev, numvfs);
+		...
+		return numvfs;
+	}
+	if (numvfs == 0) {
+		....
+		pci_disable_sriov(dev);
+		...
+		return 0;
+	}
+}
+
 static struct pci_driver dev_driver = {
 	.name =		"SR-IOV Physical Function driver",
 	.id_table =	dev_id_table,
@@ -96,4 +135,5 @@
 	.suspend =	dev_suspend,
 	.resume =	dev_resume,
 	.shutdown =	dev_shutdown,
+	.sriov_configure = dev_sriov_configure,
 };
diff --git a/Documentation/accounting/getdelays.c b/Documentation/accounting/getdelays.c
index 6f706ac..f8ebcde 100644
--- a/Documentation/accounting/getdelays.c
+++ b/Documentation/accounting/getdelays.c
@@ -51,7 +51,6 @@
 int print_delays;
 int print_io_accounting;
 int print_task_context_switch_counts;
-__u64 stime, utime;
 
 #define PRINTF(fmt, arg...) {			\
 	    if (dbg) {				\
diff --git a/Documentation/bus-devices/ti-gpmc.txt b/Documentation/bus-devices/ti-gpmc.txt
new file mode 100644
index 0000000..cc9ce57
--- /dev/null
+++ b/Documentation/bus-devices/ti-gpmc.txt
@@ -0,0 +1,122 @@
+GPMC (General Purpose Memory Controller):
+=========================================
+
+GPMC is an unified memory controller dedicated to interfacing external
+memory devices like
+ * Asynchronous SRAM like memories and application specific integrated
+   circuit devices.
+ * Asynchronous, synchronous, and page mode burst NOR flash devices
+   NAND flash
+ * Pseudo-SRAM devices
+
+GPMC is found on Texas Instruments SoC's (OMAP based)
+IP details: http://www.ti.com/lit/pdf/spruh73 section 7.1
+
+
+GPMC generic timing calculation:
+================================
+
+GPMC has certain timings that has to be programmed for proper
+functioning of the peripheral, while peripheral has another set of
+timings. To have peripheral work with gpmc, peripheral timings has to
+be translated to the form gpmc can understand. The way it has to be
+translated depends on the connected peripheral. Also there is a
+dependency for certain gpmc timings on gpmc clock frequency. Hence a
+generic timing routine was developed to achieve above requirements.
+
+Generic routine provides a generic method to calculate gpmc timings
+from gpmc peripheral timings. struct gpmc_device_timings fields has to
+be updated with timings from the datasheet of the peripheral that is
+connected to gpmc. A few of the peripheral timings can be fed either
+in time or in cycles, provision to handle this scenario has been
+provided (refer struct gpmc_device_timings definition). It may so
+happen that timing as specified by peripheral datasheet is not present
+in timing structure, in this scenario, try to correlate peripheral
+timing to the one available. If that doesn't work, try to add a new
+field as required by peripheral, educate generic timing routine to
+handle it, make sure that it does not break any of the existing.
+Then there may be cases where peripheral datasheet doesn't mention
+certain fields of struct gpmc_device_timings, zero those entries.
+
+Generic timing routine has been verified to work properly on
+multiple onenand's and tusb6010 peripherals.
+
+A word of caution: generic timing routine has been developed based
+on understanding of gpmc timings, peripheral timings, available
+custom timing routines, a kind of reverse engineering without
+most of the datasheets & hardware (to be exact none of those supported
+in mainline having custom timing routine) and by simulation.
+
+gpmc timing dependency on peripheral timings:
+[<gpmc_timing>: <peripheral timing1>, <peripheral timing2> ...]
+
+1. common
+cs_on: t_ceasu
+adv_on: t_avdasu, t_ceavd
+
+2. sync common
+sync_clk: clk
+page_burst_access: t_bacc
+clk_activation: t_ces, t_avds
+
+3. read async muxed
+adv_rd_off: t_avdp_r
+oe_on: t_oeasu, t_aavdh
+access: t_iaa, t_oe, t_ce, t_aa
+rd_cycle: t_rd_cycle, t_cez_r, t_oez
+
+4. read async non-muxed
+adv_rd_off: t_avdp_r
+oe_on: t_oeasu
+access: t_iaa, t_oe, t_ce, t_aa
+rd_cycle: t_rd_cycle, t_cez_r, t_oez
+
+5. read sync muxed
+adv_rd_off: t_avdp_r, t_avdh
+oe_on: t_oeasu, t_ach, cyc_aavdh_oe
+access: t_iaa, cyc_iaa, cyc_oe
+rd_cycle: t_cez_r, t_oez, t_ce_rdyz
+
+6. read sync non-muxed
+adv_rd_off: t_avdp_r
+oe_on: t_oeasu
+access: t_iaa, cyc_iaa, cyc_oe
+rd_cycle: t_cez_r, t_oez, t_ce_rdyz
+
+7. write async muxed
+adv_wr_off: t_avdp_w
+we_on, wr_data_mux_bus: t_weasu, t_aavdh, cyc_aavhd_we
+we_off: t_wpl
+cs_wr_off: t_wph
+wr_cycle: t_cez_w, t_wr_cycle
+
+8. write async non-muxed
+adv_wr_off: t_avdp_w
+we_on, wr_data_mux_bus: t_weasu
+we_off: t_wpl
+cs_wr_off: t_wph
+wr_cycle: t_cez_w, t_wr_cycle
+
+9. write sync muxed
+adv_wr_off: t_avdp_w, t_avdh
+we_on, wr_data_mux_bus: t_weasu, t_rdyo, t_aavdh, cyc_aavhd_we
+we_off: t_wpl, cyc_wpl
+cs_wr_off: t_wph
+wr_cycle: t_cez_w, t_ce_rdyz
+
+10. write sync non-muxed
+adv_wr_off: t_avdp_w
+we_on, wr_data_mux_bus: t_weasu, t_rdyo
+we_off: t_wpl, cyc_wpl
+cs_wr_off: t_wph
+wr_cycle: t_cez_w, t_ce_rdyz
+
+
+Note: Many of gpmc timings are dependent on other gpmc timings (a few
+gpmc timings purely dependent on other gpmc timings, a reason that
+some of the gpmc timings are missing above), and it will result in
+indirect dependency of peripheral timings to gpmc timings other than
+mentioned above, refer timing routine for more details. To know what
+these peripheral timings correspond to, please see explanations in
+struct gpmc_device_timings definition. And for gpmc timings refer
+IP details (link above).
diff --git a/Documentation/cgroups/cpusets.txt b/Documentation/cgroups/cpusets.txt
index cefd3d8..12e01d4 100644
--- a/Documentation/cgroups/cpusets.txt
+++ b/Documentation/cgroups/cpusets.txt
@@ -218,7 +218,7 @@
 The cpus and mems files in the root (top_cpuset) cpuset are
 read-only.  The cpus file automatically tracks the value of
 cpu_online_mask using a CPU hotplug notifier, and the mems file
-automatically tracks the value of node_states[N_HIGH_MEMORY]--i.e.,
+automatically tracks the value of node_states[N_MEMORY]--i.e.,
 nodes with memory--using the cpuset_track_online_nodes() hook.
 
 
diff --git a/Documentation/devicetree/bindings/arm/exynos/power_domain.txt b/Documentation/devicetree/bindings/arm/exynos/power_domain.txt
index 6528e21..5216b41 100644
--- a/Documentation/devicetree/bindings/arm/exynos/power_domain.txt
+++ b/Documentation/devicetree/bindings/arm/exynos/power_domain.txt
@@ -4,14 +4,13 @@
 to gate power to one or more peripherals on the processor.
 
 Required Properties:
-- compatiable: should be one of the following.
+- compatible: 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.
+Node of a device using power domains must have a samsung,power-domain property
+defined with a phandle to respective power domain.
 
 Example:
 
@@ -19,3 +18,11 @@
 		compatible = "samsung,exynos4210-pd";
 		reg = <0x10023C00 0x10>;
 	};
+
+Example of the node using power domain:
+
+	node {
+		/* ... */
+		samsung,power-domain = <&lcd0>;
+		/* ... */
+	};
diff --git a/Documentation/devicetree/bindings/arm/fsl.txt b/Documentation/devicetree/bindings/arm/fsl.txt
index ac9e751..f798187 100644
--- a/Documentation/devicetree/bindings/arm/fsl.txt
+++ b/Documentation/devicetree/bindings/arm/fsl.txt
@@ -41,6 +41,10 @@
 Required root node properties:
     - compatible = "fsl,imx6q-sabresd", "fsl,imx6q";
 
+i.MX6 Quad SABRE Automotive Board
+Required root node properties:
+    - compatible = "fsl,imx6q-sabreauto", "fsl,imx6q";
+
 Generic i.MX boards
 -------------------
 
diff --git a/Documentation/devicetree/bindings/ata/exynos-sata-phy.txt b/Documentation/devicetree/bindings/ata/exynos-sata-phy.txt
new file mode 100644
index 0000000..37824fa
--- /dev/null
+++ b/Documentation/devicetree/bindings/ata/exynos-sata-phy.txt
@@ -0,0 +1,14 @@
+* Samsung SATA PHY Controller
+
+SATA PHY nodes are defined to describe on-chip SATA Physical layer controllers.
+Each SATA PHY controller should have its own node.
+
+Required properties:
+- compatible        : compatible list, contains "samsung,exynos5-sata-phy"
+- reg               : <registers mapping>
+
+Example:
+        sata@ffe07000 {
+                compatible = "samsung,exynos5-sata-phy";
+                reg = <0xffe07000 0x1000>;
+        };
diff --git a/Documentation/devicetree/bindings/ata/exynos-sata.txt b/Documentation/devicetree/bindings/ata/exynos-sata.txt
new file mode 100644
index 0000000..0849f10
--- /dev/null
+++ b/Documentation/devicetree/bindings/ata/exynos-sata.txt
@@ -0,0 +1,17 @@
+* Samsung AHCI SATA Controller
+
+SATA nodes are defined to describe on-chip Serial ATA controllers.
+Each SATA controller should have its own node.
+
+Required properties:
+- compatible        : compatible list, contains "samsung,exynos5-sata"
+- interrupts        : <interrupt mapping for SATA IRQ>
+- reg               : <registers mapping>
+- samsung,sata-freq : <frequency in MHz>
+
+Example:
+        sata@ffe08000 {
+                compatible = "samsung,exynos5-sata";
+                reg = <0xffe08000 0x1000>;
+                interrupts = <115>;
+        };
diff --git a/Documentation/devicetree/bindings/clock/imx25-clock.txt b/Documentation/devicetree/bindings/clock/imx25-clock.txt
new file mode 100644
index 0000000..c2a3525
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/imx25-clock.txt
@@ -0,0 +1,162 @@
+* Clock bindings for Freescale i.MX25
+
+Required properties:
+- compatible: Should be "fsl,imx25-ccm"
+- reg: Address and length of the register set
+- interrupts: Should contain CCM interrupt
+- #clock-cells: Should be <1>
+
+The clock consumer should specify the desired clock by having the clock
+ID in its "clocks" phandle cell.  The following is a full list of i.MX25
+clocks and IDs.
+
+	Clock			ID
+	---------------------------
+	dummy			0
+	osc			1
+	mpll			2
+	upll			3
+	mpll_cpu_3_4		4
+	cpu_sel			5
+	cpu			6
+	ahb			7
+	usb_div			8
+	ipg			9
+	per0_sel		10
+	per1_sel		11
+	per2_sel		12
+	per3_sel		13
+	per4_sel		14
+	per5_sel		15
+	per6_sel		16
+	per7_sel		17
+	per8_sel		18
+	per9_sel		19
+	per10_sel		20
+	per11_sel		21
+	per12_sel		22
+	per13_sel		23
+	per14_sel		24
+	per15_sel		25
+	per0			26
+	per1			27
+	per2			28
+	per3			29
+	per4			30
+	per5			31
+	per6			32
+	per7			33
+	per8			34
+	per9			35
+	per10			36
+	per11			37
+	per12			38
+	per13			39
+	per14			40
+	per15			41
+	csi_ipg_per		42
+	epit_ipg_per		43
+	esai_ipg_per		44
+	esdhc1_ipg_per		45
+	esdhc2_ipg_per		46
+	gpt_ipg_per		47
+	i2c_ipg_per		48
+	lcdc_ipg_per		49
+	nfc_ipg_per		50
+	owire_ipg_per		51
+	pwm_ipg_per		52
+	sim1_ipg_per		53
+	sim2_ipg_per		54
+	ssi1_ipg_per		55
+	ssi2_ipg_per		56
+	uart_ipg_per		57
+	ata_ahb			58
+	reserved		59
+	csi_ahb			60
+	emi_ahb			61
+	esai_ahb		62
+	esdhc1_ahb		63
+	esdhc2_ahb		64
+	fec_ahb			65
+	lcdc_ahb		66
+	rtic_ahb		67
+	sdma_ahb		68
+	slcdc_ahb		69
+	usbotg_ahb		70
+	reserved		71
+	reserved		72
+	reserved		73
+	reserved		74
+	can1_ipg		75
+	can2_ipg		76
+	csi_ipg			77
+	cspi1_ipg		78
+	cspi2_ipg		79
+	cspi3_ipg		80
+	dryice_ipg		81
+	ect_ipg			82
+	epit1_ipg		83
+	epit2_ipg		84
+	reserved		85
+	esdhc1_ipg		86
+	esdhc2_ipg		87
+	fec_ipg			88
+	reserved		89
+	reserved		90
+	reserved		91
+	gpt1_ipg		92
+	gpt2_ipg		93
+	gpt3_ipg		94
+	gpt4_ipg		95
+	reserved		96
+	reserved		97
+	reserved		98
+	iim_ipg			99
+	reserved		100
+	reserved		101
+	kpp_ipg			102
+	lcdc_ipg		103
+	reserved		104
+	pwm1_ipg		105
+	pwm2_ipg		106
+	pwm3_ipg		107
+	pwm4_ipg		108
+	rngb_ipg		109
+	reserved		110
+	scc_ipg			111
+	sdma_ipg		112
+	sim1_ipg		113
+	sim2_ipg		114
+	slcdc_ipg		115
+	spba_ipg		116
+	ssi1_ipg		117
+	ssi2_ipg		118
+	tsc_ipg			119
+	uart1_ipg		120
+	uart2_ipg		121
+	uart3_ipg		122
+	uart4_ipg		123
+	uart5_ipg		124
+	reserved		125
+	wdt_ipg			126
+
+Examples:
+
+clks: ccm@53f80000 {
+	compatible = "fsl,imx25-ccm";
+	reg = <0x53f80000 0x4000>;
+	interrupts = <31>;
+	clock-output-names = ...
+			"uart_ipg",
+			"uart_serial",
+			...;
+};
+
+uart1: serial@43f90000 {
+	compatible = "fsl,imx25-uart", "fsl,imx21-uart";
+	reg = <0x43f90000 0x4000>;
+	interrupts = <45>;
+	clocks = <&clks 79>, <&clks 50>;
+	clock-names = "ipg", "per";
+	status = "disabled";
+};
diff --git a/Documentation/devicetree/bindings/clock/zynq-7000.txt b/Documentation/devicetree/bindings/clock/zynq-7000.txt
new file mode 100644
index 0000000..23ae1db
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/zynq-7000.txt
@@ -0,0 +1,55 @@
+Device Tree Clock bindings for the Zynq 7000 EPP
+
+The Zynq EPP has several different clk providers, each with there own bindings.
+The purpose of this document is to document their usage.
+
+See clock_bindings.txt for more information on the generic clock bindings.
+See Chapter 25 of Zynq TRM for more information about Zynq clocks.
+
+== PLLs ==
+
+Used to describe the ARM_PLL, DDR_PLL, and IO_PLL.
+
+Required properties:
+- #clock-cells : shall be 0 (only one clock is output from this node)
+- compatible : "xlnx,zynq-pll"
+- reg : pair of u32 values, which are the address offsets within the SLCR
+        of the relevant PLL_CTRL register and PLL_CFG register respectively
+- clocks : phandle for parent clock.  should be the phandle for ps_clk
+
+Optional properties:
+- clock-output-names : name of the output clock
+
+Example:
+	armpll: armpll {
+		#clock-cells = <0>;
+		compatible = "xlnx,zynq-pll";
+		clocks = <&ps_clk>;
+		reg = <0x100 0x110>;
+		clock-output-names = "armpll";
+	};
+
+== Peripheral clocks ==
+
+Describes clock node for the SDIO, SMC, SPI, QSPI, and UART clocks.
+
+Required properties:
+- #clock-cells : shall be 1
+- compatible : "xlnx,zynq-periph-clock"
+- reg : a single u32 value, describing the offset within the SLCR where
+        the CLK_CTRL register is found for this peripheral
+- clocks : phandle for parent clocks.  should hold phandles for
+           the IO_PLL, ARM_PLL, and DDR_PLL in order
+- clock-output-names : names of the output clock(s).  For peripherals that have
+                       two output clocks (for example, the UART), two clocks
+                       should be listed.
+
+Example:
+	uart_clk: uart_clk {
+		#clock-cells = <1>;
+		compatible = "xlnx,zynq-periph-clock";
+		clocks = <&iopll &armpll &ddrpll>;
+		reg = <0x154>;
+		clock-output-names = "uart0_ref_clk",
+				     "uart1_ref_clk";
+	};
diff --git a/Documentation/devicetree/bindings/drm/exynos/hdmi.txt b/Documentation/devicetree/bindings/drm/exynos/hdmi.txt
new file mode 100644
index 0000000..589edee
--- /dev/null
+++ b/Documentation/devicetree/bindings/drm/exynos/hdmi.txt
@@ -0,0 +1,22 @@
+Device-Tree bindings for drm hdmi driver
+
+Required properties:
+- compatible: value should be "samsung,exynos5-hdmi".
+- reg: physical base address of the hdmi and length of memory mapped
+	region.
+- interrupts: interrupt number to the cpu.
+- hpd-gpio: following information about the hotplug gpio pin.
+	a) phandle of the gpio controller node.
+	b) pin number within the gpio controller.
+	c) pin function mode.
+	d) optional flags and pull up/down.
+	e) drive strength.
+
+Example:
+
+	hdmi {
+		compatible = "samsung,exynos5-hdmi";
+		reg = <0x14530000 0x100000>;
+		interrupts = <0 95 0>;
+		hpd-gpio = <&gpx3 7 0xf 1 3>;
+	};
diff --git a/Documentation/devicetree/bindings/drm/exynos/hdmiddc.txt b/Documentation/devicetree/bindings/drm/exynos/hdmiddc.txt
new file mode 100644
index 0000000..fa166d9
--- /dev/null
+++ b/Documentation/devicetree/bindings/drm/exynos/hdmiddc.txt
@@ -0,0 +1,12 @@
+Device-Tree bindings for hdmiddc driver
+
+Required properties:
+- compatible: value should be "samsung,exynos5-hdmiddc".
+- reg: I2C address of the hdmiddc device.
+
+Example:
+
+	hdmiddc {
+		compatible = "samsung,exynos5-hdmiddc";
+		reg = <0x50>;
+	};
diff --git a/Documentation/devicetree/bindings/drm/exynos/hdmiphy.txt b/Documentation/devicetree/bindings/drm/exynos/hdmiphy.txt
new file mode 100644
index 0000000..858f4f9
--- /dev/null
+++ b/Documentation/devicetree/bindings/drm/exynos/hdmiphy.txt
@@ -0,0 +1,12 @@
+Device-Tree bindings for hdmiphy driver
+
+Required properties:
+- compatible: value should be "samsung,exynos5-hdmiphy".
+- reg: I2C address of the hdmiphy device.
+
+Example:
+
+	hdmiphy {
+		compatible = "samsung,exynos5-hdmiphy";
+		reg = <0x38>;
+	};
diff --git a/Documentation/devicetree/bindings/drm/exynos/mixer.txt b/Documentation/devicetree/bindings/drm/exynos/mixer.txt
new file mode 100644
index 0000000..9b2ea03
--- /dev/null
+++ b/Documentation/devicetree/bindings/drm/exynos/mixer.txt
@@ -0,0 +1,15 @@
+Device-Tree bindings for mixer driver
+
+Required properties:
+- compatible: value should be "samsung,exynos5-mixer".
+- reg: physical base address of the mixer and length of memory mapped
+	region.
+- interrupts: interrupt number to the cpu.
+
+Example:
+
+	mixer {
+		compatible = "samsung,exynos5-mixer";
+		reg = <0x14450000 0x10000>;
+		interrupts = <0 94 0>;
+	};
diff --git a/Documentation/devicetree/bindings/gpio/gpio-poweroff.txt b/Documentation/devicetree/bindings/gpio/gpio-poweroff.txt
new file mode 100644
index 0000000..558cdf3
--- /dev/null
+++ b/Documentation/devicetree/bindings/gpio/gpio-poweroff.txt
@@ -0,0 +1,22 @@
+GPIO line that should be set high/low to power off a device
+
+Required properties:
+- compatible : should be "gpio-poweroff".
+- gpios : The GPIO to set high/low, see "gpios property" in
+  Documentation/devicetree/bindings/gpio/gpio.txt. If the pin should be
+  low to power down the board set it to "Active Low", otherwise set
+  gpio to "Active High".
+
+Optional properties:
+- input : Initially configure the GPIO line as an input. Only reconfigure
+  it to an output when the pm_power_off function is called. If this optional
+  property is not specified, the GPIO is initialized as an output in its
+  inactive state.
+
+
+Examples:
+
+gpio-poweroff {
+	compatible = "gpio-poweroff";
+	gpios = <&gpio 4 0>; /* GPIO 4 Active Low */
+};
diff --git a/Documentation/devicetree/bindings/hwmon/vexpress.txt b/Documentation/devicetree/bindings/hwmon/vexpress.txt
new file mode 100644
index 0000000..9c27ed6
--- /dev/null
+++ b/Documentation/devicetree/bindings/hwmon/vexpress.txt
@@ -0,0 +1,23 @@
+Versatile Express hwmon sensors
+-------------------------------
+
+Requires node properties:
+- "compatible" value : one of
+	"arm,vexpress-volt"
+	"arm,vexpress-amp"
+	"arm,vexpress-temp"
+	"arm,vexpress-power"
+	"arm,vexpress-energy"
+- "arm,vexpress-sysreg,func" when controlled via vexpress-sysreg
+  (see Documentation/devicetree/bindings/arm/vexpress-sysreg.txt
+  for more details)
+
+Optional node properties:
+- label : string describing the monitored value
+
+Example:
+	energy@0 {
+		compatible = "arm,vexpress-energy";
+		arm,vexpress-sysreg,func = <13 0>;
+		label = "A15 Jcore";
+	};
diff --git a/Documentation/devicetree/bindings/input/touchscreen/bu21013.txt b/Documentation/devicetree/bindings/input/touchscreen/bu21013.txt
new file mode 100644
index 0000000..ca5a2c8
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/touchscreen/bu21013.txt
@@ -0,0 +1,28 @@
+* Rohm BU21013 Touch Screen
+
+Required properties:
+ - compatible              : "rohm,bu21013_tp"
+ - reg                     :  I2C device address
+
+Optional properties:
+ - touch-gpio              : GPIO pin registering a touch event
+ - <supply_name>-supply    : Phandle to a regulator supply
+ - rohm,touch-max-x        : Maximum outward permitted limit in the X axis
+ - rohm,touch-max-y        : Maximum outward permitted limit in the Y axis
+ - rohm,flip-x             : Flip touch coordinates on the X axis
+ - rohm,flip-y             : Flip touch coordinates on the Y axis
+
+Example:
+
+	i2c@80110000 {
+		bu21013_tp@0x5c {
+			compatible = "rohm,bu21013_tp";
+			reg = <0x5c>;
+			touch-gpio = <&gpio2 20 0x4>;
+			avdd-supply = <&ab8500_ldo_aux1_reg>;
+
+			rohm,touch-max-x = <384>;
+			rohm,touch-max-y = <704>;
+			rohm,flip-y;
+		};
+	};
diff --git a/Documentation/devicetree/bindings/media/s5p-mfc.txt b/Documentation/devicetree/bindings/media/s5p-mfc.txt
new file mode 100644
index 0000000..67ec3d4
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/s5p-mfc.txt
@@ -0,0 +1,23 @@
+* Samsung Multi Format Codec (MFC)
+
+Multi Format Codec (MFC) is the IP present in Samsung SoCs which
+supports high resolution decoding and encoding functionalities.
+The MFC device driver is a v4l2 driver which can encode/decode
+video raw/elementary streams and has support for all popular
+video codecs.
+
+Required properties:
+  - compatible : value should be either one among the following
+	(a) "samsung,mfc-v5" for MFC v5 present in Exynos4 SoCs
+	(b) "samsung,mfc-v6" for MFC v6 present in Exynos5 SoCs
+
+  - reg : Physical base address of the IP registers and length of memory
+	  mapped region.
+
+  - interrupts : MFC interrupt number to the CPU.
+
+  - samsung,mfc-r : Base address of the first memory bank used by MFC
+		    for DMA contiguous memory allocation and its size.
+
+  - samsung,mfc-l : Base address of the second memory bank used by MFC
+		    for DMA contiguous memory allocation and its size.
diff --git a/Documentation/devicetree/bindings/misc/atmel-ssc.txt b/Documentation/devicetree/bindings/misc/atmel-ssc.txt
new file mode 100644
index 0000000..38e51ad
--- /dev/null
+++ b/Documentation/devicetree/bindings/misc/atmel-ssc.txt
@@ -0,0 +1,15 @@
+* Atmel SSC driver.
+
+Required properties:
+- compatible: "atmel,at91rm9200-ssc" or "atmel,at91sam9g45-ssc"
+	- atmel,at91rm9200-ssc: support pdc transfer
+	- atmel,at91sam9g45-ssc: support dma transfer
+- reg: Should contain SSC registers location and length
+- interrupts: Should contain SSC interrupt
+
+Example:
+ssc0: ssc@fffbc000 {
+	compatible = "atmel,at91rm9200-ssc";
+	reg = <0xfffbc000 0x4000>;
+	interrupts = <14 4 5>;
+};
diff --git a/Documentation/devicetree/bindings/pinctrl/marvell,kirkwood-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/marvell,kirkwood-pinctrl.txt
index 361bccb..95daf63 100644
--- a/Documentation/devicetree/bindings/pinctrl/marvell,kirkwood-pinctrl.txt
+++ b/Documentation/devicetree/bindings/pinctrl/marvell,kirkwood-pinctrl.txt
@@ -7,8 +7,10 @@
 - compatible: "marvell,88f6180-pinctrl",
               "marvell,88f6190-pinctrl", "marvell,88f6192-pinctrl",
               "marvell,88f6281-pinctrl", "marvell,88f6282-pinctrl"
+              "marvell,98dx4122-pinctrl"
 
 This driver supports all kirkwood variants, i.e. 88f6180, 88f619x, and 88f628x.
+It also support the 88f6281-based variant in the 98dx412x Bobcat SoCs.
 
 Available mpp pins/groups and functions:
 Note: brackets (x) are not part of the mpp name for marvell,function and given
@@ -277,3 +279,40 @@
 mpp47         47       gpio, ts(mp11), tdm(drx), lcd(vsync)
 mpp48         48       gpio, ts(mp12), tdm(dtx), lcd(d16)
 mpp49         49       gpo, tdm(rx0ql), pex(clkreq), lcd(d17)
+
+* Marvell Bobcat 98dx4122
+
+name          pins     functions
+================================================================================
+mpp0          0        gpio, nand(io2), spi(cs)
+mpp1          1        gpo, nand(io3), spi(mosi)
+mpp2          2        gpo, nand(io4), spi(sck)
+mpp3          3        gpo, nand(io5), spi(miso)
+mpp4          4        gpio, nand(io6), uart0(rxd)
+mpp5          5        gpo, nand(io7), uart0(txd)
+mpp6          6        sysrst(out), spi(mosi)
+mpp7          7        gpo, pex(rsto), spi(cs)
+mpp8          8        gpio, twsi0(sda), uart0(rts), uart1(rts)
+mpp9          9        gpio, twsi(sck), uart0(cts), uart1(cts)
+mpp10         10       gpo, spi(sck), uart0(txd)
+mpp11         11       gpio, spi(miso), uart0(rxd)
+mpp13         13       gpio, uart1(txd)
+mpp14         14       gpio, uart1(rxd)
+mpp15         15       gpio, uart0(rts)
+mpp16         16       gpio, uart0(cts)
+mpp18         18       gpo, nand(io0)
+mpp19         19       gpo, nand(io1)
+mpp34         34       gpio
+mpp35         35       gpio
+mpp36         36       gpio
+mpp37         37       gpio
+mpp38         38       gpio
+mpp39         39       gpio
+mpp40         40       gpio
+mpp41         41       gpio
+mpp42         42       gpio
+mpp43         43       gpio
+mpp44         44       gpio
+mpp45         45       gpio
+mpp49         49       gpio
+
diff --git a/Documentation/devicetree/bindings/regulator/gpio-regulator.txt b/Documentation/devicetree/bindings/regulator/gpio-regulator.txt
new file mode 100644
index 0000000..63c6598
--- /dev/null
+++ b/Documentation/devicetree/bindings/regulator/gpio-regulator.txt
@@ -0,0 +1,37 @@
+GPIO controlled regulators
+
+Required properties:
+- compatible		: Must be "regulator-gpio".
+- states		: Selection of available voltages and GPIO configs.
+                          if there are no states, then use a fixed regulator
+
+Optional properties:
+- enable-gpio		: GPIO to use to enable/disable the regulator.
+- gpios			: GPIO group used to control voltage.
+- startup-delay-us	: Startup time in microseconds.
+- enable-active-high	: Polarity of GPIO is active high (default is low).
+
+Any property defined as part of the core regulator binding defined in
+regulator.txt can also be used.
+
+Example:
+
+	mmciv: gpio-regulator {
+		compatible = "regulator-gpio";
+
+		regulator-name = "mmci-gpio-supply";
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <2600000>;
+		regulator-boot-on;
+
+		enable-gpio = <&gpio0 23 0x4>;
+		gpios = <&gpio0 24 0x4
+			 &gpio0 25 0x4>;
+		states = <1800000 0x3
+			  2200000 0x2
+			  2600000 0x1
+			  2900000 0x0>;
+
+		startup-delay-us = <100000>;
+		enable-active-high;
+	};
diff --git a/Documentation/devicetree/bindings/regulator/max8925-regulator.txt b/Documentation/devicetree/bindings/regulator/max8925-regulator.txt
new file mode 100644
index 0000000..0057695
--- /dev/null
+++ b/Documentation/devicetree/bindings/regulator/max8925-regulator.txt
@@ -0,0 +1,40 @@
+Max8925 Voltage regulators
+
+Required nodes:
+-nodes:
+  - SDV1 for SDV SDV1
+  - SDV2 for SDV SDV2
+  - SDV3 for SDV SDV3
+  - LDO1 for LDO LDO1
+  - LDO2 for LDO LDO2
+  - LDO3 for LDO LDO3
+  - LDO4 for LDO LDO4
+  - LDO5 for LDO LDO5
+  - LDO6 for LDO LDO6
+  - LDO7 for LDO LDO7
+  - LDO8 for LDO LDO8
+  - LDO9 for LDO LDO9
+  - LDO10 for LDO LDO10
+  - LDO11 for LDO LDO11
+  - LDO12 for LDO LDO12
+  - LDO13 for LDO LDO13
+  - LDO14 for LDO LDO14
+  - LDO15 for LDO LDO15
+  - LDO16 for LDO LDO16
+  - LDO17 for LDO LDO17
+  - LDO18 for LDO LDO18
+  - LDO19 for LDO LDO19
+  - LDO20 for LDO LDO20
+
+Optional properties:
+- Any optional property defined in bindings/regulator/regulator.txt
+
+Example:
+
+	SDV1 {
+		regulator-min-microvolt = <637500>;
+		regulator-max-microvolt = <1425000>;
+		regulator-boot-on;
+		regulator-always-on;
+	};
+
diff --git a/Documentation/devicetree/bindings/regulator/max8997-regulator.txt b/Documentation/devicetree/bindings/regulator/max8997-regulator.txt
new file mode 100644
index 0000000..9fd69a1
--- /dev/null
+++ b/Documentation/devicetree/bindings/regulator/max8997-regulator.txt
@@ -0,0 +1,146 @@
+* Maxim MAX8997 Voltage and Current Regulator
+
+The Maxim MAX8997 is a multi-function device which includes volatage and
+current regulators, rtc, charger controller and other sub-blocks. It is
+interfaced to the host controller using a i2c interface. Each sub-block is
+addressed by the host system using different i2c slave address. This document
+describes the bindings for 'pmic' sub-block of max8997.
+
+Required properties:
+- compatible: Should be "maxim,max8997-pmic".
+- reg: Specifies the i2c slave address of the pmic block. It should be 0x66.
+
+- max8997,pmic-buck1-dvs-voltage: A set of 8 voltage values in micro-volt (uV)
+  units for buck1 when changing voltage using gpio dvs. Refer to [1] below
+  for additional information.
+
+- max8997,pmic-buck2-dvs-voltage: A set of 8 voltage values in micro-volt (uV)
+  units for buck2 when changing voltage using gpio dvs. Refer to [1] below
+  for additional information.
+
+- max8997,pmic-buck5-dvs-voltage: A set of 8 voltage values in micro-volt (uV)
+  units for buck5 when changing voltage using gpio dvs. Refer to [1] below
+  for additional information.
+
+[1] If none of the 'max8997,pmic-buck[1/2/5]-uses-gpio-dvs' optional
+    property is specified, the 'max8997,pmic-buck[1/2/5]-dvs-voltage'
+    property should specify atleast one voltage level (which would be a
+    safe operating voltage).
+
+    If either of the 'max8997,pmic-buck[1/2/5]-uses-gpio-dvs' optional
+    property is specified, then all the eigth voltage values for the
+    'max8997,pmic-buck[1/2/5]-dvs-voltage' should be specified.
+
+Optional properties:
+- interrupt-parent: Specifies the phandle of the interrupt controller to which
+  the interrupts from max8997 are delivered to.
+- interrupts: Interrupt specifiers for two interrupt sources.
+  - First interrupt specifier is for 'irq1' interrupt.
+  - Second interrupt specifier is for 'alert' interrupt.
+- max8997,pmic-buck1-uses-gpio-dvs: 'buck1' can be controlled by gpio dvs.
+- max8997,pmic-buck2-uses-gpio-dvs: 'buck2' can be controlled by gpio dvs.
+- max8997,pmic-buck5-uses-gpio-dvs: 'buck5' can be controlled by gpio dvs.
+
+Additional properties required if either of the optional properties are used:
+- max8997,pmic-ignore-gpiodvs-side-effect: When GPIO-DVS mode is used for
+  multiple bucks, changing the voltage value of one of the bucks may affect
+  that of another buck, which is the side effect of the change (set_voltage).
+  Use this property to ignore such side effects and change the voltage.
+
+- max8997,pmic-buck125-default-dvs-idx: Default voltage setting selected from
+  the possible 8 options selectable by the dvs gpios. The value of this
+  property should be between 0 and 7. If not specified or if out of range, the
+  default value of this property is set to 0.
+
+- max8997,pmic-buck125-dvs-gpios: GPIO specifiers for three host gpio's used
+  for dvs. The format of the gpio specifier depends in the gpio controller.
+
+Regulators: The regulators of max8997 that have to be instantiated should be
+included in a sub-node named 'regulators'. Regulator nodes included in this
+sub-node should be of the format as listed below.
+
+	regulator_name {
+		standard regulator bindings here
+	};
+
+The following are the names of the regulators that the max8997 pmic block
+supports. Note: The 'n' in LDOn and BUCKn represents the LDO or BUCK number
+as per the datasheet of max8997.
+
+	- LDOn
+		  - valid values for n are 1 to 18 and 21
+		  - Example: LDO0, LD01, LDO2, LDO21
+	- BUCKn
+		  - valid values for n are 1 to 7.
+		  - Example: BUCK1, BUCK2, BUCK3, BUCK7
+
+	- ENVICHG: Battery Charging Current Monitor Output. This is a fixed
+		   voltage type regulator
+
+	- ESAFEOUT1: (ldo19)
+	- ESAFEOUT2: (ld020)
+
+	- CHARGER_CV: main battery charger voltage control
+	- CHARGER: main battery charger current control
+	- CHARGER_TOPOFF: end of charge current threshold level
+
+The bindings inside the regulator nodes use the standard regulator bindings
+which are documented elsewhere.
+
+Example:
+
+	max8997_pmic@66 {
+		compatible = "maxim,max8997-pmic";
+		interrupt-parent = <&wakeup_eint>;
+		reg = <0x66>;
+		interrupts = <4 0>, <3 0>;
+
+		max8997,pmic-buck1-uses-gpio-dvs;
+		max8997,pmic-buck2-uses-gpio-dvs;
+		max8997,pmic-buck5-uses-gpio-dvs;
+
+		max8997,pmic-ignore-gpiodvs-side-effect;
+		max8997,pmic-buck125-default-dvs-idx = <0>;
+
+		max8997,pmic-buck125-dvs-gpios = <&gpx0 0 1 0 0>, /* SET1 */
+						 <&gpx0 1 1 0 0>, /* SET2 */
+						 <&gpx0 2 1 0 0>; /* SET3 */
+
+		max8997,pmic-buck1-dvs-voltage = <1350000>, <1300000>,
+						 <1250000>, <1200000>,
+						 <1150000>, <1100000>,
+						 <1000000>, <950000>;
+
+		max8997,pmic-buck2-dvs-voltage = <1100000>, <1100000>,
+						 <1100000>, <1100000>,
+						 <1000000>, <1000000>,
+						 <1000000>, <1000000>;
+
+		max8997,pmic-buck5-dvs-voltage = <1200000>, <1200000>,
+						 <1200000>, <1200000>,
+						 <1200000>, <1200000>,
+						 <1200000>, <1200000>;
+
+		regulators {
+			ldo1_reg: LDO1 {
+				regulator-name = "VDD_ABB_3.3V";
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+			};
+
+			ldo2_reg: LDO2 {
+				regulator-name = "VDD_ALIVE_1.1V";
+				regulator-min-microvolt = <1100000>;
+				regulator-max-microvolt = <1100000>;
+				regulator-always-on;
+			};
+
+			buck1_reg: BUCK1 {
+				regulator-name = "VDD_ARM_1.2V";
+				regulator-min-microvolt = <950000>;
+				regulator-max-microvolt = <1350000>;
+				regulator-always-on;
+				regulator-boot-on;
+			};
+		};
+	};
diff --git a/Documentation/devicetree/bindings/regulator/vexpress.txt b/Documentation/devicetree/bindings/regulator/vexpress.txt
new file mode 100644
index 0000000..d775f72
--- /dev/null
+++ b/Documentation/devicetree/bindings/regulator/vexpress.txt
@@ -0,0 +1,32 @@
+Versatile Express voltage regulators
+------------------------------------
+
+Requires node properties:
+- "compatible" value: "arm,vexpress-volt"
+- "arm,vexpress-sysreg,func" when controlled via vexpress-sysreg
+  (see Documentation/devicetree/bindings/arm/vexpress-sysreg.txt
+  for more details)
+
+Required regulator properties:
+- "regulator-name"
+- "regulator-always-on"
+
+Optional regulator properties:
+- "regulator-min-microvolt"
+- "regulator-max-microvolt"
+
+See Documentation/devicetree/bindings/regulator/regulator.txt
+for more details about the regulator properties.
+
+When no "regulator-[min|max]-microvolt" properties are defined,
+the device is treated as fixed (or rather "read-only") regulator.
+
+Example:
+	volt@0 {
+		compatible = "arm,vexpress-volt";
+		arm,vexpress-sysreg,func = <2 0>;
+		regulator-name = "Cores";
+		regulator-min-microvolt = <800000>;
+		regulator-max-microvolt = <1050000>;
+		regulator-always-on;
+	};
diff --git a/Documentation/devicetree/bindings/rtc/nvidia,tegra20-rtc.txt b/Documentation/devicetree/bindings/rtc/nvidia,tegra20-rtc.txt
new file mode 100644
index 0000000..93f45e9
--- /dev/null
+++ b/Documentation/devicetree/bindings/rtc/nvidia,tegra20-rtc.txt
@@ -0,0 +1,19 @@
+NVIDIA Tegra20 real-time clock
+
+The Tegra RTC maintains seconds and milliseconds counters, and five alarm
+registers. The alarms and other interrupts may wake the system from low-power
+state.
+
+Required properties:
+
+- compatible : should be "nvidia,tegra20-rtc".
+- reg : Specifies base physical address and size of the registers.
+- interrupts : A single interrupt specifier.
+
+Example:
+
+timer {
+	compatible = "nvidia,tegra20-rtc";
+	reg = <0x7000e000 0x100>;
+	interrupts = <0 2 0x04>;
+};
diff --git a/Documentation/devicetree/bindings/sound/ak4104.txt b/Documentation/devicetree/bindings/sound/ak4104.txt
new file mode 100644
index 0000000..b902ee3
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/ak4104.txt
@@ -0,0 +1,22 @@
+AK4104 S/PDIF transmitter
+
+This device supports SPI mode only.
+
+Required properties:
+
+  - compatible : "asahi-kasei,ak4104"
+
+  - reg : The chip select number on the SPI bus
+
+Optional properties:
+
+  - reset-gpio : a GPIO spec for the reset pin. If specified, it will be
+		 deasserted before communication to the device starts.
+
+Example:
+
+spdif: ak4104@0 {
+	compatible = "asahi-kasei,ak4104";
+	reg = <0>;
+	spi-max-frequency = <5000000>;
+};
diff --git a/Documentation/devicetree/bindings/sound/atmel-at91sam9g20ek-wm8731-audio.txt b/Documentation/devicetree/bindings/sound/atmel-at91sam9g20ek-wm8731-audio.txt
new file mode 100644
index 0000000..9c5a994
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/atmel-at91sam9g20ek-wm8731-audio.txt
@@ -0,0 +1,26 @@
+* Atmel at91sam9g20ek wm8731 audio complex
+
+Required properties:
+  - compatible: "atmel,at91sam9g20ek-wm8731-audio"
+  - atmel,model: The user-visible name of this sound complex.
+  - atmel,audio-routing: A list of the connections between audio components.
+  - atmel,ssc-controller: The phandle of the SSC controller
+  - atmel,audio-codec: The phandle of the WM8731 audio codec
+Optional properties:
+  - pinctrl-names, pinctrl-0: Please refer to pinctrl-bindings.txt
+
+Example:
+sound {
+	compatible = "atmel,at91sam9g20ek-wm8731-audio";
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_pck0_as_mck>;
+
+	atmel,model = "wm8731 @ AT91SAMG20EK";
+
+	atmel,audio-routing =
+		"Ext Spk", "LHPOUT",
+		"Int MIC", "MICIN";
+
+	atmel,ssc-controller = <&ssc0>;
+	atmel,audio-codec = <&wm8731>;
+};
diff --git a/Documentation/devicetree/bindings/sound/cs4271.txt b/Documentation/devicetree/bindings/sound/cs4271.txt
index c81b5fd..a850fb9 100644
--- a/Documentation/devicetree/bindings/sound/cs4271.txt
+++ b/Documentation/devicetree/bindings/sound/cs4271.txt
@@ -18,6 +18,8 @@
 
  - reset-gpio: 	a GPIO spec to define which pin is connected to the chip's
 		!RESET pin
+ - cirrus,amuteb-eq-bmutec:	When given, the Codec's AMUTEB=BMUTEC flag
+				is enabled.
 
 Examples:
 
diff --git a/Documentation/devicetree/bindings/sound/omap-abe-twl6040.txt b/Documentation/devicetree/bindings/sound/omap-abe-twl6040.txt
index 65dec87..fd40c85 100644
--- a/Documentation/devicetree/bindings/sound/omap-abe-twl6040.txt
+++ b/Documentation/devicetree/bindings/sound/omap-abe-twl6040.txt
@@ -12,7 +12,7 @@
 
 Optional properties:
 - ti,dmic: phandle for the OMAP dmic node if the machine have it connected
-- ti,jack_detection: Need to be set to <1> if the board capable to detect jack
+- ti,jack_detection: Need to be present if the board capable to detect jack
   insertion, removal.
 
 Available audio endpoints for the audio-routing table:
@@ -59,7 +59,7 @@
 	compatible = "ti,abe-twl6040";
 	ti,model = "SDP4430";
 
-	ti,jack-detection = <1>;
+	ti,jack-detection;
 	ti,mclk-freq = <38400000>;
 
 	ti,mcpdm = <&mcpdm>;
diff --git a/Documentation/devicetree/bindings/timer/nvidia,tegra20-timer.txt b/Documentation/devicetree/bindings/timer/nvidia,tegra20-timer.txt
new file mode 100644
index 0000000..e019fdc
--- /dev/null
+++ b/Documentation/devicetree/bindings/timer/nvidia,tegra20-timer.txt
@@ -0,0 +1,21 @@
+NVIDIA Tegra20 timer
+
+The Tegra20 timer provides four 29-bit timer channels and a single 32-bit free
+running counter. The first two channels may also trigger a watchdog reset.
+
+Required properties:
+
+- compatible : should be "nvidia,tegra20-timer".
+- reg : Specifies base physical address and size of the registers.
+- interrupts : A list of 4 interrupts; one per timer channel.
+
+Example:
+
+timer {
+	compatible = "nvidia,tegra20-timer";
+	reg = <0x60005000 0x60>;
+	interrupts = <0 0 0x04
+			0 1 0x04
+			0 41 0x04
+			0 42 0x04>;
+};
diff --git a/Documentation/devicetree/bindings/timer/nvidia,tegra30-timer.txt b/Documentation/devicetree/bindings/timer/nvidia,tegra30-timer.txt
new file mode 100644
index 0000000..906109d
--- /dev/null
+++ b/Documentation/devicetree/bindings/timer/nvidia,tegra30-timer.txt
@@ -0,0 +1,23 @@
+NVIDIA Tegra30 timer
+
+The Tegra30 timer provides ten 29-bit timer channels, a single 32-bit free
+running counter, and 5 watchdog modules. The first two channels may also
+trigger a legacy watchdog reset.
+
+Required properties:
+
+- compatible : should be "nvidia,tegra30-timer", "nvidia,tegra20-timer".
+- reg : Specifies base physical address and size of the registers.
+- interrupts : A list of 6 interrupts; one per each of timer channels 1
+    through 5, and one for the shared interrupt for the remaining channels.
+
+timer {
+	compatible = "nvidia,tegra30-timer", "nvidia,tegra20-timer";
+	reg = <0x60005000 0x400>;
+	interrupts = <0 0 0x04
+		      0 1 0x04
+		      0 41 0x04
+		      0 42 0x04
+		      0 121 0x04
+		      0 122 0x04>;
+};
diff --git a/Documentation/devicetree/bindings/usb/ehci-orion.txt b/Documentation/devicetree/bindings/usb/ehci-orion.txt
new file mode 100644
index 0000000..6bc09ec
--- /dev/null
+++ b/Documentation/devicetree/bindings/usb/ehci-orion.txt
@@ -0,0 +1,15 @@
+* EHCI controller, Orion Marvell variants
+
+Required properties:
+- compatible: must be "marvell,orion-ehci"
+- reg: physical base address of the controller and length of memory mapped
+  region.
+- interrupts: The EHCI interrupt
+
+Example:
+
+	ehci@50000 {
+		compatible = "marvell,orion-ehci";
+		reg = <0x50000 0x1000>;
+		interrupts = <19>;
+	};
diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt
index 770a019..902b1b1 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.txt
+++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
@@ -55,4 +55,5 @@
 via	VIA Technologies, Inc.
 wlf	Wolfson Microelectronics
 wm	Wondermedia Technologies, Inc.
+winbond Winbond Electronics corp.
 xlnx	Xilinx
diff --git a/Documentation/devicetree/bindings/watchdog/atmel-wdt.txt b/Documentation/devicetree/bindings/watchdog/atmel-wdt.txt
new file mode 100644
index 0000000..2957ebb
--- /dev/null
+++ b/Documentation/devicetree/bindings/watchdog/atmel-wdt.txt
@@ -0,0 +1,15 @@
+* Atmel Watchdog Timers
+
+** at91sam9-wdt
+
+Required properties:
+- compatible: must be "atmel,at91sam9260-wdt".
+- reg: physical base address of the controller and length of memory mapped
+  region.
+
+Example:
+
+	watchdog@fffffd40 {
+		compatible = "atmel,at91sam9260-wdt";
+		reg = <0xfffffd40 0x10>;
+	};
diff --git a/Documentation/dma-buf-sharing.txt b/Documentation/dma-buf-sharing.txt
index ad86fb8..0188903 100644
--- a/Documentation/dma-buf-sharing.txt
+++ b/Documentation/dma-buf-sharing.txt
@@ -376,7 +376,7 @@
    leaving the cpu domain and flushing caches at fault time. Note that all the
    dma_buf files share the same anon inode, hence the exporter needs to replace
    the dma_buf file stored in vma->vm_file with it's own if pte shootdown is
-   requred. This is because the kernel uses the underlying inode's address_space
+   required. This is because the kernel uses the underlying inode's address_space
    for vma tracking (and hence pte tracking at shootdown time with
    unmap_mapping_range).
 
@@ -388,7 +388,7 @@
    Exporters that shoot down mappings (for any reasons) shall not do any
    synchronization at fault time with outstanding device operations.
    Synchronization is an orthogonal issue to sharing the backing storage of a
-   buffer and hence should not be handled by dma-buf itself. This is explictly
+   buffer and hence should not be handled by dma-buf itself. This is explicitly
    mentioned here because many people seem to want something like this, but if
    different exporters handle this differently, buffer sharing can fail in
    interesting ways depending upong the exporter (if userspace starts depending
diff --git a/Documentation/dontdiff b/Documentation/dontdiff
index 74c25c8..b89a739 100644
--- a/Documentation/dontdiff
+++ b/Documentation/dontdiff
@@ -181,7 +181,6 @@
 nconf
 ncscope.*
 offset.h
-offsets.h
 oui.c*
 page-types
 parse.c
diff --git a/Documentation/fault-injection/notifier-error-inject.txt b/Documentation/fault-injection/notifier-error-inject.txt
index c83526c..09adabe 100644
--- a/Documentation/fault-injection/notifier-error-inject.txt
+++ b/Documentation/fault-injection/notifier-error-inject.txt
@@ -1,7 +1,7 @@
 Notifier error injection
 ========================
 
-Notifier error injection provides the ability to inject artifical errors to
+Notifier error injection provides the ability to inject artificial errors to
 specified notifier chain callbacks. It is useful to test the error handling of
 notifier call chain failures which is rarely executed.  There are kernel
 modules that can be used to test the following notifiers.
@@ -14,7 +14,7 @@
 CPU notifier error injection module
 -----------------------------------
 This feature can be used to test the error handling of the CPU notifiers by
-injecting artifical errors to CPU notifier chain callbacks.
+injecting artificial errors to CPU notifier chain callbacks.
 
 If the notifier call chain should be failed with some events notified, write
 the error code to debugfs interface
diff --git a/Documentation/hid/uhid.txt b/Documentation/hid/uhid.txt
index 4627c42..3c74121 100644
--- a/Documentation/hid/uhid.txt
+++ b/Documentation/hid/uhid.txt
@@ -108,7 +108,7 @@
   UHID_FEATURE_ANSWER:
   If you receive a UHID_FEATURE request you must answer with this request. You
   must copy the "id" field from the request into the answer. Set the "err" field
-  to 0 if no error occured or to EIO if an I/O error occurred.
+  to 0 if no error occurred or to EIO if an I/O error occurred.
   If "err" is 0 then you should fill the buffer of the answer with the results
   of the feature request and set "size" correspondingly.
 
diff --git a/Documentation/hwmon/pmbus b/Documentation/hwmon/pmbus
index f90f999..3d3a0f9 100644
--- a/Documentation/hwmon/pmbus
+++ b/Documentation/hwmon/pmbus
@@ -138,7 +138,7 @@
 
 When probing the chip, the driver identifies which PMBus registers are
 supported, and determines available sensors from this information.
-Attribute files only exist if respective sensors are suported by the chip.
+Attribute files only exist if respective sensors are supported by the chip.
 Labels are provided to inform the user about the sensor associated with
 a given sysfs entry.
 
diff --git a/Documentation/hwmon/vexpress b/Documentation/hwmon/vexpress
new file mode 100644
index 0000000..557d6d5
--- /dev/null
+++ b/Documentation/hwmon/vexpress
@@ -0,0 +1,34 @@
+Kernel driver vexpress
+======================
+
+Supported systems:
+  * ARM Ltd. Versatile Express platform
+    Prefix: 'vexpress'
+    Datasheets:
+      * "Hardware Description" sections of the Technical Reference Manuals
+        for the Versatile Express boards:
+        http://infocenter.arm.com/help/topic/com.arm.doc.subset.boards.express/index.html
+      * Section "4.4.14. System Configuration registers" of the V2M-P1 TRM:
+        http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0447-/index.html
+
+Author: Pawel Moll
+
+Description
+-----------
+
+Versatile Express platform (http://www.arm.com/versatileexpress/) is a
+reference & prototyping system for ARM Ltd. processors. It can be set up
+from a wide range of boards, each of them containing (apart of the main
+chip/FPGA) a number of microcontrollers responsible for platform
+configuration and control. Theses microcontrollers can also monitor the
+board and its environment by a number of internal and external sensors,
+providing information about power lines voltages and currents, board
+temperature and power usage. Some of them also calculate consumed energy
+and provide a cumulative use counter.
+
+The configuration devices are _not_ memory mapped and must be accessed
+via a custom interface, abstracted by the "vexpress_config" API.
+
+As these devices are non-discoverable, they must be described in a Device
+Tree passed to the kernel. Details of the DT binding for them can be found
+in Documentation/devicetree/bindings/hwmon/vexpress.txt.
diff --git a/Documentation/input/alps.txt b/Documentation/input/alps.txt
index ae8ba9a..3262b6e 100644
--- a/Documentation/input/alps.txt
+++ b/Documentation/input/alps.txt
@@ -133,7 +133,7 @@
 
 This packet only appears after a position packet with the mt bit set, and
 usually only appears when there are two or more contacts (although
-occassionally it's seen with only a single contact).
+occasionally it's seen with only a single contact).
 
 The final v3 packet type is the trackstick packet.
 
diff --git a/Documentation/input/event-codes.txt b/Documentation/input/event-codes.txt
index 53305bd..f1ea2c6 100644
--- a/Documentation/input/event-codes.txt
+++ b/Documentation/input/event-codes.txt
@@ -196,6 +196,17 @@
 EV_MSC events are used for input and output events that do not fall under other
 categories.
 
+A few EV_MSC codes have special meaning:
+
+* MSC_TIMESTAMP:
+  - Used to report the number of microseconds since the last reset. This event
+    should be coded as an uint32 value, which is allowed to wrap around with
+    no special consequence. It is assumed that the time difference between two
+    consecutive events is reliable on a reasonable time scale (hours).
+    A reset to zero can happen, in which case the time since the last event is
+    unknown.  If the device does not provide this information, the driver must
+    not provide it to user space.
+
 EV_LED:
 ----------
 EV_LED events are used for input and output to set and query the state of
diff --git a/Documentation/kbuild/modules.txt b/Documentation/kbuild/modules.txt
index 3fb39e0..69372fb 100644
--- a/Documentation/kbuild/modules.txt
+++ b/Documentation/kbuild/modules.txt
@@ -470,7 +470,7 @@
 
 	Sometimes, an external module uses exported symbols from
 	another external module. kbuild needs to have full knowledge of
-	all symbols to avoid spitting out warnings about undefined
+	all symbols to avoid spliitting out warnings about undefined
 	symbols. Three solutions exist for this situation.
 
 	NOTE: The method with a top-level kbuild file is recommended
diff --git a/Documentation/kernel-doc-nano-HOWTO.txt b/Documentation/kernel-doc-nano-HOWTO.txt
index 3d8a977..99b57ab 100644
--- a/Documentation/kernel-doc-nano-HOWTO.txt
+++ b/Documentation/kernel-doc-nano-HOWTO.txt
@@ -64,6 +64,8 @@
  * comment lines.
  *
  * The longer description can have multiple paragraphs.
+ *
+ * Return: Describe the return value of foobar.
  */
 
 The short description following the subject can span multiple lines
@@ -78,6 +80,8 @@
 kernel-doc notation as:
  * @...: description
 
+The return value, if any, should be described in a dedicated section
+named "Return".
 
 Example kernel-doc data structure comment.
 
@@ -222,6 +226,9 @@
 "section header:" names must be unique per function (or struct,
 union, typedef, enum).
 
+Use the section header "Return" for sections describing the return value
+of a function.
+
 Avoid putting a spurious blank line after the function name, or else the
 description will be repeated!
 
@@ -237,21 +244,21 @@
 NOTE 1:  The multi-line descriptive text you provide does *not* recognize
 line breaks, so if you try to format some text nicely, as in:
 
-  Return codes
+  Return:
     0 - cool
     1 - invalid arg
     2 - out of memory
 
 this will all run together and produce:
 
-  Return codes 0 - cool 1 - invalid arg 2 - out of memory
+  Return: 0 - cool 1 - invalid arg 2 - out of memory
 
 NOTE 2:  If the descriptive text you provide has lines that begin with
 some phrase followed by a colon, each of those phrases will be taken as
 a new section heading, which means you should similarly try to avoid text
 like:
 
-  Return codes:
+  Return:
     0: cool
     1: invalid arg
     2: out of memory
diff --git a/Documentation/memory-hotplug.txt b/Documentation/memory-hotplug.txt
index c6f993d..8e5eacb 100644
--- a/Documentation/memory-hotplug.txt
+++ b/Documentation/memory-hotplug.txt
@@ -390,6 +390,7 @@
        unsigned long start_pfn;
        unsigned long nr_pages;
        int status_change_nid_normal;
+       int status_change_nid_high;
        int status_change_nid;
 }
 
@@ -397,7 +398,9 @@
 nr_pages is # of pages of online/offline memory.
 status_change_nid_normal is set node id when N_NORMAL_MEMORY of nodemask
 is (will be) set/clear, if this is -1, then nodemask status is not changed.
-status_change_nid is set node id when N_HIGH_MEMORY of nodemask is (will be)
+status_change_nid_high is set node id when N_HIGH_MEMORY of nodemask
+is (will be) set/clear, if this is -1, then nodemask status is not changed.
+status_change_nid is set node id when N_MEMORY of nodemask is (will be)
 set/clear. It means a new(memoryless) node gets new memory by online and a
 node loses all memory. If this is -1, then nodemask status is not changed.
 If status_changed_nid* >= 0, callback should create/discard structures for the
diff --git a/Documentation/misc-devices/mei/mei-amt-version.c b/Documentation/misc-devices/mei/mei-amt-version.c
index 01804f2..49e4f77 100644
--- a/Documentation/misc-devices/mei/mei-amt-version.c
+++ b/Documentation/misc-devices/mei/mei-amt-version.c
@@ -214,7 +214,7 @@
 }
 
 /***************************************************************************
- * Intel Advanced Management Technolgy ME Client
+ * Intel Advanced Management Technology ME Client
  ***************************************************************************/
 
 #define AMT_MAJOR_VERSION 1
@@ -256,7 +256,7 @@
 } __attribute__((packed));
 
 /***************************************************************************
- * Intel Advanced Management Technolgy Host Interface
+ * Intel Advanced Management Technology Host Interface
  ***************************************************************************/
 
 struct amt_host_if_msg_header {
diff --git a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt
index d90d8ec..b9cfd33 100644
--- a/Documentation/sound/alsa/ALSA-Configuration.txt
+++ b/Documentation/sound/alsa/ALSA-Configuration.txt
@@ -1905,7 +1905,6 @@
     vid             - Vendor ID for the device (optional)
     pid             - Product ID for the device (optional)
     nrpacks	    - Max. number of packets per URB (default: 8)
-    async_unlink    - Use async unlink mode (default: yes)
     device_setup    - Device specific magic number (optional)
                     - Influence depends on the device
                     - Default: 0x0000 
@@ -1917,8 +1916,6 @@
     NB: nrpacks parameter can be modified dynamically via sysfs.
         Don't put the value over 20.  Changing via sysfs has no sanity
 	check.
-    NB: async_unlink=0 would cause Oops.  It remains just for
-        debugging purpose (if any).
     NB: ignore_ctl_error=1 may help when you get an error at accessing
         the mixer element such as URB error -22.  This happens on some
         buggy USB device or the controller.
diff --git a/Documentation/video4linux/bttv/Cards b/Documentation/video4linux/bttv/Cards
index db833ce..a8fb6e2 100644
--- a/Documentation/video4linux/bttv/Cards
+++ b/Documentation/video4linux/bttv/Cards
@@ -43,7 +43,7 @@
 to the card via composite.
 
 Many thanks to Matrix-Vision for giving us 2 cards for free which made
-Bt848a/Bt849 single crytal operation support possible!!!
+Bt848a/Bt849 single crystal operation support possible!!!
 
 
 
diff --git a/Documentation/video4linux/bttv/Sound-FAQ b/Documentation/video4linux/bttv/Sound-FAQ
index 395f6c6..d3f1d77 100644
--- a/Documentation/video4linux/bttv/Sound-FAQ
+++ b/Documentation/video4linux/bttv/Sound-FAQ
@@ -82,7 +82,7 @@
 values used by the windows driver.  A tool to do this is available
 from ftp://telepresence.dmem.strath.ac.uk/pub/bt848/winutil, but it
 does'nt work with bt878 boards according to some reports I received.
-Another one with bt878 suport is available from
+Another one with bt878 support is available from
 http://btwincap.sourceforge.net/Files/btspy2.00.zip
 
 You might also dig around in the *.ini files of the Windows applications.
diff --git a/Documentation/vm/frontswap.txt b/Documentation/vm/frontswap.txt
index 5ef2d13..c71a019 100644
--- a/Documentation/vm/frontswap.txt
+++ b/Documentation/vm/frontswap.txt
@@ -193,7 +193,7 @@
    or maybe swap-over-nbd/NFS)?
 
 No.  First, the existing swap subsystem doesn't allow for any kind of
-swap hierarchy.  Perhaps it could be rewritten to accomodate a hierarchy,
+swap hierarchy.  Perhaps it could be rewritten to accommodate a hierarchy,
 but this would require fairly drastic changes.  Even if it were
 rewritten, the existing swap subsystem uses the block I/O layer which
 assumes a swap device is fixed size and any page in it is linearly
diff --git a/Documentation/vm/transhuge.txt b/Documentation/vm/transhuge.txt
index f734bb2..8785fb8 100644
--- a/Documentation/vm/transhuge.txt
+++ b/Documentation/vm/transhuge.txt
@@ -116,6 +116,13 @@
 echo madvise >/sys/kernel/mm/transparent_hugepage/defrag
 echo never >/sys/kernel/mm/transparent_hugepage/defrag
 
+By default kernel tries to use huge zero page on read page fault.
+It's possible to disable huge zero page by writing 0 or enable it
+back by writing 1:
+
+echo 0 >/sys/kernel/mm/transparent_hugepage/khugepaged/use_zero_page
+echo 1 >/sys/kernel/mm/transparent_hugepage/khugepaged/use_zero_page
+
 khugepaged will be automatically started when
 transparent_hugepage/enabled is set to "always" or "madvise, and it'll
 be automatically shutdown if it's set to "never".
@@ -197,6 +204,14 @@
 	pages. This can happen for a variety of reasons but a common
 	reason is that a huge page is old and is being reclaimed.
 
+thp_zero_page_alloc is incremented every time a huge zero page is
+	successfully allocated. It includes allocations which where
+	dropped due race with other allocation. Note, it doesn't count
+	every map of the huge zero page, only its allocation.
+
+thp_zero_page_alloc_failed is incremented if kernel fails to allocate
+	huge zero page and falls back to using small pages.
+
 As the system ages, allocating huge pages may be expensive as the
 system uses memory compaction to copy data around memory to free a
 huge page for use. There are some counters in /proc/vmstat to help
@@ -276,7 +291,7 @@
 == Graceful fallback ==
 
 Code walking pagetables but unware about huge pmds can simply call
-split_huge_page_pmd(mm, pmd) where the pmd is the one returned by
+split_huge_page_pmd(vma, addr, pmd) where the pmd is the one returned by
 pmd_offset. It's trivial to make the code transparent hugepage aware
 by just grepping for "pmd_offset" and adding split_huge_page_pmd where
 missing after pmd_offset returns the pmd. Thanks to the graceful
@@ -299,7 +314,7 @@
 		return NULL;
 
 	pmd = pmd_offset(pud, addr);
-+	split_huge_page_pmd(mm, pmd);
++	split_huge_page_pmd(vma, addr, pmd);
 	if (pmd_none_or_clear_bad(pmd))
 		return NULL;
 
diff --git a/MAINTAINERS b/MAINTAINERS
index 0bc485c..b0b880d 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3596,7 +3596,7 @@
 F:	drivers/input/touchscreen/htcpen.c
 
 HUGETLB FILESYSTEM
-M:	William Irwin <wli@holomorphy.com>
+M:	Nadia Yvette Chambers <nyc@holomorphy.com>
 S:	Maintained
 F:	fs/hugetlbfs/
 
diff --git a/README b/README
index f32710a..a24ec89 100644
--- a/README
+++ b/README
@@ -180,6 +180,10 @@
                         with questions already answered.
                         Additionally updates the dependencies.
 
+     "make olddefconfig"
+                        Like above, but sets new symbols to their default
+                        values without prompting.
+
      "make defconfig"   Create a ./.config file by using the default
                         symbol values from either arch/$ARCH/defconfig
                         or arch/$ARCH/configs/${PLATFORM}_defconfig,
diff --git a/arch/alpha/include/asm/mmzone.h b/arch/alpha/include/asm/mmzone.h
index 445dc42..c5b5d6b 100644
--- a/arch/alpha/include/asm/mmzone.h
+++ b/arch/alpha/include/asm/mmzone.h
@@ -66,7 +66,7 @@
     ((unsigned long)__va(NODE_DATA(kvaddr_to_nid(kaddr))->node_start_pfn  \
 			 << PAGE_SHIFT))
 
-/* XXX: FIXME -- wli */
+/* XXX: FIXME -- nyc */
 #define kern_addr_valid(kaddr)	(0)
 
 #define virt_to_page(kaddr)	pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)
diff --git a/arch/alpha/kernel/pci_iommu.c b/arch/alpha/kernel/pci_iommu.c
index 3f844d2..a21d0ab 100644
--- a/arch/alpha/kernel/pci_iommu.c
+++ b/arch/alpha/kernel/pci_iommu.c
@@ -354,8 +354,7 @@
 	struct pci_dev *pdev = alpha_gendev_to_pci(dev);
 	int dac_allowed;
 
-	if (dir == PCI_DMA_NONE)
-		BUG();
+	BUG_ON(dir == PCI_DMA_NONE);
 
 	dac_allowed = pdev ? pci_dac_dma_supported(pdev, pdev->dma_mask) : 0; 
 	return pci_map_single_1(pdev, (char *)page_address(page) + offset, 
@@ -378,8 +377,7 @@
 	struct pci_iommu_arena *arena;
 	long dma_ofs, npages;
 
-	if (dir == PCI_DMA_NONE)
-		BUG();
+	BUG_ON(dir == PCI_DMA_NONE);
 
 	if (dma_addr >= __direct_map_base
 	    && dma_addr < __direct_map_base + __direct_map_size) {
@@ -662,8 +660,7 @@
 	dma_addr_t max_dma;
 	int dac_allowed;
 
-	if (dir == PCI_DMA_NONE)
-		BUG();
+	BUG_ON(dir == PCI_DMA_NONE);
 
 	dac_allowed = dev ? pci_dac_dma_supported(pdev, pdev->dma_mask) : 0;
 
@@ -742,8 +739,7 @@
 	dma_addr_t max_dma;
 	dma_addr_t fbeg, fend;
 
-	if (dir == PCI_DMA_NONE)
-		BUG();
+	BUG_ON(dir == PCI_DMA_NONE);
 
 	if (! alpha_mv.mv_pci_tbi)
 		return;
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 08330d9..2277f95 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -536,6 +536,8 @@
 	select CPU_V7
 	select GENERIC_CLOCKEVENTS
 	select MIGHT_HAVE_PCI
+	select PINCTRL
+	select PINCTRL_DOVE
 	select PLAT_ORION_LEGACY
 	select USB_ARCH_HAS_EHCI
 	help
@@ -548,6 +550,8 @@
 	select GENERIC_CLOCKEVENTS
 	select PCI
 	select PCI_QUIRKS
+	select PINCTRL
+	select PINCTRL_KIRKWOOD
 	select PLAT_ORION_LEGACY
 	help
 	  Support for the following Marvell Kirkwood series SoCs:
@@ -646,6 +650,7 @@
 	select HAVE_CLK
 	select HAVE_SMP
 	select MIGHT_HAVE_CACHE_L2X0
+	select SPARSE_IRQ
 	select USE_OF
 	help
 	  This enables support for NVIDIA Tegra based systems (Tegra APX,
@@ -887,6 +892,7 @@
 	select GENERIC_CLOCKEVENTS
 	select HAVE_SMP
 	select MIGHT_HAVE_CACHE_L2X0
+	select SPARSE_IRQ
 	help
 	  Support for ST-Ericsson's Ux500 architecture
 
@@ -901,6 +907,7 @@
 	select MIGHT_HAVE_CACHE_L2X0
 	select PINCTRL
 	select PINCTRL_STN8815
+	select SPARSE_IRQ
 	help
 	  Support for the Nomadik platform by ST-Ericsson
 
@@ -944,7 +951,7 @@
 	help
 	  Support for TI's OMAP platform (OMAP1/2/3/4).
 
-config ARCH_VT8500
+config ARCH_VT8500_SINGLE
 	bool "VIA/WonderMedia 85xx"
 	select ARCH_HAS_CPUFREQ
 	select ARCH_REQUIRE_GPIOLIB
@@ -954,21 +961,12 @@
 	select GENERIC_CLOCKEVENTS
 	select GENERIC_GPIO
 	select HAVE_CLK
+	select MULTI_IRQ_HANDLER
+	select SPARSE_IRQ
 	select USE_OF
 	help
 	  Support for VIA/WonderMedia VT8500/WM85xx System-on-Chip.
 
-config ARCH_ZYNQ
-	bool "Xilinx Zynq ARM Cortex A9 Platform"
-	select ARM_AMBA
-	select ARM_GIC
-	select CPU_V7
-	select GENERIC_CLOCKEVENTS
-	select ICST
-	select MIGHT_HAVE_CACHE_L2X0
-	select USE_OF
-	help
-	  Support for Xilinx Zynq ARM Cortex A9 Platform
 endchoice
 
 menu "Multiple platform selection"
@@ -1069,7 +1067,6 @@
 source "arch/arm/mach-netx/Kconfig"
 
 source "arch/arm/mach-nomadik/Kconfig"
-source "arch/arm/plat-nomadik/Kconfig"
 
 source "arch/arm/plat-omap/Kconfig"
 
@@ -1132,8 +1129,12 @@
 source "arch/arm/mach-vexpress/Kconfig"
 source "arch/arm/plat-versatile/Kconfig"
 
+source "arch/arm/mach-vt8500/Kconfig"
+
 source "arch/arm/mach-w90x900/Kconfig"
 
+source "arch/arm/mach-zynq/Kconfig"
+
 # Definitions to make life easier
 config ARCH_ACORN
 	bool
diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug
index 04a3f0d..661030d 100644
--- a/arch/arm/Kconfig.debug
+++ b/arch/arm/Kconfig.debug
@@ -132,6 +132,23 @@
 		  their output to UART1 serial port on DaVinci TNETV107X
 		  devices.
 
+	config DEBUG_ZYNQ_UART0
+		bool "Kernel low-level debugging on Xilinx Zynq using UART0"
+		depends on ARCH_ZYNQ
+		help
+		  Say Y here if you want the debug print routines to direct
+		  their output to UART0 on the Zynq platform.
+
+	config DEBUG_ZYNQ_UART1
+		bool "Kernel low-level debugging on Xilinx Zynq using UART1"
+		depends on ARCH_ZYNQ
+		help
+		  Say Y here if you want the debug print routines to direct
+		  their output to UART1 on the Zynq platform.
+
+		  If you have a ZC702 board and want early boot messages to
+		  appear on the USB serial adaptor, select this option.
+
 	config DEBUG_DC21285_PORT
 		bool "Kernel low-level debugging messages via footbridge serial port"
 		depends on FOOTBRIDGE
@@ -209,20 +226,12 @@
 		  Say Y here if you want kernel low-level debugging support
 		  on i.MX50 or i.MX53.
 
-	config DEBUG_IMX6Q_UART2
-		bool "i.MX6Q Debug UART2"
+	config DEBUG_IMX6Q_UART
+		bool "i.MX6Q Debug UART"
 		depends on SOC_IMX6Q
 		help
 		  Say Y here if you want kernel low-level debugging support
-		  on i.MX6Q UART2. This is correct for e.g. the SabreLite
-                  board.
-
-	config DEBUG_IMX6Q_UART4
-		bool "i.MX6Q Debug UART4"
-		depends on SOC_IMX6Q
-		help
-		  Say Y here if you want kernel low-level debugging support
-		  on i.MX6Q UART4.
+		  on i.MX6Q.
 
 	config DEBUG_MMP_UART2
 		bool "Kernel low-level debugging message via MMP UART2"
@@ -370,6 +379,13 @@
 		  Say Y here if you want kernel low-level debugging support
 		  on Allwinner A1X based platforms on the UART1.
 
+	config DEBUG_TEGRA_UART
+		depends on ARCH_TEGRA
+		bool "Use Tegra UART for low-level debug"
+		help
+		  Say Y here if you want kernel low-level debugging support
+		  on Tegra based platforms.
+
 	config DEBUG_VEXPRESS_UART0_DETECT
 		bool "Autodetect UART0 on Versatile Express Cortex-A core tiles"
 		depends on ARCH_VEXPRESS && CPU_CP15_MMU
@@ -434,6 +450,45 @@
 
 endchoice
 
+config DEBUG_IMX6Q_UART_PORT
+	int "i.MX6Q Debug UART Port (1-5)" if DEBUG_IMX6Q_UART
+	range 1 5
+	default 1
+	depends on SOC_IMX6Q
+	help
+	  Choose UART port on which kernel low-level debug messages
+	  should be output.
+
+choice
+	prompt "Low-level debug console UART"
+	depends on DEBUG_LL && DEBUG_TEGRA_UART
+
+	config TEGRA_DEBUG_UART_AUTO_ODMDATA
+	bool "Via ODMDATA"
+	help
+	  Automatically determines which UART to use for low-level debug based
+	  on the ODMDATA value. This value is part of the BCT, and is written
+	  to the boot memory device using nvflash, or other flashing tool.
+	  When bits 19:18 are 3, then bits 17:15 indicate which UART to use;
+	  0/1/2/3/4 are UART A/B/C/D/E.
+
+	config TEGRA_DEBUG_UARTA
+		bool "UART A"
+
+	config TEGRA_DEBUG_UARTB
+		bool "UART B"
+
+	config TEGRA_DEBUG_UARTC
+		bool "UART C"
+
+	config TEGRA_DEBUG_UARTD
+		bool "UART D"
+
+	config TEGRA_DEBUG_UARTE
+		bool "UART E"
+
+endchoice
+
 config DEBUG_LL_INCLUDE
 	string
 	default "debug/icedcc.S" if DEBUG_ICEDCC
@@ -443,8 +498,7 @@
 				 DEBUG_IMX31_IMX35_UART || \
 				 DEBUG_IMX51_UART || \
 				 DEBUG_IMX50_IMX53_UART ||\
-				 DEBUG_IMX6Q_UART2 || \
-				 DEBUG_IMX6Q_UART4
+				 DEBUG_IMX6Q_UART
 	default "debug/highbank.S" if DEBUG_HIGHBANK_UART
 	default "debug/mvebu.S" if DEBUG_MVEBU_UART
 	default "debug/picoxcell.S" if DEBUG_PICOXCELL_UART
@@ -452,6 +506,8 @@
 	default "debug/sunxi.S" if DEBUG_SUNXI_UART0 || DEBUG_SUNXI_UART1
 	default "debug/vexpress.S" if DEBUG_VEXPRESS_UART0_DETECT || \
 		DEBUG_VEXPRESS_UART0_CA9 || DEBUG_VEXPRESS_UART0_RS1
+	default "debug/tegra.S" if DEBUG_TEGRA_UART
+	default "debug/zynq.S" if DEBUG_ZYNQ_UART0 || DEBUG_ZYNQ_UART1
 	default "mach/debug-macro.S"
 
 config EARLY_PRINTK
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 9c60f47..30c443c 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -202,7 +202,6 @@
 plat-$(CONFIG_ARCH_OMAP)	+= omap
 plat-$(CONFIG_ARCH_S3C64XX)	+= samsung
 plat-$(CONFIG_PLAT_IOP)		+= iop
-plat-$(CONFIG_PLAT_NOMADIK)	+= nomadik
 plat-$(CONFIG_PLAT_ORION)	+= orion
 plat-$(CONFIG_PLAT_PXA)		+= pxa
 plat-$(CONFIG_PLAT_S3C24XX)	+= s3c24xx samsung
diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index f3f2f80..2af359c 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -34,6 +34,8 @@
 
 dtb-$(CONFIG_ARCH_BCM2835) += bcm2835-rpi-b.dtb
 dtb-$(CONFIG_ARCH_BCM) += bcm11351-brt.dtb
+dtb-$(CONFIG_ARCH_DAVINCI) += da850-enbw-cmc.dtb \
+	da850-evm.dtb
 dtb-$(CONFIG_ARCH_DOVE) += dove-cm-a510.dtb \
 	dove-cubox.dtb \
 	dove-dove-db.dtb
@@ -41,7 +43,10 @@
 	exynos4210-smdkv310.dtb \
 	exynos4210-trats.dtb \
 	exynos5250-smdk5250.dtb \
-	exynos5440-ssdk5440.dtb
+	exynos5440-ssdk5440.dtb \
+	exynos4412-smdk4412.dtb \
+	exynos5250-smdk5250.dtb \
+	exynos5250-snow.dtb
 dtb-$(CONFIG_ARCH_HIGHBANK) += highbank.dtb \
 	ecx-2000.dtb
 dtb-$(CONFIG_ARCH_INTEGRATOR) += integratorap.dtb \
@@ -79,16 +84,20 @@
 	imx53-qsb.dtb \
 	imx53-smd.dtb \
 	imx6q-arm2.dtb \
+	imx6q-sabreauto.dtb \
 	imx6q-sabrelite.dtb \
 	imx6q-sabresd.dtb
 dtb-$(CONFIG_ARCH_MXS) += imx23-evk.dtb \
 	imx23-olinuxino.dtb \
 	imx23-stmp378x_devb.dtb \
+	imx28-apf28.dtb \
+	imx28-apf28dev.dtb \
 	imx28-apx4devkit.dtb \
 	imx28-cfa10036.dtb \
 	imx28-cfa10049.dtb \
 	imx28-evk.dtb \
 	imx28-m28evk.dtb \
+	imx28-sps1.dtb \
 	imx28-tx28.dtb
 dtb-$(CONFIG_ARCH_OMAP2PLUS) += omap2420-h4.dtb \
 	omap3-beagle.dtb \
@@ -105,7 +114,10 @@
 	am335x-bone.dtb
 dtb-$(CONFIG_ARCH_ORION5X) += orion5x-lacie-ethernet-disk-mini-v2.dtb
 dtb-$(CONFIG_ARCH_PRIMA2) += prima2-evb.dtb
-dtb-$(CONFIG_ARCH_U8500) += snowball.dtb
+dtb-$(CONFIG_ARCH_U8500) += snowball.dtb \
+	hrefprev60.dtb \
+	hrefv60plus.dtb \
+	ccu9540.dtb
 dtb-$(CONFIG_ARCH_SHMOBILE) += emev2-kzm9d.dtb \
 	r8a7740-armadillo800eva.dtb \
 	sh73a0-kzm9g.dtb \
@@ -137,6 +149,7 @@
 dtb-$(CONFIG_ARCH_VT8500) += vt8500-bv07.dtb \
 	wm8505-ref.dtb \
 	wm8650-mid.dtb
+dtb-$(CONFIG_ARCH_ZYNQ) += zynq-zc702.dtb
 
 targets += dtbs
 endif
diff --git a/arch/arm/boot/dts/at91sam9260.dtsi b/arch/arm/boot/dts/at91sam9260.dtsi
index b1d3fab..68bccf4 100644
--- a/arch/arm/boot/dts/at91sam9260.dtsi
+++ b/arch/arm/boot/dts/at91sam9260.dtsi
@@ -29,6 +29,7 @@
 		tcb0 = &tcb0;
 		tcb1 = &tcb1;
 		i2c0 = &i2c0;
+		ssc0 = &ssc0;
 	};
 	cpus {
 		cpu@0 {
@@ -445,6 +446,13 @@
 				status = "disabled";
 			};
 
+			ssc0: ssc@fffbc000 {
+				compatible = "atmel,at91rm9200-ssc";
+				reg = <0xfffbc000 0x4000>;
+				interrupts = <14 4 5>;
+				status = "disabled";
+			};
+
 			adc0: adc@fffe0000 {
 				compatible = "atmel,at91sam9260-adc";
 				reg = <0xfffe0000 0x100>;
@@ -479,6 +487,12 @@
 					trigger-external;
 				};
 			};
+
+			watchdog@fffffd40 {
+				compatible = "atmel,at91sam9260-wdt";
+				reg = <0xfffffd40 0x10>;
+				status = "disabled";
+			};
 		};
 
 		nand0: nand@40000000 {
diff --git a/arch/arm/boot/dts/at91sam9263.dtsi b/arch/arm/boot/dts/at91sam9263.dtsi
index 66106ee..8e6251f 100644
--- a/arch/arm/boot/dts/at91sam9263.dtsi
+++ b/arch/arm/boot/dts/at91sam9263.dtsi
@@ -25,6 +25,8 @@
 		gpio4 = &pioE;
 		tcb0 = &tcb0;
 		i2c0 = &i2c0;
+		ssc0 = &ssc0;
+		ssc1 = &ssc1;
 	};
 	cpus {
 		cpu@0 {
@@ -362,6 +364,20 @@
 				status = "disabled";
 			};
 
+			ssc0: ssc@fff98000 {
+				compatible = "atmel,at91rm9200-ssc";
+				reg = <0xfff98000 0x4000>;
+				interrupts = <16 4 5>;
+				status = "disable";
+			};
+
+			ssc1: ssc@fff9c000 {
+				compatible = "atmel,at91rm9200-ssc";
+				reg = <0xfff9c000 0x4000>;
+				interrupts = <17 4 5>;
+				status = "disable";
+			};
+
 			macb0: ethernet@fffbc000 {
 				compatible = "cdns,at32ap7000-macb", "cdns,macb";
 				reg = <0xfffbc000 0x100>;
@@ -404,6 +420,12 @@
 				#size-cells = <0>;
 				status = "disabled";
 			};
+
+			watchdog@fffffd40 {
+				compatible = "atmel,at91sam9260-wdt";
+				reg = <0xfffffd40 0x10>;
+				status = "disabled";
+			};
 		};
 
 		nand0: nand@40000000 {
diff --git a/arch/arm/boot/dts/at91sam9g20ek_common.dtsi b/arch/arm/boot/dts/at91sam9g20ek_common.dtsi
index 32a500a..da15e83 100644
--- a/arch/arm/boot/dts/at91sam9g20ek_common.dtsi
+++ b/arch/arm/boot/dts/at91sam9g20ek_common.dtsi
@@ -30,6 +30,16 @@
 
 	ahb {
 		apb {
+			pinctrl@fffff400 {
+				board {
+					pinctrl_pck0_as_mck: pck0_as_mck {
+						atmel,pins =
+							<2 1 0x2 0x0>;	/* PC1 periph B */
+					};
+
+				};
+			};
+
 			dbgu: serial@fffff200 {
 				status = "okay";
 			};
@@ -81,6 +91,11 @@
 					};
 				};
 			};
+
+			ssc0: ssc@fffbc000 {
+				status = "okay";
+				pinctrl-0 = <&pinctrl_ssc0_tx>;
+			};
 		};
 
 		nand0: nand@40000000 {
@@ -144,7 +159,7 @@
 			reg = <0x50>;
 		};
 
-		wm8731@1b {
+		wm8731: wm8731@1b {
 			compatible = "wm8731";
 			reg = <0x1b>;
 		};
@@ -169,4 +184,19 @@
 			gpio-key,wakeup;
 		};
 	};
+
+	sound {
+		compatible = "atmel,at91sam9g20ek-wm8731-audio";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_pck0_as_mck>;
+
+		atmel,model = "wm8731 @ AT91SAMG20EK";
+
+		atmel,audio-routing =
+			"Ext Spk", "LHPOUT",
+			"Int Mic", "MICIN";
+
+		atmel,ssc-controller = <&ssc0>;
+		atmel,audio-codec = <&wm8731>;
+	};
 };
diff --git a/arch/arm/boot/dts/at91sam9g45.dtsi b/arch/arm/boot/dts/at91sam9g45.dtsi
index 0741cae..fa1ae0c 100644
--- a/arch/arm/boot/dts/at91sam9g45.dtsi
+++ b/arch/arm/boot/dts/at91sam9g45.dtsi
@@ -31,6 +31,8 @@
 		tcb1 = &tcb1;
 		i2c0 = &i2c0;
 		i2c1 = &i2c1;
+		ssc0 = &ssc0;
+		ssc1 = &ssc1;
 	};
 	cpus {
 		cpu@0 {
@@ -419,6 +421,20 @@
 				status = "disabled";
 			};
 
+			ssc0: ssc@fff9c000 {
+				compatible = "atmel,at91sam9g45-ssc";
+				reg = <0xfff9c000 0x4000>;
+				interrupts = <16 4 5>;
+				status = "disable";
+			};
+
+			ssc1: ssc@fffa0000 {
+				compatible = "atmel,at91sam9g45-ssc";
+				reg = <0xfffa0000 0x4000>;
+				interrupts = <17 4 5>;
+				status = "disable";
+			};
+
 			adc0: adc@fffb0000 {
 				compatible = "atmel,at91sam9260-adc";
 				reg = <0xfffb0000 0x100>;
@@ -473,6 +489,12 @@
 				#size-cells = <0>;
 				status = "disabled";
 			};
+
+			watchdog@fffffd40 {
+				compatible = "atmel,at91sam9260-wdt";
+				reg = <0xfffffd40 0x10>;
+				status = "disabled";
+			};
 		};
 
 		nand0: nand@40000000 {
diff --git a/arch/arm/boot/dts/at91sam9x5.dtsi b/arch/arm/boot/dts/at91sam9x5.dtsi
index 7ee49e8d..617ede5 100644
--- a/arch/arm/boot/dts/at91sam9x5.dtsi
+++ b/arch/arm/boot/dts/at91sam9x5.dtsi
@@ -30,6 +30,7 @@
 		i2c0 = &i2c0;
 		i2c1 = &i2c1;
 		i2c2 = &i2c2;
+		ssc0 = &ssc0;
 	};
 	cpus {
 		cpu@0 {
@@ -87,6 +88,13 @@
 				interrupts = <1 4 7>;
 			};
 
+			ssc0: ssc@f0010000 {
+				compatible = "atmel,at91sam9g45-ssc";
+				reg = <0xf0010000 0x4000>;
+				interrupts = <28 4 5>;
+				status = "disable";
+			};
+
 			tcb0: timer@f8008000 {
 				compatible = "atmel,at91sam9x5-tcb";
 				reg = <0xf8008000 0x100>;
diff --git a/arch/arm/boot/dts/ccu9540.dts b/arch/arm/boot/dts/ccu9540.dts
new file mode 100644
index 0000000..0430546
--- /dev/null
+++ b/arch/arm/boot/dts/ccu9540.dts
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2012 ST-Ericsson AB
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/dts-v1/;
+/include/ "dbx5x0.dtsi"
+
+/ {
+	model = "ST-Ericsson CCU9540 platform with Device Tree";
+	compatible = "st-ericsson,ccu9540", "st-ericsson,u9540";
+
+	memory {
+		reg = <0x00000000 0x20000000>;
+	};
+
+	soc-u9500 {
+		uart@80120000 {
+			status = "okay";
+		};
+
+		uart@80121000 {
+			status = "okay";
+		};
+
+		uart@80007000 {
+			status = "okay";
+		};
+
+		// External Micro SD slot
+		sdi0_per1@80126000 {
+			arm,primecell-periphid = <0x10480180>;
+			max-frequency = <100000000>;
+			bus-width = <4>;
+			mmc-cap-sd-highspeed;
+			mmc-cap-mmc-highspeed;
+			vmmc-supply = <&ab8500_ldo_aux3_reg>;
+
+			cd-gpios  = <&gpio7 6 0x4>; // 230
+			cd-inverted;
+
+			status = "okay";
+		};
+
+
+		// WLAN SDIO channel
+		sdi1_per2@80118000 {
+			arm,primecell-periphid = <0x10480180>;
+			max-frequency = <50000000>;
+			bus-width = <4>;
+
+			status = "okay";
+		};
+
+		// On-board eMMC
+		sdi4_per2@80114000 {
+			arm,primecell-periphid = <0x10480180>;
+		        max-frequency = <100000000>;
+			bus-width = <8>;
+			mmc-cap-mmc-highspeed;
+			vmmc-supply = <&ab8500_ldo_aux2_reg>;
+
+			status = "okay";
+		};
+	};
+};
diff --git a/arch/arm/boot/dts/cros5250-common.dtsi b/arch/arm/boot/dts/cros5250-common.dtsi
new file mode 100644
index 0000000..fddd174
--- /dev/null
+++ b/arch/arm/boot/dts/cros5250-common.dtsi
@@ -0,0 +1,184 @@
+/*
+ * Common device tree include for all Exynos 5250 boards based off of Daisy.
+ *
+ * Copyright (c) 2012 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.
+*/
+
+/ {
+	aliases {
+	};
+
+	memory {
+		reg = <0x40000000 0x80000000>;
+	};
+
+	chosen {
+	};
+
+	i2c@12C60000 {
+		samsung,i2c-sda-delay = <100>;
+		samsung,i2c-max-bus-freq = <378000>;
+		gpios = <&gpb3 0 2 3 0>,
+			<&gpb3 1 2 3 0>;
+	};
+
+	i2c@12C70000 {
+		samsung,i2c-sda-delay = <100>;
+		samsung,i2c-max-bus-freq = <378000>;
+		gpios = <&gpb3 2 2 3 0>,
+			<&gpb3 3 2 3 0>;
+	};
+
+	i2c@12C80000 {
+		samsung,i2c-sda-delay = <100>;
+		samsung,i2c-max-bus-freq = <66000>;
+
+		/*
+		 * Disabled pullups since external part has its own pullups and
+		 * double-pulling gets us out of spec in some cases.
+		 */
+		gpios = <&gpa0 6 3 0 0>,
+			<&gpa0 7 3 0 0>;
+
+		hdmiddc@50 {
+			compatible = "samsung,exynos5-hdmiddc";
+			reg = <0x50>;
+		};
+	};
+
+	i2c@12C90000 {
+		samsung,i2c-sda-delay = <100>;
+		samsung,i2c-max-bus-freq = <66000>;
+		gpios = <&gpa1 2 3 3 0>,
+			<&gpa1 3 3 3 0>;
+	};
+
+	i2c@12CA0000 {
+		status = "disabled";
+	};
+
+	i2c@12CB0000 {
+		samsung,i2c-sda-delay = <100>;
+		samsung,i2c-max-bus-freq = <66000>;
+		gpios = <&gpa2 2 3 3 0>,
+			<&gpa2 3 3 3 0>;
+	};
+
+	i2c@12CC0000 {
+		status = "disabled";
+	};
+
+	i2c@12CD0000 {
+		samsung,i2c-sda-delay = <100>;
+		samsung,i2c-max-bus-freq = <66000>;
+		gpios = <&gpb2 2 3 3 0>,
+			<&gpb2 3 3 3 0>;
+	};
+
+	i2c@12CE0000 {
+		samsung,i2c-sda-delay = <100>;
+		samsung,i2c-max-bus-freq = <378000>;
+
+		hdmiphy@38 {
+			compatible = "samsung,exynos5-hdmiphy";
+			reg = <0x38>;
+		};
+	};
+
+	dwmmc0@12200000 {
+		num-slots = <1>;
+		supports-highspeed;
+		broken-cd;
+		fifo-depth = <0x80>;
+		card-detect-delay = <200>;
+		samsung,dw-mshc-ciu-div = <3>;
+		samsung,dw-mshc-sdr-timing = <2 3 3>;
+		samsung,dw-mshc-ddr-timing = <1 2 3>;
+
+		slot@0 {
+			reg = <0>;
+			bus-width = <8>;
+			gpios = <&gpc0 0 2 0 3>, <&gpc0 1 2 0 3>,
+				<&gpc1 0 2 3 3>, <&gpc1 1 2 3 3>,
+				<&gpc1 2 2 3 3>, <&gpc1 3 2 3 3>,
+				<&gpc0 3 2 3 3>, <&gpc0 4 2 3 3>,
+				<&gpc0 5 2 3 3>, <&gpc0 6 2 3 3>;
+		};
+	};
+
+	dwmmc1@12210000 {
+		status = "disabled";
+	};
+
+	dwmmc2@12220000 {
+		num-slots = <1>;
+		supports-highspeed;
+		fifo-depth = <0x80>;
+		card-detect-delay = <200>;
+		samsung,dw-mshc-ciu-div = <3>;
+		samsung,dw-mshc-sdr-timing = <2 3 3>;
+		samsung,dw-mshc-ddr-timing = <1 2 3>;
+
+		slot@0 {
+			reg = <0>;
+			bus-width = <4>;
+			samsung,cd-pinmux-gpio = <&gpc3 2 2 3 3>;
+			wp-gpios = <&gpc2 1 0 0 3>;
+			gpios = <&gpc3 0 2 0 3>, <&gpc3 1 2 0 3>,
+				<&gpc3 3 2 3 3>, <&gpc3 4 2 3 3>,
+				<&gpc3 5 2 3 3>, <&gpc3 6 2 3 3>;
+		};
+	};
+
+	dwmmc3@12230000 {
+		num-slots = <1>;
+		supports-highspeed;
+		broken-cd;
+		fifo-depth = <0x80>;
+		card-detect-delay = <200>;
+		samsung,dw-mshc-ciu-div = <3>;
+		samsung,dw-mshc-sdr-timing = <2 3 3>;
+		samsung,dw-mshc-ddr-timing = <1 2 3>;
+
+		slot@0 {
+			reg = <0>;
+			bus-width = <4>;
+			/* See board-specific dts files for GPIOs */
+		};
+	};
+
+	spi_0: spi@12d20000 {
+		status = "disabled";
+	};
+
+	spi_1: spi@12d30000 {
+		gpios = <&gpa2 4 2 3 0>,
+			<&gpa2 6 2 3 0>,
+			<&gpa2 7 2 3 0>;
+		samsung,spi-src-clk = <0>;
+		num-cs = <1>;
+	};
+
+	spi_2: spi@12d40000 {
+		status = "disabled";
+	};
+
+	hdmi {
+		hpd-gpio = <&gpx3 7 0xf 1 3>;
+	};
+
+	gpio-keys {
+		compatible = "gpio-keys";
+
+		power {
+			label = "Power";
+			gpios = <&gpx1 3 0 0x10000 0>;
+			linux,code = <116>; /* KEY_POWER */
+			gpio-key,wakeup;
+		};
+	};
+};
diff --git a/arch/arm/boot/dts/dbx5x0.dtsi b/arch/arm/boot/dts/dbx5x0.dtsi
index 731086b..0d69322 100644
--- a/arch/arm/boot/dts/dbx5x0.dtsi
+++ b/arch/arm/boot/dts/dbx5x0.dtsi
@@ -217,123 +217,103 @@
 				// DB8500_REGULATOR_VAPE
 				db8500_vape_reg: db8500_vape {
 					regulator-compatible = "db8500_vape";
-					regulator-name = "db8500-vape";
 					regulator-always-on;
 				};
 
 				// DB8500_REGULATOR_VARM
 				db8500_varm_reg: db8500_varm {
 					regulator-compatible = "db8500_varm";
-					regulator-name = "db8500-varm";
 				};
 
 				// DB8500_REGULATOR_VMODEM
 				db8500_vmodem_reg: db8500_vmodem {
 					regulator-compatible = "db8500_vmodem";
-					regulator-name = "db8500-vmodem";
 				};
 
 				// DB8500_REGULATOR_VPLL
 				db8500_vpll_reg: db8500_vpll {
 					regulator-compatible = "db8500_vpll";
-					regulator-name = "db8500-vpll";
 				};
 
 				// DB8500_REGULATOR_VSMPS1
 				db8500_vsmps1_reg: db8500_vsmps1 {
 					regulator-compatible = "db8500_vsmps1";
-					regulator-name = "db8500-vsmps1";
 				};
 
 				// DB8500_REGULATOR_VSMPS2
 				db8500_vsmps2_reg: db8500_vsmps2 {
 					regulator-compatible = "db8500_vsmps2";
-					regulator-name = "db8500-vsmps2";
 				};
 
 				// DB8500_REGULATOR_VSMPS3
 				db8500_vsmps3_reg: db8500_vsmps3 {
 					regulator-compatible = "db8500_vsmps3";
-					regulator-name = "db8500-vsmps3";
 				};
 
 				// DB8500_REGULATOR_VRF1
 				db8500_vrf1_reg: db8500_vrf1 {
 					regulator-compatible = "db8500_vrf1";
-					regulator-name = "db8500-vrf1";
 				};
 
 				// DB8500_REGULATOR_SWITCH_SVAMMDSP
 				db8500_sva_mmdsp_reg: db8500_sva_mmdsp {
 					regulator-compatible = "db8500_sva_mmdsp";
-					regulator-name = "db8500-sva-mmdsp";
 				};
 
 				// DB8500_REGULATOR_SWITCH_SVAMMDSPRET
 				db8500_sva_mmdsp_ret_reg: db8500_sva_mmdsp_ret {
 					regulator-compatible = "db8500_sva_mmdsp_ret";
-					regulator-name = "db8500-sva-mmdsp-ret";
 				};
 
 				// DB8500_REGULATOR_SWITCH_SVAPIPE
 				db8500_sva_pipe_reg: db8500_sva_pipe {
 					regulator-compatible = "db8500_sva_pipe";
-					regulator-name = "db8500_sva_pipe";
 				};
 
 				// DB8500_REGULATOR_SWITCH_SIAMMDSP
 				db8500_sia_mmdsp_reg: db8500_sia_mmdsp {
 					regulator-compatible = "db8500_sia_mmdsp";
-					regulator-name = "db8500_sia_mmdsp";
 				};
 
 				// DB8500_REGULATOR_SWITCH_SIAMMDSPRET
 				db8500_sia_mmdsp_ret_reg: db8500_sia_mmdsp_ret {
-					regulator-name = "db8500-sia-mmdsp-ret";
 				};
 
 				// DB8500_REGULATOR_SWITCH_SIAPIPE
 				db8500_sia_pipe_reg: db8500_sia_pipe {
 					regulator-compatible = "db8500_sia_pipe";
-					regulator-name = "db8500-sia-pipe";
 				};
 
 				// DB8500_REGULATOR_SWITCH_SGA
 				db8500_sga_reg: db8500_sga {
 					regulator-compatible = "db8500_sga";
-					regulator-name = "db8500-sga";
 					vin-supply = <&db8500_vape_reg>;
 				};
 
 				// DB8500_REGULATOR_SWITCH_B2R2_MCDE
 				db8500_b2r2_mcde_reg: db8500_b2r2_mcde {
 					regulator-compatible = "db8500_b2r2_mcde";
-					regulator-name = "db8500-b2r2-mcde";
 					vin-supply = <&db8500_vape_reg>;
 				};
 
 				// DB8500_REGULATOR_SWITCH_ESRAM12
 				db8500_esram12_reg: db8500_esram12 {
 					regulator-compatible = "db8500_esram12";
-					regulator-name = "db8500-esram12";
 				};
 
 				// DB8500_REGULATOR_SWITCH_ESRAM12RET
 				db8500_esram12_ret_reg: db8500_esram12_ret {
 					regulator-compatible = "db8500_esram12_ret";
-					regulator-name = "db8500-esram12-ret";
 				};
 
 				// DB8500_REGULATOR_SWITCH_ESRAM34
 				db8500_esram34_reg: db8500_esram34 {
 					regulator-compatible = "db8500_esram34";
-					regulator-name = "db8500-esram34";
 				};
 
 				// DB8500_REGULATOR_SWITCH_ESRAM34RET
 				db8500_esram34_ret_reg: db8500_esram34_ret {
 					regulator-compatible = "db8500_esram34_ret";
-					regulator-name = "db8500-esram34-ret";
 				};
 			};
 
@@ -412,7 +392,6 @@
 					// supplies to the display/camera
 					ab8500_ldo_aux1_reg: ab8500_ldo_aux1 {
 						regulator-compatible = "ab8500_ldo_aux1";
-						regulator-name = "V-DISPLAY";
 						regulator-min-microvolt = <2500000>;
 						regulator-max-microvolt = <2900000>;
 						regulator-boot-on;
@@ -423,7 +402,6 @@
 					// supplies to the on-board eMMC
 					ab8500_ldo_aux2_reg: ab8500_ldo_aux2 {
 						regulator-compatible = "ab8500_ldo_aux2";
-						regulator-name = "V-eMMC1";
 						regulator-min-microvolt = <1100000>;
 						regulator-max-microvolt = <3300000>;
 					};
@@ -431,7 +409,6 @@
 					// supply for VAUX3; SDcard slots
 					ab8500_ldo_aux3_reg: ab8500_ldo_aux3 {
 						regulator-compatible = "ab8500_ldo_aux3";
-						regulator-name = "V-MMC-SD";
 						regulator-min-microvolt = <1100000>;
 						regulator-max-microvolt = <3300000>;
 					};
@@ -439,49 +416,41 @@
 					// supply for v-intcore12; VINTCORE12 LDO
 					ab8500_ldo_initcore_reg: ab8500_ldo_initcore {
 						regulator-compatible = "ab8500_ldo_initcore";
-						regulator-name = "V-INTCORE";
 					};
 
 					// supply for tvout; gpadc; TVOUT LDO
 					ab8500_ldo_tvout_reg: ab8500_ldo_tvout {
 						regulator-compatible = "ab8500_ldo_tvout";
-						regulator-name = "V-TVOUT";
 					};
 
 					// supply for ab8500-usb; USB LDO
 					ab8500_ldo_usb_reg: ab8500_ldo_usb {
 						regulator-compatible = "ab8500_ldo_usb";
-						regulator-name = "dummy";
 					};
 
 					// supply for ab8500-vaudio; VAUDIO LDO
 					ab8500_ldo_audio_reg: ab8500_ldo_audio {
 						regulator-compatible = "ab8500_ldo_audio";
-						regulator-name = "V-AUD";
 					};
 
 					// supply for v-anamic1 VAMic1-LDO
 					ab8500_ldo_anamic1_reg: ab8500_ldo_anamic1 {
 						regulator-compatible = "ab8500_ldo_anamic1";
-						regulator-name = "V-AMIC1";
 					};
 
 					// supply for v-amic2; VAMIC2 LDO; reuse constants for AMIC1
 					ab8500_ldo_amamic2_reg: ab8500_ldo_amamic2 {
 						regulator-compatible = "ab8500_ldo_amamic2";
-						regulator-name = "V-AMIC2";
 					};
 
 					// supply for v-dmic; VDMIC LDO
 					ab8500_ldo_dmic_reg: ab8500_ldo_dmic {
 						regulator-compatible = "ab8500_ldo_dmic";
-						regulator-name = "V-DMIC";
 					};
 
 					// supply for U8500 CSI/DSI; VANA LDO
 					ab8500_ldo_ana_reg: ab8500_ldo_ana {
 						regulator-compatible = "ab8500_ldo_ana";
-						regulator-name = "V-CSI/DSI";
 					};
 				};
 			};
@@ -585,42 +554,42 @@
 			status = "disabled";
 		};
 
-		sdi@80126000 {
+		sdi0_per1@80126000 {
 			compatible = "arm,pl18x", "arm,primecell";
 			reg = <0x80126000 0x1000>;
 			interrupts = <0 60 0x4>;
 			status = "disabled";
 		};
 
-		sdi@80118000 {
+		sdi1_per2@80118000 {
 			compatible = "arm,pl18x", "arm,primecell";
 			reg = <0x80118000 0x1000>;
 			interrupts = <0 50 0x4>;
 			status = "disabled";
 		};
 
-		sdi@80005000 {
+		sdi2_per3@80005000 {
 			compatible = "arm,pl18x", "arm,primecell";
 			reg = <0x80005000 0x1000>;
 			interrupts = <0 41 0x4>;
 			status = "disabled";
 		};
 
-		sdi@80119000 {
+		sdi3_per2@80119000 {
 			compatible = "arm,pl18x", "arm,primecell";
 			reg = <0x80119000 0x1000>;
 			interrupts = <0 59 0x4>;
 			status = "disabled";
 		};
 
-		sdi@80114000 {
+		sdi4_per2@80114000 {
 			compatible = "arm,pl18x", "arm,primecell";
 			reg = <0x80114000 0x1000>;
 			interrupts = <0 99 0x4>;
 			status = "disabled";
 		};
 
-		sdi@80008000 {
+		sdi5_per3@80008000 {
 			compatible = "arm,pl18x", "arm,primecell";
 			reg = <0x80008000 0x1000>;
 			interrupts = <0 100 0x4>;
@@ -674,5 +643,18 @@
 			status = "disabled";
 		 };
 
+		vmmci: regulator-gpio {
+			compatible = "regulator-gpio";
+
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <2600000>;
+			regulator-name = "mmci-reg";
+			regulator-type = "voltage";
+
+			states = <1800000 0x1
+				  2900000 0x0>;
+
+			status = "disabled";
+		};
 	};
 };
diff --git a/arch/arm/boot/dts/dove-cubox.dts b/arch/arm/boot/dts/dove-cubox.dts
index 0adbd5a..fed7d3f 100644
--- a/arch/arm/boot/dts/dove-cubox.dts
+++ b/arch/arm/boot/dts/dove-cubox.dts
@@ -40,3 +40,13 @@
 		reg = <0>;
 	};
 };
+
+&pinctrl {
+	pinctrl-0 = <&pmx_gpio_18>;
+	pinctrl-names = "default";
+
+	pmx_gpio_18: pmx-gpio-18 {
+		marvell,pins = "mpp18";
+		marvell,function = "gpio";
+	};
+};
diff --git a/arch/arm/boot/dts/dove.dtsi b/arch/arm/boot/dts/dove.dtsi
index 5a00022..61f3914 100644
--- a/arch/arm/boot/dts/dove.dtsi
+++ b/arch/arm/boot/dts/dove.dtsi
@@ -4,6 +4,12 @@
 	compatible = "marvell,dove";
 	model = "Marvell Armada 88AP510 SoC";
 
+	aliases {
+		gpio0 = &gpio0;
+		gpio1 = &gpio1;
+		gpio2 = &gpio2;
+	};
+
 	soc@f1000000 {
 		compatible = "simple-bus";
 		#address-cells = <1>;
@@ -72,7 +78,8 @@
 			#gpio-cells = <2>;
 			gpio-controller;
 			reg = <0xd0400 0x20>;
-			ngpio = <32>;
+			ngpios = <32>;
+			interrupt-controller;
 			interrupts = <12>, <13>, <14>, <60>;
 		};
 
@@ -81,7 +88,8 @@
 			#gpio-cells = <2>;
 			gpio-controller;
 			reg = <0xd0420 0x20>;
-			ngpio = <32>;
+			ngpios = <32>;
+			interrupt-controller;
 			interrupts = <61>;
 		};
 
@@ -90,7 +98,12 @@
 			#gpio-cells = <2>;
 			gpio-controller;
 			reg = <0xe8400 0x0c>;
-			ngpio = <8>;
+			ngpios = <8>;
+		};
+
+		pinctrl: pinctrl@d0200 {
+			compatible = "marvell,dove-pinctrl";
+			reg = <0xd0200 0x10>;
 		};
 
 		spi0: spi@10600 {
diff --git a/arch/arm/boot/dts/evk-pro3.dts b/arch/arm/boot/dts/evk-pro3.dts
index b7354e6..96e50f5 100644
--- a/arch/arm/boot/dts/evk-pro3.dts
+++ b/arch/arm/boot/dts/evk-pro3.dts
@@ -22,10 +22,22 @@
 				status = "okay";
 			};
 
+			usart0: serial@fffb0000 {
+				status = "okay";
+			};
+
+			usart2: serial@fffb8000 {
+				status = "okay";
+			};
+
 			usb1: gadget@fffa4000 {
 				atmel,vbus-gpio = <&pioC 5 0>;
 				status = "okay";
 			};
+
+			watchdog@fffffd40 {
+				status = "okay";
+			};
 		};
 
 		usb0: ohci@00500000 {
diff --git a/arch/arm/boot/dts/exynos4.dtsi b/arch/arm/boot/dts/exynos4.dtsi
index 96d4462..e1347fc 100644
--- a/arch/arm/boot/dts/exynos4.dtsi
+++ b/arch/arm/boot/dts/exynos4.dtsi
@@ -28,6 +28,44 @@
 		spi0 = &spi_0;
 		spi1 = &spi_1;
 		spi2 = &spi_2;
+		i2c0 = &i2c_0;
+		i2c1 = &i2c_1;
+		i2c2 = &i2c_2;
+		i2c3 = &i2c_3;
+		i2c4 = &i2c_4;
+		i2c5 = &i2c_5;
+		i2c6 = &i2c_6;
+		i2c7 = &i2c_7;
+	};
+
+	pd_mfc: mfc-power-domain@10023C40 {
+		compatible = "samsung,exynos4210-pd";
+		reg = <0x10023C40 0x20>;
+	};
+
+	pd_g3d: g3d-power-domain@10023C60 {
+		compatible = "samsung,exynos4210-pd";
+		reg = <0x10023C60 0x20>;
+	};
+
+	pd_lcd0: lcd0-power-domain@10023C80 {
+		compatible = "samsung,exynos4210-pd";
+		reg = <0x10023C80 0x20>;
+	};
+
+	pd_tv: tv-power-domain@10023C20 {
+		compatible = "samsung,exynos4210-pd";
+		reg = <0x10023C20 0x20>;
+	};
+
+	pd_cam: cam-power-domain@10023C00 {
+		compatible = "samsung,exynos4210-pd";
+		reg = <0x10023C00 0x20>;
+	};
+
+	pd_gps: gps-power-domain@10023CE0 {
+		compatible = "samsung,exynos4210-pd";
+		reg = <0x10023CE0 0x20>;
 	};
 
 	gic:interrupt-controller@10490000 {
@@ -121,7 +159,7 @@
 		status = "disabled";
 	};
 
-	i2c@13860000 {
+	i2c_0: i2c@13860000 {
 		#address-cells = <1>;
 		#size-cells = <0>;
 		compatible = "samsung,s3c2440-i2c";
@@ -130,7 +168,7 @@
 		status = "disabled";
 	};
 
-	i2c@13870000 {
+	i2c_1: i2c@13870000 {
 		#address-cells = <1>;
 		#size-cells = <0>;
 		compatible = "samsung,s3c2440-i2c";
@@ -139,7 +177,7 @@
 		status = "disabled";
 	};
 
-	i2c@13880000 {
+	i2c_2: i2c@13880000 {
 		#address-cells = <1>;
 		#size-cells = <0>;
 		compatible = "samsung,s3c2440-i2c";
@@ -148,7 +186,7 @@
 		status = "disabled";
 	};
 
-	i2c@13890000 {
+	i2c_3: i2c@13890000 {
 		#address-cells = <1>;
 		#size-cells = <0>;
 		compatible = "samsung,s3c2440-i2c";
@@ -157,7 +195,7 @@
 		status = "disabled";
 	};
 
-	i2c@138A0000 {
+	i2c_4: i2c@138A0000 {
 		#address-cells = <1>;
 		#size-cells = <0>;
 		compatible = "samsung,s3c2440-i2c";
@@ -166,7 +204,7 @@
 		status = "disabled";
 	};
 
-	i2c@138B0000 {
+	i2c_5: i2c@138B0000 {
 		#address-cells = <1>;
 		#size-cells = <0>;
 		compatible = "samsung,s3c2440-i2c";
@@ -175,7 +213,7 @@
 		status = "disabled";
 	};
 
-	i2c@138C0000 {
+	i2c_6: i2c@138C0000 {
 		#address-cells = <1>;
 		#size-cells = <0>;
 		compatible = "samsung,s3c2440-i2c";
@@ -184,7 +222,7 @@
 		status = "disabled";
 	};
 
-	i2c@138D0000 {
+	i2c_7: i2c@138D0000 {
 		#address-cells = <1>;
 		#size-cells = <0>;
 		compatible = "samsung,s3c2440-i2c";
diff --git a/arch/arm/boot/dts/exynos4210-origen.dts b/arch/arm/boot/dts/exynos4210-origen.dts
index 3e68f52..f271001 100644
--- a/arch/arm/boot/dts/exynos4210-origen.dts
+++ b/arch/arm/boot/dts/exynos4210-origen.dts
@@ -22,38 +22,54 @@
 	compatible = "insignal,origen", "samsung,exynos4210";
 
 	memory {
-		reg = <0x40000000 0x40000000>;
+		reg = <0x40000000 0x10000000
+		       0x50000000 0x10000000
+		       0x60000000 0x10000000
+		       0x70000000 0x10000000>;
 	};
 
 	chosen {
 		bootargs ="root=/dev/ram0 rw ramdisk=8192 initrd=0x41000000,8M console=ttySAC2,115200 init=/linuxrc";
 	};
 
+	mmc_reg: voltage-regulator {
+	        compatible = "regulator-fixed";
+		regulator-name = "VMEM_VDD_2.8V";
+		regulator-min-microvolt = <2800000>;
+		regulator-max-microvolt = <2800000>;
+		gpio = <&gpx1 1 0>;
+		enable-active-high;
+	};
+
 	sdhci@12530000 {
-		samsung,sdhci-bus-width = <4>;
-		linux,mmc_cap_4_bit_data;
-		samsung,sdhci-cd-internal;
-		gpio-cd = <&gpk2 2 2 3 3>;
-		gpios = <&gpk2 0 2 0 3>,
-			<&gpk2 1 2 0 3>,
-			<&gpk2 3 2 3 3>,
-			<&gpk2 4 2 3 3>,
-			<&gpk2 5 2 3 3>,
-			<&gpk2 6 2 3 3>;
+		bus-width = <4>;
+		pinctrl-0 = <&sd2_clk &sd2_cmd &sd2_bus4 &sd2_cd>;
+		pinctrl-names = "default";
+		vmmc-supply = <&mmc_reg>;
 		status = "okay";
 	};
 
 	sdhci@12510000 {
-		samsung,sdhci-bus-width = <4>;
-		linux,mmc_cap_4_bit_data;
-		samsung,sdhci-cd-internal;
-		gpio-cd = <&gpk0 2 2 3 3>;
-		gpios = <&gpk0 0 2 0 3>,
-			<&gpk0 1 2 0 3>,
-			<&gpk0 3 2 3 3>,
-			<&gpk0 4 2 3 3>,
-			<&gpk0 5 2 3 3>,
-			<&gpk0 6 2 3 3>;
+		bus-width = <4>;
+		pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_cd>;
+		pinctrl-names = "default";
+		vmmc-supply = <&mmc_reg>;
+		status = "okay";
+	};
+
+	serial@13800000 {
+		status = "okay";
+	};
+
+	serial@13810000 {
+		status = "okay";
+	};
+
+	serial@13820000 {
+		status = "okay";
+	};
+
+	serial@13830000 {
 		status = "okay";
 	};
 
@@ -64,35 +80,35 @@
 
 		up {
 			label = "Up";
-			gpios = <&gpx2 0 0 0x10000 2>;
+			gpios = <&gpx2 0 1>;
 			linux,code = <103>;
 			gpio-key,wakeup;
 		};
 
 		down {
 			label = "Down";
-			gpios = <&gpx2 1 0 0x10000 2>;
+			gpios = <&gpx2 1 1>;
 			linux,code = <108>;
 			gpio-key,wakeup;
 		};
 
 		back {
 			label = "Back";
-			gpios = <&gpx1 7 0 0x10000 2>;
+			gpios = <&gpx1 7 1>;
 			linux,code = <158>;
 			gpio-key,wakeup;
 		};
 
 		home {
 			label = "Home";
-			gpios = <&gpx1 6 0 0x10000 2>;
+			gpios = <&gpx1 6 1>;
 			linux,code = <102>;
 			gpio-key,wakeup;
 		};
 
 		menu {
 			label = "Menu";
-			gpios = <&gpx1 5 0 0x10000 2>;
+			gpios = <&gpx1 5 1>;
 			linux,code = <139>;
 			gpio-key,wakeup;
 		};
@@ -101,7 +117,7 @@
 	leds {
 		compatible = "gpio-leds";
 		status {
-			gpios = <&gpx1 3 0 0x10000 2>;
+			gpios = <&gpx1 3 1>;
 			linux,default-trigger = "heartbeat";
 		};
 	};
diff --git a/arch/arm/boot/dts/exynos4210-pinctrl.dtsi b/arch/arm/boot/dts/exynos4210-pinctrl.dtsi
index 6a4a1a0..55a2efb 100644
--- a/arch/arm/boot/dts/exynos4210-pinctrl.dtsi
+++ b/arch/arm/boot/dts/exynos4210-pinctrl.dtsi
@@ -482,196 +482,196 @@
 			samsung,pins = "gpk0-0";
 			samsung,pin-function = <2>;
 			samsung,pin-pud = <0>;
-			samsung,pin-drv = <0>;
+			samsung,pin-drv = <3>;
 		};
 
 		sd0_cmd: sd0-cmd {
 			samsung,pins = "gpk0-1";
 			samsung,pin-function = <2>;
 			samsung,pin-pud = <0>;
-			samsung,pin-drv = <0>;
+			samsung,pin-drv = <3>;
 		};
 
 		sd0_cd: sd0-cd {
 			samsung,pins = "gpk0-2";
 			samsung,pin-function = <2>;
 			samsung,pin-pud = <3>;
-			samsung,pin-drv = <0>;
+			samsung,pin-drv = <3>;
 		};
 
 		sd0_bus1: sd0-bus-width1 {
 			samsung,pins = "gpk0-3";
 			samsung,pin-function = <2>;
 			samsung,pin-pud = <3>;
-			samsung,pin-drv = <0>;
+			samsung,pin-drv = <3>;
 		};
 
 		sd0_bus4: sd0-bus-width4 {
 			samsung,pins = "gpk0-3", "gpk0-4", "gpk0-5", "gpk0-6";
 			samsung,pin-function = <2>;
 			samsung,pin-pud = <3>;
-			samsung,pin-drv = <0>;
+			samsung,pin-drv = <3>;
 		};
 
 		sd0_bus8: sd0-bus-width8 {
 			samsung,pins = "gpk1-3", "gpk1-4", "gpk1-5", "gpk1-6";
 			samsung,pin-function = <3>;
 			samsung,pin-pud = <3>;
-			samsung,pin-drv = <0>;
+			samsung,pin-drv = <3>;
 		};
 
 		sd4_clk: sd4-clk {
 			samsung,pins = "gpk0-0";
 			samsung,pin-function = <3>;
 			samsung,pin-pud = <0>;
-			samsung,pin-drv = <0>;
+			samsung,pin-drv = <3>;
 		};
 
 		sd4_cmd: sd4-cmd {
 			samsung,pins = "gpk0-1";
 			samsung,pin-function = <3>;
 			samsung,pin-pud = <0>;
-			samsung,pin-drv = <0>;
+			samsung,pin-drv = <3>;
 		};
 
 		sd4_cd: sd4-cd {
 			samsung,pins = "gpk0-2";
 			samsung,pin-function = <3>;
 			samsung,pin-pud = <3>;
-			samsung,pin-drv = <0>;
+			samsung,pin-drv = <3>;
 		};
 
 		sd4_bus1: sd4-bus-width1 {
 			samsung,pins = "gpk0-3";
 			samsung,pin-function = <3>;
 			samsung,pin-pud = <3>;
-			samsung,pin-drv = <0>;
+			samsung,pin-drv = <3>;
 		};
 
 		sd4_bus4: sd4-bus-width4 {
 			samsung,pins = "gpk0-3", "gpk0-4", "gpk0-5", "gpk0-6";
 			samsung,pin-function = <3>;
 			samsung,pin-pud = <3>;
-			samsung,pin-drv = <0>;
+			samsung,pin-drv = <3>;
 		};
 
 		sd4_bus8: sd4-bus-width8 {
 			samsung,pins = "gpk1-3", "gpk1-4", "gpk1-5", "gpk1-6";
 			samsung,pin-function = <3>;
 			samsung,pin-pud = <4>;
-			samsung,pin-drv = <0>;
+			samsung,pin-drv = <3>;
 		};
 
 		sd1_clk: sd1-clk {
 			samsung,pins = "gpk1-0";
 			samsung,pin-function = <2>;
 			samsung,pin-pud = <0>;
-			samsung,pin-drv = <0>;
+			samsung,pin-drv = <3>;
 		};
 
 		sd1_cmd: sd1-cmd {
 			samsung,pins = "gpk1-1";
 			samsung,pin-function = <2>;
 			samsung,pin-pud = <0>;
-			samsung,pin-drv = <0>;
+			samsung,pin-drv = <3>;
 		};
 
 		sd1_cd: sd1-cd {
 			samsung,pins = "gpk1-2";
 			samsung,pin-function = <2>;
 			samsung,pin-pud = <3>;
-			samsung,pin-drv = <0>;
+			samsung,pin-drv = <3>;
 		};
 
 		sd1_bus1: sd1-bus-width1 {
 			samsung,pins = "gpk1-3";
 			samsung,pin-function = <2>;
 			samsung,pin-pud = <3>;
-			samsung,pin-drv = <0>;
+			samsung,pin-drv = <3>;
 		};
 
 		sd1_bus4: sd1-bus-width4 {
 			samsung,pins = "gpk1-3", "gpk1-4", "gpk1-5", "gpk1-6";
 			samsung,pin-function = <2>;
 			samsung,pin-pud = <3>;
-			samsung,pin-drv = <0>;
+			samsung,pin-drv = <3>;
 		};
 
 		sd2_clk: sd2-clk {
 			samsung,pins = "gpk2-0";
 			samsung,pin-function = <2>;
 			samsung,pin-pud = <0>;
-			samsung,pin-drv = <0>;
+			samsung,pin-drv = <3>;
 		};
 
 		sd2_cmd: sd2-cmd {
 			samsung,pins = "gpk2-1";
 			samsung,pin-function = <2>;
 			samsung,pin-pud = <0>;
-			samsung,pin-drv = <0>;
+			samsung,pin-drv = <3>;
 		};
 
 		sd2_cd: sd2-cd {
 			samsung,pins = "gpk2-2";
 			samsung,pin-function = <2>;
 			samsung,pin-pud = <3>;
-			samsung,pin-drv = <0>;
+			samsung,pin-drv = <3>;
 		};
 
 		sd2_bus1: sd2-bus-width1 {
 			samsung,pins = "gpk2-3";
 			samsung,pin-function = <2>;
 			samsung,pin-pud = <3>;
-			samsung,pin-drv = <0>;
+			samsung,pin-drv = <3>;
 		};
 
 		sd2_bus4: sd2-bus-width4 {
 			samsung,pins = "gpk2-3", "gpk2-4", "gpk2-5", "gpk2-6";
 			samsung,pin-function = <2>;
 			samsung,pin-pud = <3>;
-			samsung,pin-drv = <0>;
+			samsung,pin-drv = <3>;
 		};
 
 		sd2_bus8: sd2-bus-width8 {
 			samsung,pins = "gpk3-3", "gpk3-4", "gpk3-5", "gpk3-6";
 			samsung,pin-function = <3>;
 			samsung,pin-pud = <3>;
-			samsung,pin-drv = <0>;
+			samsung,pin-drv = <3>;
 		};
 
 		sd3_clk: sd3-clk {
 			samsung,pins = "gpk3-0";
 			samsung,pin-function = <2>;
 			samsung,pin-pud = <0>;
-			samsung,pin-drv = <0>;
+			samsung,pin-drv = <3>;
 		};
 
 		sd3_cmd: sd3-cmd {
 			samsung,pins = "gpk3-1";
 			samsung,pin-function = <2>;
 			samsung,pin-pud = <0>;
-			samsung,pin-drv = <0>;
+			samsung,pin-drv = <3>;
 		};
 
 		sd3_cd: sd3-cd {
 			samsung,pins = "gpk3-2";
 			samsung,pin-function = <2>;
 			samsung,pin-pud = <3>;
-			samsung,pin-drv = <0>;
+			samsung,pin-drv = <3>;
 		};
 
 		sd3_bus1: sd3-bus-width1 {
 			samsung,pins = "gpk3-3";
 			samsung,pin-function = <2>;
 			samsung,pin-pud = <3>;
-			samsung,pin-drv = <0>;
+			samsung,pin-drv = <3>;
 		};
 
 		sd3_bus4: sd3-bus-width4 {
 			samsung,pins = "gpk3-3", "gpk3-4", "gpk3-5", "gpk3-6";
 			samsung,pin-function = <2>;
 			samsung,pin-pud = <3>;
-			samsung,pin-drv = <0>;
+			samsung,pin-drv = <3>;
 		};
 
 		eint0: ext-int0 {
diff --git a/arch/arm/boot/dts/exynos4210-smdkv310.dts b/arch/arm/boot/dts/exynos4210-smdkv310.dts
index 63610c3..9b23a82 100644
--- a/arch/arm/boot/dts/exynos4210-smdkv310.dts
+++ b/arch/arm/boot/dts/exynos4210-smdkv310.dts
@@ -43,6 +43,22 @@
 		status = "okay";
 	};
 
+	serial@13800000 {
+		status = "okay";
+	};
+
+	serial@13810000 {
+		status = "okay";
+	};
+
+	serial@13820000 {
+		status = "okay";
+	};
+
+	serial@13830000 {
+		status = "okay";
+	};
+
 	keypad@100A0000 {
 		samsung,keypad-num-rows = <2>;
 		samsung,keypad-num-columns = <8>;
diff --git a/arch/arm/boot/dts/exynos4210-trats.dts b/arch/arm/boot/dts/exynos4210-trats.dts
index a21511c..c346b64 100644
--- a/arch/arm/boot/dts/exynos4210-trats.dts
+++ b/arch/arm/boot/dts/exynos4210-trats.dts
@@ -35,24 +35,15 @@
 		regulator-name = "VMEM_VDD_2.8V";
 		regulator-min-microvolt = <2800000>;
 		regulator-max-microvolt = <2800000>;
-		gpio = <&gpk0 2 1 0 0>;
+		gpio = <&gpk0 2 0>;
 		enable-active-high;
 	};
 
 	sdhci_emmc: sdhci@12510000 {
 		bus-width = <8>;
 		non-removable;
-		broken-voltage;
-		gpios = <&gpk0 0 2 0 3>,
-			<&gpk0 1 2 0 3>,
-			<&gpk0 3 2 2 3>,
-			<&gpk0 4 2 2 3>,
-			<&gpk0 5 2 2 3>,
-			<&gpk0 6 2 2 3>,
-			<&gpk1 3 3 3 3>,
-			<&gpk1 4 3 3 3>,
-			<&gpk1 5 3 3 3>,
-			<&gpk1 6 3 3 3>;
+		pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus8>;
+		pinctrl-names = "default";
 		vmmc-supply = <&vemmc_reg>;
 		status = "okay";
 	};
@@ -73,12 +64,74 @@
 		status = "okay";
 	};
 
+	gpio-keys {
+		compatible = "gpio-keys";
+
+		vol-down-key {
+			gpios = <&gpx2 1 1>;
+			linux,code = <114>;
+			label = "volume down";
+			debounce-interval = <10>;
+		};
+
+		vol-up-key {
+			gpios = <&gpx2 0 1>;
+			linux,code = <115>;
+			label = "volume up";
+			debounce-interval = <10>;
+		};
+
+		power-key {
+			gpios = <&gpx2 7 1>;
+			linux,code = <116>;
+			label = "power";
+			debounce-interval = <10>;
+			gpio-key,wakeup;
+		};
+
+		ok-key {
+			gpios = <&gpx3 5 1>;
+			linux,code = <352>;
+			label = "ok";
+			debounce-interval = <10>;
+		};
+	};
+
+	tsp_reg: voltage-regulator {
+		compatible = "regulator-fixed";
+		regulator-name = "TSP_FIXED_VOLTAGES";
+		regulator-min-microvolt = <2800000>;
+		regulator-max-microvolt = <2800000>;
+		gpio = <&gpl0 3 0>;
+		enable-active-high;
+	};
+
+	i2c@13890000 {
+		samsung,i2c-sda-delay = <100>;
+		samsung,i2c-slave-addr = <0x10>;
+		samsung,i2c-max-bus-freq = <400000>;
+		pinctrl-0 = <&i2c3_bus>;
+		pinctrl-names = "default";
+		status = "okay";
+
+		mms114-touchscreen@48 {
+			compatible = "melfas,mms114";
+			reg = <0x48>;
+			interrupt-parent = <&gpx0>;
+			interrupts = <4 2>;
+			x-size = <720>;
+			y-size = <1280>;
+			avdd-supply = <&tsp_reg>;
+			vdd-supply = <&tsp_reg>;
+		};
+	};
+
 	i2c@138B0000 {
 		samsung,i2c-sda-delay = <100>;
 		samsung,i2c-slave-addr = <0x10>;
 		samsung,i2c-max-bus-freq = <100000>;
-		gpios = <&gpb 6 3 3 0>,
-			<&gpb 7 3 3 0>;
+		pinctrl-0 = <&i2c5_bus>;
+		pinctrl-names = "default";
 		status = "okay";
 
 		max8997_pmic@66 {
@@ -93,9 +146,9 @@
 			max8997,pmic-ignore-gpiodvs-side-effect;
 			max8997,pmic-buck125-default-dvs-idx = <0>;
 
-			max8997,pmic-buck125-dvs-gpios = <&gpx0 5 1 0 0>,
-						         <&gpx0 6 1 0 0>,
-							 <&gpl0 0 1 0 0>;
+			max8997,pmic-buck125-dvs-gpios = <&gpx0 5 0>,
+						         <&gpx0 6 0>,
+							 <&gpl0 0 0>;
 
 			max8997,pmic-buck1-dvs-voltage = <1350000>, <1300000>,
 							 <1250000>, <1200000>,
diff --git a/arch/arm/boot/dts/exynos4210.dtsi b/arch/arm/boot/dts/exynos4210.dtsi
index d877dbe..e31bfc4 100644
--- a/arch/arm/boot/dts/exynos4210.dtsi
+++ b/arch/arm/boot/dts/exynos4210.dtsi
@@ -31,6 +31,11 @@
 		pinctrl2 = &pinctrl_2;
 	};
 
+	pd_lcd1: lcd1-power-domain@10023CA0 {
+		compatible = "samsung,exynos4210-pd";
+		reg = <0x10023CA0 0x20>;
+	};
+
 	gic:interrupt-controller@10490000 {
 		cpu-offset = <0x8000>;
 	};
@@ -64,4 +69,11 @@
 		compatible = "samsung,pinctrl-exynos4210";
 		reg = <0x03860000 0x1000>;
 	};
+
+	tmu@100C0000 {
+		compatible = "samsung,exynos4210-tmu";
+		interrupt-parent = <&combiner>;
+		reg = <0x100C0000 0x100>;
+		interrupts = <2 4>;
+	};
 };
diff --git a/arch/arm/boot/dts/exynos4212.dtsi b/arch/arm/boot/dts/exynos4212.dtsi
new file mode 100644
index 0000000..c6ae200
--- /dev/null
+++ b/arch/arm/boot/dts/exynos4212.dtsi
@@ -0,0 +1,28 @@
+/*
+ * Samsung's Exynos4212 SoC device tree source
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com
+ *
+ * Samsung's Exynos4212 SoC device nodes are listed in this file. Exynos4212
+ * based board files can include this file and provide values for board specfic
+ * bindings.
+ *
+ * Note: This file does not include device nodes for all the controllers in
+ * Exynos4212 SoC. As device tree coverage for Exynos4212 increases, additional
+ * nodes can be added to this file.
+ *
+ * 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/ "exynos4x12.dtsi"
+
+/ {
+	compatible = "samsung,exynos4212";
+
+	gic:interrupt-controller@10490000 {
+		cpu-offset = <0x8000>;
+	};
+};
diff --git a/arch/arm/boot/dts/exynos4412-smdk4412.dts b/arch/arm/boot/dts/exynos4412-smdk4412.dts
new file mode 100644
index 0000000..f05bf57
--- /dev/null
+++ b/arch/arm/boot/dts/exynos4412-smdk4412.dts
@@ -0,0 +1,45 @@
+/*
+ * Samsung's Exynos4412 based SMDK board device tree source
+ *
+ * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com
+ *
+ * Device tree source file for Samsung's SMDK4412 board which is based on
+ * Samsung's Exynos4412 SoC.
+ *
+ * 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.
+*/
+
+/dts-v1/;
+/include/ "exynos4412.dtsi"
+
+/ {
+	model = "Samsung SMDK evaluation board based on Exynos4412";
+	compatible = "samsung,smdk4412", "samsung,exynos4412";
+
+	memory {
+		reg = <0x40000000 0x40000000>;
+	};
+
+	chosen {
+		bootargs ="root=/dev/ram0 rw ramdisk=8192 initrd=0x41000000,8M console=ttySAC1,115200 init=/linuxrc";
+	};
+
+	serial@13800000 {
+		status = "okay";
+	};
+
+	serial@13810000 {
+		status = "okay";
+	};
+
+	serial@13820000 {
+		status = "okay";
+	};
+
+	serial@13830000 {
+		status = "okay";
+	};
+};
diff --git a/arch/arm/boot/dts/exynos4412.dtsi b/arch/arm/boot/dts/exynos4412.dtsi
new file mode 100644
index 0000000..d7dfe31
--- /dev/null
+++ b/arch/arm/boot/dts/exynos4412.dtsi
@@ -0,0 +1,28 @@
+/*
+ * Samsung's Exynos4412 SoC device tree source
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com
+ *
+ * Samsung's Exynos4412 SoC device nodes are listed in this file. Exynos4412
+ * based board files can include this file and provide values for board specfic
+ * bindings.
+ *
+ * Note: This file does not include device nodes for all the controllers in
+ * Exynos4412 SoC. As device tree coverage for Exynos4412 increases, additional
+ * nodes can be added to this file.
+ *
+ * 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/ "exynos4x12.dtsi"
+
+/ {
+	compatible = "samsung,exynos4412";
+
+	gic:interrupt-controller@10490000 {
+		cpu-offset = <0x4000>;
+	};
+};
diff --git a/arch/arm/boot/dts/exynos4x12-pinctrl.dtsi b/arch/arm/boot/dts/exynos4x12-pinctrl.dtsi
new file mode 100644
index 0000000..8e6115a
--- /dev/null
+++ b/arch/arm/boot/dts/exynos4x12-pinctrl.dtsi
@@ -0,0 +1,965 @@
+/*
+ * Samsung's Exynos4x12 SoCs pin-mux and pin-config device tree source
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com
+ *
+ * Samsung's Exynos4x12 SoCs pin-mux and pin-config optiosn are listed as device
+ * tree nodes are listed in this file.
+ *
+ * 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.
+*/
+
+/ {
+	pinctrl@11400000 {
+		gpa0: gpa0 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpa1: gpa1 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpb: gpb {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpc0: gpc0 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpc1: gpc1 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpd0: gpd0 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpd1: gpd1 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpf0: gpf0 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpf1: gpf1 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpf2: gpf2 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpf3: gpf3 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpj0: gpj0 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpj1: gpj1 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		uart0_data: uart0-data {
+			samsung,pins = "gpa0-0", "gpa0-1";
+			samsung,pin-function = <0x2>;
+			samsung,pin-pud = <0>;
+			samsung,pin-drv = <0>;
+		};
+
+		uart0_fctl: uart0-fctl {
+			samsung,pins = "gpa0-2", "gpa0-3";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <0>;
+			samsung,pin-drv = <0>;
+		};
+
+		uart1_data: uart1-data {
+			samsung,pins = "gpa0-4", "gpa0-5";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <0>;
+			samsung,pin-drv = <0>;
+		};
+
+		uart1_fctl: uart1-fctl {
+			samsung,pins = "gpa0-6", "gpa0-7";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <0>;
+			samsung,pin-drv = <0>;
+		};
+
+		i2c2_bus: i2c2-bus {
+			samsung,pins = "gpa0-6", "gpa0-7";
+			samsung,pin-function = <3>;
+			samsung,pin-pud = <3>;
+			samsung,pin-drv = <0>;
+		};
+
+		uart2_data: uart2-data {
+			samsung,pins = "gpa1-0", "gpa1-1";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <0>;
+			samsung,pin-drv = <0>;
+		};
+
+		uart2_fctl: uart2-fctl {
+			samsung,pins = "gpa1-2", "gpa1-3";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <0>;
+			samsung,pin-drv = <0>;
+		};
+
+		uart_audio_a: uart-audio-a {
+			samsung,pins = "gpa1-0", "gpa1-1";
+			samsung,pin-function = <4>;
+			samsung,pin-pud = <0>;
+			samsung,pin-drv = <0>;
+		};
+
+		i2c3_bus: i2c3-bus {
+			samsung,pins = "gpa1-2", "gpa1-3";
+			samsung,pin-function = <3>;
+			samsung,pin-pud = <3>;
+			samsung,pin-drv = <0>;
+		};
+
+		uart3_data: uart3-data {
+			samsung,pins = "gpa1-4", "gpa1-5";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <0>;
+			samsung,pin-drv = <0>;
+		};
+
+		uart_audio_b: uart-audio-b {
+			samsung,pins = "gpa1-4", "gpa1-5";
+			samsung,pin-function = <4>;
+			samsung,pin-pud = <0>;
+			samsung,pin-drv = <0>;
+		};
+
+		spi0_bus: spi0-bus {
+			samsung,pins = "gpb-0", "gpb-2", "gpb-3";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <3>;
+			samsung,pin-drv = <0>;
+		};
+
+		i2c4_bus: i2c4-bus {
+			samsung,pins = "gpb-0", "gpb-1";
+			samsung,pin-function = <3>;
+			samsung,pin-pud = <3>;
+			samsung,pin-drv = <0>;
+		};
+
+		spi1_bus: spi1-bus {
+			samsung,pins = "gpb-4", "gpb-6", "gpb-7";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <3>;
+			samsung,pin-drv = <0>;
+		};
+
+		i2c5_bus: i2c5-bus {
+			samsung,pins = "gpb-2", "gpb-3";
+			samsung,pin-function = <3>;
+			samsung,pin-pud = <3>;
+			samsung,pin-drv = <0>;
+		};
+
+		i2s1_bus: i2s1-bus {
+			samsung,pins = "gpc0-0", "gpc0-1", "gpc0-2", "gpc0-3",
+					"gpc0-4";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <0>;
+			samsung,pin-drv = <0>;
+		};
+
+		pcm1_bus: pcm1-bus {
+			samsung,pins = "gpc0-0", "gpc0-1", "gpc0-2", "gpc0-3",
+					"gpc0-4";
+			samsung,pin-function = <3>;
+			samsung,pin-pud = <0>;
+			samsung,pin-drv = <0>;
+		};
+
+		ac97_bus: ac97-bus {
+			samsung,pins = "gpc0-0", "gpc0-1", "gpc0-2", "gpc0-3",
+					"gpc0-4";
+			samsung,pin-function = <4>;
+			samsung,pin-pud = <0>;
+			samsung,pin-drv = <0>;
+		};
+
+		i2s2_bus: i2s2-bus {
+			samsung,pins = "gpc1-0", "gpc1-1", "gpc1-2", "gpc1-3",
+					"gpc1-4";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <0>;
+			samsung,pin-drv = <0>;
+		};
+
+		pcm2_bus: pcm2-bus {
+			samsung,pins = "gpc1-0", "gpc1-1", "gpc1-2", "gpc1-3",
+					"gpc1-4";
+			samsung,pin-function = <3>;
+			samsung,pin-pud = <0>;
+			samsung,pin-drv = <0>;
+		};
+
+		spdif_bus: spdif-bus {
+			samsung,pins = "gpc1-0", "gpc1-1";
+			samsung,pin-function = <4>;
+			samsung,pin-pud = <0>;
+			samsung,pin-drv = <0>;
+		};
+
+		i2c6_bus: i2c6-bus {
+			samsung,pins = "gpc1-3", "gpc1-4";
+			samsung,pin-function = <4>;
+			samsung,pin-pud = <3>;
+			samsung,pin-drv = <0>;
+		};
+
+		spi2_bus: spi2-bus {
+			samsung,pins = "gpc1-1", "gpc1-3", "gpc1-4";
+			samsung,pin-function = <5>;
+			samsung,pin-pud = <3>;
+			samsung,pin-drv = <0>;
+		};
+
+		pwm0_out: pwm0-out {
+			samsung,pins = "gpd0-0";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <0>;
+			samsung,pin-drv = <0>;
+		};
+
+		pwm1_out: pwm1-out {
+			samsung,pins = "gpd0-1";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <0>;
+			samsung,pin-drv = <0>;
+		};
+
+		lcd_ctrl: lcd-ctrl {
+			samsung,pins = "gpd0-0", "gpd0-1";
+			samsung,pin-function = <3>;
+			samsung,pin-pud = <0>;
+			samsung,pin-drv = <0>;
+		};
+
+		i2c7_bus: i2c7-bus {
+			samsung,pins = "gpd0-2", "gpd0-3";
+			samsung,pin-function = <3>;
+			samsung,pin-pud = <3>;
+			samsung,pin-drv = <0>;
+		};
+
+		pwm2_out: pwm2-out {
+			samsung,pins = "gpd0-2";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <0>;
+			samsung,pin-drv = <0>;
+		};
+
+		pwm3_out: pwm3-out {
+			samsung,pins = "gpd0-3";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <0>;
+			samsung,pin-drv = <0>;
+		};
+
+		i2c0_bus: i2c0-bus {
+			samsung,pins = "gpd1-0", "gpd1-1";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <3>;
+			samsung,pin-drv = <0>;
+		};
+
+		mipi0_clk: mipi0-clk {
+			samsung,pins = "gpd1-0", "gpd1-1";
+			samsung,pin-function = <3>;
+			samsung,pin-pud = <0>;
+			samsung,pin-drv = <0>;
+		};
+
+		i2c1_bus: i2c1-bus {
+			samsung,pins = "gpd1-2", "gpd1-3";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <3>;
+			samsung,pin-drv = <0>;
+		};
+
+		mipi1_clk: mipi1-clk {
+			samsung,pins = "gpd1-2", "gpd1-3";
+			samsung,pin-function = <3>;
+			samsung,pin-pud = <0>;
+			samsung,pin-drv = <0>;
+		};
+
+		lcd_clk: lcd-clk {
+			samsung,pins = "gpf0-0", "gpf0-1", "gpf0-2", "gpf0-3";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <0>;
+			samsung,pin-drv = <0>;
+		};
+
+		lcd_data16: lcd-data-width16 {
+			samsung,pins = "gpf0-7", "gpf1-0", "gpf1-1", "gpf1-2",
+					"gpf1-3", "gpf1-6", "gpf1-7", "gpf2-0",
+					"gpf2-1", "gpf2-2", "gpf2-3", "gpf2-7",
+					"gpf3-0", "gpf3-1", "gpf3-2", "gpf3-3";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <0>;
+			samsung,pin-drv = <0>;
+		};
+
+		lcd_data18: lcd-data-width18 {
+			samsung,pins = "gpf0-6", "gpf0-7", "gpf1-0", "gpf1-1",
+					"gpf1-2", "gpf1-3", "gpf1-6", "gpf1-7",
+					"gpf2-0", "gpf2-1", "gpf2-2", "gpf2-3",
+					"gpf2-6", "gpf2-7", "gpf3-0", "gpf3-1",
+					"gpf3-2", "gpf3-3";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <0>;
+			samsung,pin-drv = <0>;
+		};
+
+		lcd_data24: lcd-data-width24 {
+			samsung,pins = "gpf0-4", "gpf0-5", "gpf0-6", "gpf0-7",
+					"gpf1-0", "gpf1-1", "gpf1-2", "gpf1-3",
+					"gpf1-4", "gpf1-5", "gpf1-6", "gpf1-7",
+					"gpf2-0", "gpf2-1", "gpf2-2", "gpf2-3",
+					"gpf2-4", "gpf2-5", "gpf2-6", "gpf2-7",
+					"gpf3-0", "gpf3-1", "gpf3-2", "gpf3-3";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <0>;
+			samsung,pin-drv = <0>;
+		};
+
+		lcd_ldi: lcd-ldi {
+			samsung,pins = "gpf3-4";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <0>;
+			samsung,pin-drv = <0>;
+		};
+
+		cam_port_a: cam-port-a {
+			samsung,pins = "gpj0-0", "gpj0-1", "gpj0-2", "gpj0-3",
+					"gpj0-4", "gpj0-5", "gpj0-6", "gpj0-7",
+					"gpj1-0", "gpj1-1", "gpj1-2", "gpj1-3",
+					"gpj1-4";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <3>;
+			samsung,pin-drv = <0>;
+		};
+	};
+
+	pinctrl@11000000 {
+		gpk0: gpk0 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpk1: gpk1 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpk2: gpk2 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpk3: gpk3 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpl0: gpl0 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpl1: gpl1 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpl2: gpl2 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpm0: gpm0 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpm1: gpm1 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpm2: gpm2 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpm3: gpm3 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpm4: gpm4 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpy0: gpy0 {
+			gpio-controller;
+			#gpio-cells = <2>;
+		};
+
+		gpy1: gpy1 {
+			gpio-controller;
+			#gpio-cells = <2>;
+		};
+
+		gpy2: gpy2 {
+			gpio-controller;
+			#gpio-cells = <2>;
+		};
+
+		gpy3: gpy3 {
+			gpio-controller;
+			#gpio-cells = <2>;
+		};
+
+		gpy4: gpy4 {
+			gpio-controller;
+			#gpio-cells = <2>;
+		};
+
+		gpy5: gpy5 {
+			gpio-controller;
+			#gpio-cells = <2>;
+		};
+
+		gpy6: gpy6 {
+			gpio-controller;
+			#gpio-cells = <2>;
+		};
+
+		gpx0: gpx0 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			interrupt-parent = <&gic>;
+			interrupts = <0 16 0>, <0 17 0>, <0 18 0>, <0 19 0>,
+				     <0 20 0>, <0 21 0>, <0 22 0>, <0 23 0>;
+			#interrupt-cells = <2>;
+		};
+
+		gpx1: gpx1 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			interrupt-parent = <&gic>;
+			interrupts = <0 24 0>, <0 25 0>, <0 26 0>, <0 27 0>,
+				     <0 28 0>, <0 29 0>, <0 30 0>, <0 31 0>;
+			#interrupt-cells = <2>;
+		};
+
+		gpx2: gpx2 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpx3: gpx3 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		sd0_clk: sd0-clk {
+			samsung,pins = "gpk0-0";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <0>;
+			samsung,pin-drv = <3>;
+		};
+
+		sd0_cmd: sd0-cmd {
+			samsung,pins = "gpk0-1";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <0>;
+			samsung,pin-drv = <3>;
+		};
+
+		sd0_cd: sd0-cd {
+			samsung,pins = "gpk0-2";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <3>;
+			samsung,pin-drv = <3>;
+		};
+
+		sd0_bus1: sd0-bus-width1 {
+			samsung,pins = "gpk0-3";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <3>;
+			samsung,pin-drv = <3>;
+		};
+
+		sd0_bus4: sd0-bus-width4 {
+			samsung,pins = "gpk0-3", "gpk0-4", "gpk0-5", "gpk0-6";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <3>;
+			samsung,pin-drv = <3>;
+		};
+
+		sd0_bus8: sd0-bus-width8 {
+			samsung,pins = "gpk1-3", "gpk1-4", "gpk1-5", "gpk1-6";
+			samsung,pin-function = <3>;
+			samsung,pin-pud = <3>;
+			samsung,pin-drv = <3>;
+		};
+
+		sd4_clk: sd4-clk {
+			samsung,pins = "gpk0-0";
+			samsung,pin-function = <3>;
+			samsung,pin-pud = <0>;
+			samsung,pin-drv = <3>;
+		};
+
+		sd4_cmd: sd4-cmd {
+			samsung,pins = "gpk0-1";
+			samsung,pin-function = <3>;
+			samsung,pin-pud = <0>;
+			samsung,pin-drv = <3>;
+		};
+
+		sd4_cd: sd4-cd {
+			samsung,pins = "gpk0-2";
+			samsung,pin-function = <3>;
+			samsung,pin-pud = <3>;
+			samsung,pin-drv = <3>;
+		};
+
+		sd4_bus1: sd4-bus-width1 {
+			samsung,pins = "gpk0-3";
+			samsung,pin-function = <3>;
+			samsung,pin-pud = <3>;
+			samsung,pin-drv = <3>;
+		};
+
+		sd4_bus4: sd4-bus-width4 {
+			samsung,pins = "gpk0-3", "gpk0-4", "gpk0-5", "gpk0-6";
+			samsung,pin-function = <3>;
+			samsung,pin-pud = <3>;
+			samsung,pin-drv = <3>;
+		};
+
+		sd4_bus8: sd4-bus-width8 {
+			samsung,pins = "gpk1-3", "gpk1-4", "gpk1-5", "gpk1-6";
+			samsung,pin-function = <3>;
+			samsung,pin-pud = <4>;
+			samsung,pin-drv = <3>;
+		};
+
+		sd1_clk: sd1-clk {
+			samsung,pins = "gpk1-0";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <0>;
+			samsung,pin-drv = <3>;
+		};
+
+		sd1_cmd: sd1-cmd {
+			samsung,pins = "gpk1-1";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <0>;
+			samsung,pin-drv = <3>;
+		};
+
+		sd1_cd: sd1-cd {
+			samsung,pins = "gpk1-2";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <3>;
+			samsung,pin-drv = <3>;
+		};
+
+		sd1_bus1: sd1-bus-width1 {
+			samsung,pins = "gpk1-3";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <3>;
+			samsung,pin-drv = <3>;
+		};
+
+		sd1_bus4: sd1-bus-width4 {
+			samsung,pins = "gpk1-3", "gpk1-4", "gpk1-5", "gpk1-6";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <3>;
+			samsung,pin-drv = <3>;
+		};
+
+		sd2_clk: sd2-clk {
+			samsung,pins = "gpk2-0";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <0>;
+			samsung,pin-drv = <3>;
+		};
+
+		sd2_cmd: sd2-cmd {
+			samsung,pins = "gpk2-1";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <0>;
+			samsung,pin-drv = <3>;
+		};
+
+		sd2_cd: sd2-cd {
+			samsung,pins = "gpk2-2";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <3>;
+			samsung,pin-drv = <3>;
+		};
+
+		sd2_bus1: sd2-bus-width1 {
+			samsung,pins = "gpk2-3";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <3>;
+			samsung,pin-drv = <3>;
+		};
+
+		sd2_bus4: sd2-bus-width4 {
+			samsung,pins = "gpk2-3", "gpk2-4", "gpk2-5", "gpk2-6";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <3>;
+			samsung,pin-drv = <3>;
+		};
+
+		sd2_bus8: sd2-bus-width8 {
+			samsung,pins = "gpk3-3", "gpk3-4", "gpk3-5", "gpk3-6";
+			samsung,pin-function = <3>;
+			samsung,pin-pud = <3>;
+			samsung,pin-drv = <3>;
+		};
+
+		sd3_clk: sd3-clk {
+			samsung,pins = "gpk3-0";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <0>;
+			samsung,pin-drv = <3>;
+		};
+
+		sd3_cmd: sd3-cmd {
+			samsung,pins = "gpk3-1";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <0>;
+			samsung,pin-drv = <3>;
+		};
+
+		sd3_cd: sd3-cd {
+			samsung,pins = "gpk3-2";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <3>;
+			samsung,pin-drv = <3>;
+		};
+
+		sd3_bus1: sd3-bus-width1 {
+			samsung,pins = "gpk3-3";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <3>;
+			samsung,pin-drv = <3>;
+		};
+
+		sd3_bus4: sd3-bus-width4 {
+			samsung,pins = "gpk3-3", "gpk3-4", "gpk3-5", "gpk3-6";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <3>;
+			samsung,pin-drv = <3>;
+		};
+
+		keypad_col0: keypad-col0 {
+			samsung,pins = "gpl2-0";
+			samsung,pin-function = <3>;
+			samsung,pin-pud = <0>;
+			samsung,pin-drv = <0>;
+		};
+
+		keypad_col1: keypad-col1 {
+			samsung,pins = "gpl2-1";
+			samsung,pin-function = <3>;
+			samsung,pin-pud = <0>;
+			samsung,pin-drv = <0>;
+		};
+
+		keypad_col2: keypad-col2 {
+			samsung,pins = "gpl2-2";
+			samsung,pin-function = <3>;
+			samsung,pin-pud = <0>;
+			samsung,pin-drv = <0>;
+		};
+
+		keypad_col3: keypad-col3 {
+			samsung,pins = "gpl2-3";
+			samsung,pin-function = <3>;
+			samsung,pin-pud = <0>;
+			samsung,pin-drv = <0>;
+		};
+
+		keypad_col4: keypad-col4 {
+			samsung,pins = "gpl2-4";
+			samsung,pin-function = <3>;
+			samsung,pin-pud = <0>;
+			samsung,pin-drv = <0>;
+		};
+
+		keypad_col5: keypad-col5 {
+			samsung,pins = "gpl2-5";
+			samsung,pin-function = <3>;
+			samsung,pin-pud = <0>;
+			samsung,pin-drv = <0>;
+		};
+
+		keypad_col6: keypad-col6 {
+			samsung,pins = "gpl2-6";
+			samsung,pin-function = <3>;
+			samsung,pin-pud = <0>;
+			samsung,pin-drv = <0>;
+		};
+
+		keypad_col7: keypad-col7 {
+			samsung,pins = "gpl2-7";
+			samsung,pin-function = <3>;
+			samsung,pin-pud = <0>;
+			samsung,pin-drv = <0>;
+		};
+
+		cam_port_b: cam-port-b {
+			samsung,pins = "gpm0-0", "gpm0-1", "gpm0-2", "gpm0-3",
+					"gpm0-4", "gpm0-5", "gpm0-6", "gpm0-7",
+					"gpm1-0", "gpm1-1", "gpm2-0", "gpm2-1",
+					"gpm2-2";
+			samsung,pin-function = <3>;
+			samsung,pin-pud = <3>;
+			samsung,pin-drv = <0>;
+		};
+
+		eint0: ext-int0 {
+			samsung,pins = "gpx0-0";
+			samsung,pin-function = <0xf>;
+			samsung,pin-pud = <0>;
+			samsung,pin-drv = <0>;
+		};
+
+		eint8: ext-int8 {
+			samsung,pins = "gpx1-0";
+			samsung,pin-function = <0xf>;
+			samsung,pin-pud = <0>;
+			samsung,pin-drv = <0>;
+		};
+
+		eint15: ext-int15 {
+			samsung,pins = "gpx1-7";
+			samsung,pin-function = <0xf>;
+			samsung,pin-pud = <0>;
+			samsung,pin-drv = <0>;
+		};
+
+		eint16: ext-int16 {
+			samsung,pins = "gpx2-0";
+			samsung,pin-function = <0xf>;
+			samsung,pin-pud = <0>;
+			samsung,pin-drv = <0>;
+		};
+
+		eint31: ext-int31 {
+			samsung,pins = "gpx3-7";
+			samsung,pin-function = <0xf>;
+			samsung,pin-pud = <0>;
+			samsung,pin-drv = <0>;
+		};
+	};
+
+	pinctrl@03860000 {
+		gpz: gpz {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		i2s0_bus: i2s0-bus {
+			samsung,pins = "gpz-0", "gpz-1", "gpz-2", "gpz-3",
+					"gpz-4", "gpz-5", "gpz-6";
+			samsung,pin-function = <0x2>;
+			samsung,pin-pud = <0>;
+			samsung,pin-drv = <0>;
+		};
+
+		pcm0_bus: pcm0-bus {
+			samsung,pins = "gpz-0", "gpz-1", "gpz-2", "gpz-3",
+					"gpz-4";
+			samsung,pin-function = <0x3>;
+			samsung,pin-pud = <0>;
+			samsung,pin-drv = <0>;
+		};
+	};
+
+	pinctrl@106E0000 {
+		gpv0: gpv0 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpv1: gpv1 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpv2: gpv2 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpv3: gpv3 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpv4: gpv4 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		c2c_bus: c2c-bus {
+			samsung,pins = "gpv0-0", "gpv0-1", "gpv0-2", "gpv0-3",
+					"gpv0-4", "gpv0-5", "gpv0-6", "gpv0-7",
+					"gpv1-0", "gpv1-1", "gpv1-2", "gpv1-3",
+					"gpv1-4", "gpv1-5", "gpv1-6", "gpv1-7",
+					"gpv2-0", "gpv2-1", "gpv2-2", "gpv2-3",
+					"gpv2-4", "gpv2-5", "gpv2-6", "gpv2-7",
+					"gpv3-0", "gpv3-1", "gpv3-2", "gpv3-3",
+					"gpv3-4", "gpv3-5", "gpv3-6", "gpv3-7",
+					"gpv4-0", "gpv4-1";
+			samsung,pin-function = <0x2>;
+			samsung,pin-pud = <0>;
+			samsung,pin-drv = <0>;
+		};
+	};
+};
diff --git a/arch/arm/boot/dts/exynos4x12.dtsi b/arch/arm/boot/dts/exynos4x12.dtsi
new file mode 100644
index 0000000..179a62e
--- /dev/null
+++ b/arch/arm/boot/dts/exynos4x12.dtsi
@@ -0,0 +1,69 @@
+/*
+ * Samsung's Exynos4x12 SoCs device tree source
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com
+ *
+ * Samsung's Exynos4x12 SoCs device nodes are listed in this file. Exynos4x12
+ * based board files can include this file and provide values for board specfic
+ * bindings.
+ *
+ * Note: This file does not include device nodes for all the controllers in
+ * Exynos4x12 SoC. As device tree coverage for Exynos4x12 increases, additional
+ * nodes can be added to this file.
+ *
+ * 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/ "exynos4.dtsi"
+/include/ "exynos4x12-pinctrl.dtsi"
+
+/ {
+	aliases {
+		pinctrl0 = &pinctrl_0;
+		pinctrl1 = &pinctrl_1;
+		pinctrl2 = &pinctrl_2;
+		pinctrl3 = &pinctrl_3;
+	};
+
+	combiner:interrupt-controller@10440000 {
+		interrupts = <0 0 0>, <0 1 0>, <0 2 0>, <0 3 0>,
+			     <0 4 0>, <0 5 0>, <0 6 0>, <0 7 0>,
+			     <0 8 0>, <0 9 0>, <0 10 0>, <0 11 0>,
+			     <0 12 0>, <0 13 0>, <0 14 0>, <0 15 0>,
+			     <0 16 0>, <0 17 0>, <0 18 0>, <0 19 0>;
+	};
+
+	pinctrl_0: pinctrl@11400000 {
+		compatible = "samsung,pinctrl-exynos4x12";
+		reg = <0x11400000 0x1000>;
+		interrupts = <0 47 0>;
+	};
+
+	pinctrl_1: pinctrl@11000000 {
+		compatible = "samsung,pinctrl-exynos4x12";
+		reg = <0x11000000 0x1000>;
+		interrupts = <0 46 0>;
+
+		wakup_eint: wakeup-interrupt-controller {
+			compatible = "samsung,exynos4210-wakeup-eint";
+			interrupt-parent = <&gic>;
+			interrupts = <0 32 0>;
+		};
+	};
+
+	pinctrl_2: pinctrl@03860000 {
+		compatible = "samsung,pinctrl-exynos4x12";
+		reg = <0x03860000 0x1000>;
+		interrupt-parent = <&combiner>;
+		interrupts = <10 0>;
+	};
+
+	pinctrl_3: pinctrl@106E0000 {
+		compatible = "samsung,pinctrl-exynos4x12";
+		reg = <0x106E0000 0x1000>;
+		interrupts = <0 72 0>;
+	};
+};
diff --git a/arch/arm/boot/dts/exynos5250-smdk5250.dts b/arch/arm/boot/dts/exynos5250-smdk5250.dts
index a352df4..942d576 100644
--- a/arch/arm/boot/dts/exynos5250-smdk5250.dts
+++ b/arch/arm/boot/dts/exynos5250-smdk5250.dts
@@ -17,10 +17,6 @@
 	compatible = "samsung,smdk5250", "samsung,exynos5250";
 
 	aliases {
-		mshc0 = &dwmmc_0;
-		mshc1 = &dwmmc_1;
-		mshc2 = &dwmmc_2;
-		mshc3 = &dwmmc_3;
 	};
 
 	memory {
@@ -55,8 +51,31 @@
 		};
 	};
 
+	i2c@121D0000 {
+		samsung,i2c-sda-delay = <100>;
+		samsung,i2c-max-bus-freq = <40000>;
+		samsung,i2c-slave-addr = <0x38>;
+
+		sata-phy {
+			compatible = "samsung,sata-phy";
+			reg = <0x38>;
+		};
+	};
+
+	sata@122F0000 {
+		samsung,sata-freq = <66>;
+	};
+
 	i2c@12C80000 {
-		status = "disabled";
+		samsung,i2c-sda-delay = <100>;
+		samsung,i2c-max-bus-freq = <66000>;
+		gpios = <&gpa0 6 3 3 0>,
+			<&gpa0 7 3 3 0>;
+
+		hdmiddc@50 {
+			compatible = "samsung,exynos5-hdmiddc";
+			reg = <0x50>;
+		};
 	};
 
 	i2c@12C90000 {
@@ -79,7 +98,17 @@
 		status = "disabled";
 	};
 
-	dwmmc_0: dwmmc0@12200000 {
+	i2c@12CE0000 {
+		samsung,i2c-sda-delay = <100>;
+		samsung,i2c-max-bus-freq = <66000>;
+
+		hdmiphy@38 {
+			compatible = "samsung,exynos5-hdmiphy";
+			reg = <0x38>;
+		};
+	};
+
+	dwmmc0@12200000 {
 		num-slots = <1>;
 		supports-highspeed;
 		broken-cd;
@@ -100,11 +129,11 @@
 		};
 	};
 
-	dwmmc_1: dwmmc1@12210000 {
+	dwmmc1@12210000 {
 		status = "disabled";
 	};
 
-	dwmmc_2: dwmmc2@12220000 {
+	dwmmc2@12220000 {
 		num-slots = <1>;
 		supports-highspeed;
 		fifo-depth = <0x80>;
@@ -125,7 +154,7 @@
 		};
 	};
 
-	dwmmc_3: dwmmc3@12230000 {
+	dwmmc3@12230000 {
 		status = "disabled";
 	};
 
@@ -166,4 +195,13 @@
 	spi_2: spi@12d40000 {
 		status = "disabled";
 	};
+
+	hdmi {
+		hpd-gpio = <&gpx3 7 0xf 1 3>;
+	};
+
+	codec@11000000 {
+		samsung,mfc-r = <0x43000000 0x800000>;
+		samsung,mfc-l = <0x51000000 0x800000>;
+	};
 };
diff --git a/arch/arm/boot/dts/exynos5250-snow.dts b/arch/arm/boot/dts/exynos5250-snow.dts
new file mode 100644
index 0000000..17dd951
--- /dev/null
+++ b/arch/arm/boot/dts/exynos5250-snow.dts
@@ -0,0 +1,43 @@
+/*
+ * Google Snow board device tree source
+ *
+ * Copyright (c) 2012 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.
+*/
+
+/dts-v1/;
+/include/ "exynos5250.dtsi"
+/include/ "cros5250-common.dtsi"
+
+/ {
+	model = "Google Snow";
+	compatible = "google,snow", "samsung,exynos5250";
+
+	gpio-keys {
+		compatible = "gpio-keys";
+
+		lid-switch {
+			label = "Lid";
+			gpios = <&gpx3 5 0 0x10000 0>;
+			linux,input-type = <5>; /* EV_SW */
+			linux,code = <0>; /* SW_LID */
+			debounce-interval = <1>;
+			gpio-key,wakeup;
+		};
+	};
+
+	/*
+	 * On Snow we've got SIP WiFi and so can keep drive strengths low to
+	 * reduce EMI.
+	 */
+	dwmmc3@12230000 {
+		slot@0 {
+			gpios = <&gpc4 0 2 0 0>, <&gpc4 1 2 3 0>,
+				<&gpc4 3 2 3 0>, <&gpc4 4 2 3 0>,
+				<&gpc4 5 2 3 0>, <&gpc4 6 2 3 0>;
+		};
+	};
+};
diff --git a/arch/arm/boot/dts/exynos5250.dtsi b/arch/arm/boot/dts/exynos5250.dtsi
index dddfd6e..36d8246 100644
--- a/arch/arm/boot/dts/exynos5250.dtsi
+++ b/arch/arm/boot/dts/exynos5250.dtsi
@@ -31,6 +31,10 @@
 		gsc1 = &gsc_1;
 		gsc2 = &gsc_2;
 		gsc3 = &gsc_3;
+		mshc0 = &dwmmc_0;
+		mshc1 = &dwmmc_1;
+		mshc2 = &dwmmc_2;
+		mshc3 = &dwmmc_3;
 	};
 
 	gic:interrupt-controller@10481000 {
@@ -62,12 +66,24 @@
 		interrupts = <0 42 0>;
 	};
 
+	codec@11000000 {
+		compatible = "samsung,mfc-v6";
+		reg = <0x11000000 0x10000>;
+		interrupts = <0 96 0>;
+	};
+
 	rtc {
 		compatible = "samsung,s3c6410-rtc";
 		reg = <0x101E0000 0x100>;
 		interrupts = <0 43 0>, <0 44 0>;
 	};
 
+	tmu@10060000 {
+		compatible = "samsung,exynos5250-tmu";
+		reg = <0x10060000 0x100>;
+		interrupts = <0 65 0>;
+	};
+
 	serial@12C00000 {
 		compatible = "samsung,exynos4210-uart";
 		reg = <0x12C00000 0x100>;
@@ -92,6 +108,17 @@
 		interrupts = <0 54 0>;
 	};
 
+	sata@122F0000 {
+		compatible = "samsung,exynos5-sata-ahci";
+		reg = <0x122F0000 0x1ff>;
+		interrupts = <0 115 0>;
+	};
+
+	sata-phy@12170000 {
+		compatible = "samsung,exynos5-sata-phy";
+		reg = <0x12170000 0x1ff>;
+	};
+
 	i2c@12C60000 {
 		compatible = "samsung,s3c2440-i2c";
 		reg = <0x12C60000 0x100>;
@@ -156,6 +183,21 @@
 		#size-cells = <0>;
 	};
 
+	i2c@12CE0000 {
+		compatible = "samsung,s3c2440-hdmiphy-i2c";
+		reg = <0x12CE0000 0x1000>;
+		interrupts = <0 64 0>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+	};
+
+	i2c@121D0000 {
+                compatible = "samsung,exynos5-sata-phy-i2c";
+                reg = <0x121D0000 0x100>;
+                #address-cells = <1>;
+                #size-cells = <0>;
+	};
+
 	spi_0: spi@12d20000 {
 		compatible = "samsung,exynos4210-spi";
 		reg = <0x12d20000 0x100>;
@@ -186,7 +228,7 @@
 		#size-cells = <0>;
 	};
 
-	dwmmc0@12200000 {
+	dwmmc_0: dwmmc0@12200000 {
 		compatible = "samsung,exynos5250-dw-mshc";
 		reg = <0x12200000 0x1000>;
 		interrupts = <0 75 0>;
@@ -194,7 +236,7 @@
 		#size-cells = <0>;
 	};
 
-	dwmmc1@12210000 {
+	dwmmc_1: dwmmc1@12210000 {
 		compatible = "samsung,exynos5250-dw-mshc";
 		reg = <0x12210000 0x1000>;
 		interrupts = <0 76 0>;
@@ -202,7 +244,7 @@
 		#size-cells = <0>;
 	};
 
-	dwmmc2@12220000 {
+	dwmmc_2: dwmmc2@12220000 {
 		compatible = "samsung,exynos5250-dw-mshc";
 		reg = <0x12220000 0x1000>;
 		interrupts = <0 77 0>;
@@ -210,7 +252,7 @@
 		#size-cells = <0>;
 	};
 
-	dwmmc3@12230000 {
+	dwmmc_3: dwmmc3@12230000 {
 		compatible = "samsung,exynos5250-dw-mshc";
 		reg = <0x12230000 0x1000>;
 		interrupts = <0 78 0>;
@@ -520,4 +562,16 @@
 		reg = <0x13e30000 0x1000>;
 		interrupts = <0 88 0>;
 	};
+
+	hdmi {
+		compatible = "samsung,exynos5-hdmi";
+		reg = <0x14530000 0x100000>;
+		interrupts = <0 95 0>;
+	};
+
+	mixer {
+		compatible = "samsung,exynos5-mixer";
+		reg = <0x14450000 0x10000>;
+		interrupts = <0 94 0>;
+	};
 };
diff --git a/arch/arm/boot/dts/href.dtsi b/arch/arm/boot/dts/href.dtsi
new file mode 100644
index 0000000..592fb9d
--- /dev/null
+++ b/arch/arm/boot/dts/href.dtsi
@@ -0,0 +1,273 @@
+/*
+ * Copyright 2012 ST-Ericsson AB
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/include/ "dbx5x0.dtsi"
+
+/ {
+	memory {
+		reg = <0x00000000 0x20000000>;
+	};
+
+	gpio_keys {
+		compatible = "gpio-keys";
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		button@1 {
+			linux,code = <11>;
+			label = "SFH7741 Proximity Sensor";
+		};
+	};
+
+	soc-u9500 {
+		uart@80120000 {
+			status = "okay";
+		};
+
+		uart@80121000 {
+			status = "okay";
+		};
+
+		uart@80007000 {
+			status = "okay";
+		};
+
+		i2c@80004000 {
+			tc3589x@42 {
+				compatible = "tc3589x";
+				reg = <0x42>;
+				interrupt-parent = <&gpio6>;
+				interrupts = <25 0x1>;
+
+				interrupt-controller;
+				#interrupt-cells = <2>;
+
+				tc3589x_gpio: tc3589x_gpio {
+					compatible = "tc3589x-gpio";
+					interrupts = <0 0x1>;
+
+					interrupt-controller;
+					#interrupt-cells = <2>;
+					gpio-controller;
+					#gpio-cells = <2>;
+				};
+			};
+		};
+
+		i2c@80128000 {
+			lp5521@0x33 {
+				compatible = "lp5521";
+				reg = <0x33>;
+			};
+
+			lp5521@0x34 {
+				compatible = "lp5521";
+				reg = <0x34>;
+			};
+
+			bh1780@0x29 {
+				compatible = "rohm,bh1780gli";
+				reg = <0x33>;
+			};
+		};
+
+		// External Micro SD slot
+		sdi0_per1@80126000 {
+			arm,primecell-periphid = <0x10480180>;
+			max-frequency = <50000000>;
+			bus-width = <4>;
+			mmc-cap-sd-highspeed;
+			mmc-cap-mmc-highspeed;
+			vmmc-supply = <&ab8500_ldo_aux3_reg>;
+
+			cd-gpios  = <&tc3589x_gpio 3 0x4>;
+
+			status = "okay";
+		};
+
+		// WLAN SDIO channel
+		sdi1_per2@80118000 {
+			arm,primecell-periphid = <0x10480180>;
+			max-frequency = <50000000>;
+			bus-width = <4>;
+
+			status = "okay";
+		};
+
+		// PoP:ed eMMC
+		sdi2_per3@80005000 {
+			arm,primecell-periphid = <0x10480180>;
+			max-frequency = <50000000>;
+			bus-width = <8>;
+			mmc-cap-mmc-highspeed;
+
+			status = "okay";
+		};
+
+		// On-board eMMC
+		sdi4_per2@80114000 {
+			arm,primecell-periphid = <0x10480180>;
+		        max-frequency = <50000000>;
+			bus-width = <8>;
+			mmc-cap-mmc-highspeed;
+			vmmc-supply = <&ab8500_ldo_aux2_reg>;
+
+			status = "okay";
+		};
+
+		sound {
+			compatible = "stericsson,snd-soc-mop500";
+
+			stericsson,cpu-dai = <&msp1 &msp3>;
+			stericsson,audio-codec = <&codec>;
+		};
+
+		msp1: msp@80124000 {
+			status = "okay";
+		};
+
+		msp3: msp@80125000 {
+			status = "okay";
+		};
+
+		prcmu@80157000 {
+			db8500-prcmu-regulators {
+				db8500_vape_reg: db8500_vape {
+					regulator-name = "db8500-vape";
+				};
+
+				db8500_varm_reg: db8500_varm {
+					regulator-name = "db8500-varm";
+				};
+
+				db8500_vmodem_reg: db8500_vmodem {
+					regulator-name = "db8500-vmodem";
+				};
+
+				db8500_vpll_reg: db8500_vpll {
+					regulator-name = "db8500-vpll";
+				};
+
+				db8500_vsmps1_reg: db8500_vsmps1 {
+					regulator-name = "db8500-vsmps1";
+				};
+
+				db8500_vsmps2_reg: db8500_vsmps2 {
+					regulator-name = "db8500-vsmps2";
+				};
+
+				db8500_vsmps3_reg: db8500_vsmps3 {
+					regulator-name = "db8500-vsmps3";
+				};
+
+				db8500_vrf1_reg: db8500_vrf1 {
+					regulator-name = "db8500-vrf1";
+				};
+
+				db8500_sva_mmdsp_reg: db8500_sva_mmdsp {
+					regulator-name = "db8500-sva-mmdsp";
+				};
+
+				db8500_sva_mmdsp_ret_reg: db8500_sva_mmdsp_ret {
+					regulator-name = "db8500-sva-mmdsp-ret";
+				};
+
+				db8500_sva_pipe_reg: db8500_sva_pipe {
+					regulator-name = "db8500_sva_pipe";
+				};
+
+				db8500_sia_mmdsp_reg: db8500_sia_mmdsp {
+					regulator-name = "db8500_sia_mmdsp";
+				};
+
+				db8500_sia_mmdsp_ret_reg: db8500_sia_mmdsp_ret {
+					regulator-name = "db8500-sia-mmdsp-ret";
+				};
+
+				db8500_sia_pipe_reg: db8500_sia_pipe {
+					regulator-name = "db8500-sia-pipe";
+				};
+
+				db8500_sga_reg: db8500_sga {
+					regulator-name = "db8500-sga";
+				};
+
+				db8500_b2r2_mcde_reg: db8500_b2r2_mcde {
+					regulator-name = "db8500-b2r2-mcde";
+				};
+
+				db8500_esram12_reg: db8500_esram12 {
+					regulator-name = "db8500-esram12";
+				};
+
+				db8500_esram12_ret_reg: db8500_esram12_ret {
+					regulator-name = "db8500-esram12-ret";
+				};
+
+				db8500_esram34_reg: db8500_esram34 {
+					regulator-name = "db8500-esram34";
+				};
+
+				db8500_esram34_ret_reg: db8500_esram34_ret {
+					regulator-name = "db8500-esram34-ret";
+				};
+			};
+
+			ab8500@5 {
+				ab8500-regulators {
+					ab8500_ldo_aux1_reg: ab8500_ldo_aux1 {
+						regulator-name = "V-DISPLAY";
+					};
+
+					ab8500_ldo_aux2_reg: ab8500_ldo_aux2 {
+						regulator-name = "V-eMMC1";
+					};
+
+					ab8500_ldo_aux3_reg: ab8500_ldo_aux3 {
+						regulator-name = "V-MMC-SD";
+					};
+
+					ab8500_ldo_initcore_reg: ab8500_ldo_initcore {
+						regulator-name = "V-INTCORE";
+					};
+
+					ab8500_ldo_tvout_reg: ab8500_ldo_tvout {
+						regulator-name = "V-TVOUT";
+					};
+
+					ab8500_ldo_usb_reg: ab8500_ldo_usb {
+						regulator-name = "dummy";
+					};
+
+					ab8500_ldo_audio_reg: ab8500_ldo_audio {
+						regulator-name = "V-AUD";
+					};
+
+					ab8500_ldo_anamic1_reg: ab8500_ldo_anamic1 {
+						regulator-name = "V-AMIC1";
+					};
+
+					ab8500_ldo_amamic2_reg: ab8500_ldo_amamic2 {
+						regulator-name = "V-AMIC2";
+					};
+
+					ab8500_ldo_dmic_reg: ab8500_ldo_dmic {
+						regulator-name = "V-DMIC";
+					};
+
+					ab8500_ldo_ana_reg: ab8500_ldo_ana {
+						regulator-name = "V-CSI/DSI";
+					};
+				};
+			};
+		};
+	};
+};
diff --git a/arch/arm/boot/dts/hrefprev60.dts b/arch/arm/boot/dts/hrefprev60.dts
new file mode 100644
index 0000000..eec29c4
--- /dev/null
+++ b/arch/arm/boot/dts/hrefprev60.dts
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2012 ST-Ericsson AB
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/dts-v1/;
+/include/ "dbx5x0.dtsi"
+/include/ "href.dtsi"
+/include/ "stuib.dtsi"
+
+/ {
+	model = "ST-Ericsson HREF (pre-v60) platform with Device Tree";
+	compatible = "st-ericsson,mop500", "st-ericsson,u8500";
+
+	gpio_keys {
+		button@1 {
+			gpios = <&tc3589x_gpio 7 0x4>;
+		};
+	};
+
+	soc-u9500 {
+		i2c@80004000 {
+			tps61052@33 {
+				compatible = "tps61052";
+				reg = <0x33>;
+			};
+		};
+
+		i2c@80110000 {
+			bu21013_tp@0x5c {
+				reset-gpio = <&tc3589x_gpio 13 0x4>;
+			};
+		};
+
+		vmmci: regulator-gpio {
+			gpios = <&tc3589x_gpio 18 0x4>;
+			gpio-enable = <&tc3589x_gpio 17 0x4>;
+
+			status = "okay";
+		};
+	};
+};
diff --git a/arch/arm/boot/dts/hrefv60plus.dts b/arch/arm/boot/dts/hrefv60plus.dts
index 2131d77..55f4191 100644
--- a/arch/arm/boot/dts/hrefv60plus.dts
+++ b/arch/arm/boot/dts/hrefv60plus.dts
@@ -11,85 +11,200 @@
 
 /dts-v1/;
 /include/ "dbx5x0.dtsi"
+/include/ "href.dtsi"
+/include/ "stuib.dtsi"
 
 / {
-	model = "ST-Ericsson HREF platform with Device Tree";
-	compatible = "st-ericsson,hrefv60+";
+	model = "ST-Ericsson HREF (v60+) platform with Device Tree";
+	compatible = "st-ericsson,hrefv60+", "st-ericsson,u8500";
 
-	memory {
-		reg = <0x00000000 0x20000000>;
+	gpio_keys {
+		button@1 {
+			gpios = <&gpio6 25 0x4>;
+		};
 	};
 
 	soc-u9500 {
-		uart@80120000 {
+		i2c@80110000 {
+			bu21013_tp@0x5c {
+				reset-gpio = <&gpio4 15 0x4>;
+			};
+		};
+
+		// External Micro SD slot
+		sdi0_per1@80126000 {
+			arm,primecell-periphid = <0x10480180>;
+			max-frequency = <50000000>;
+			bus-width = <4>;
+			mmc-cap-sd-highspeed;
+			mmc-cap-mmc-highspeed;
+			vmmc-supply = <&ab8500_ldo_aux3_reg>;
+
+			cd-gpios  = <&tc3589x_gpio 3 0x4>;
+
 			status = "okay";
 		};
 
-		uart@80121000 {
+		// WLAN SDIO channel
+		sdi1_per2@80118000 {
+			arm,primecell-periphid = <0x10480180>;
+			max-frequency = <50000000>;
+			bus-width = <4>;
+
 			status = "okay";
 		};
 
-		uart@80007000 {
+		// PoP:ed eMMC
+		sdi2_per3@80005000 {
+			arm,primecell-periphid = <0x10480180>;
+			max-frequency = <50000000>;
+			bus-width = <8>;
+			mmc-cap-mmc-highspeed;
+
 			status = "okay";
 		};
 
-		i2c@80004000 {
-			tc3589x@42 {
-				compatible = "tc3589x";
-				reg = <0x42>;
-				interrupt-parent = <&gpio6>;
-				interrupts = <25 0x1>;
+		// On-board eMMC
+		sdi4_per2@80114000 {
+			arm,primecell-periphid = <0x10480180>;
+		        max-frequency = <50000000>;
+			bus-width = <8>;
+			mmc-cap-mmc-highspeed;
+			vmmc-supply = <&ab8500_ldo_aux2_reg>;
 
-				interrupt-controller;
-				#interrupt-cells = <2>;
+			status = "okay";
+		};
 
-				tc3589x_gpio: tc3589x_gpio {
-					compatible = "tc3589x-gpio";
-					interrupts = <0 0x1>;
+		prcmu@80157000 {
+			db8500-prcmu-regulators {
+				db8500_vape_reg: db8500_vape {
+					regulator-name = "db8500-vape";
+				};
 
-					interrupt-controller;
-					#interrupt-cells = <2>;
-					gpio-controller;
-					#gpio-cells = <2>;
+				db8500_varm_reg: db8500_varm {
+					regulator-name = "db8500-varm";
+				};
+
+				db8500_vmodem_reg: db8500_vmodem {
+					regulator-name = "db8500-vmodem";
+				};
+
+				db8500_vpll_reg: db8500_vpll {
+					regulator-name = "db8500-vpll";
+				};
+
+				db8500_vsmps1_reg: db8500_vsmps1 {
+					regulator-name = "db8500-vsmps1";
+				};
+
+				db8500_vsmps2_reg: db8500_vsmps2 {
+					regulator-name = "db8500-vsmps2";
+				};
+
+				db8500_vsmps3_reg: db8500_vsmps3 {
+					regulator-name = "db8500-vsmps3";
+				};
+
+				db8500_vrf1_reg: db8500_vrf1 {
+					regulator-name = "db8500-vrf1";
+				};
+
+				db8500_sva_mmdsp_reg: db8500_sva_mmdsp {
+					regulator-name = "db8500-sva-mmdsp";
+				};
+
+				db8500_sva_mmdsp_ret_reg: db8500_sva_mmdsp_ret {
+					regulator-name = "db8500-sva-mmdsp-ret";
+				};
+
+				db8500_sva_pipe_reg: db8500_sva_pipe {
+					regulator-name = "db8500_sva_pipe";
+				};
+
+				db8500_sia_mmdsp_reg: db8500_sia_mmdsp {
+					regulator-name = "db8500_sia_mmdsp";
+				};
+
+				db8500_sia_mmdsp_ret_reg: db8500_sia_mmdsp_ret {
+					regulator-name = "db8500-sia-mmdsp-ret";
+				};
+
+				db8500_sia_pipe_reg: db8500_sia_pipe {
+					regulator-name = "db8500-sia-pipe";
+				};
+
+				db8500_sga_reg: db8500_sga {
+					regulator-name = "db8500-sga";
+				};
+
+				db8500_b2r2_mcde_reg: db8500_b2r2_mcde {
+					regulator-name = "db8500-b2r2-mcde";
+				};
+
+				db8500_esram12_reg: db8500_esram12 {
+					regulator-name = "db8500-esram12";
+				};
+
+				db8500_esram12_ret_reg: db8500_esram12_ret {
+					regulator-name = "db8500-esram12-ret";
+				};
+
+				db8500_esram34_reg: db8500_esram34 {
+					regulator-name = "db8500-esram34";
+				};
+
+				db8500_esram34_ret_reg: db8500_esram34_ret {
+					regulator-name = "db8500-esram34-ret";
 				};
 			};
 
-			tps61052@33 {
-				compatible = "tps61052";
-				reg = <0x33>;
+			ab8500@5 {
+				ab8500-regulators {
+					ab8500_ldo_aux1_reg: ab8500_ldo_aux1 {
+						regulator-name = "V-DISPLAY";
+					};
+
+					ab8500_ldo_aux2_reg: ab8500_ldo_aux2 {
+						regulator-name = "V-eMMC1";
+					};
+
+					ab8500_ldo_aux3_reg: ab8500_ldo_aux3 {
+						regulator-name = "V-MMC-SD";
+					};
+
+					ab8500_ldo_initcore_reg: ab8500_ldo_initcore {
+						regulator-name = "V-INTCORE";
+					};
+
+					ab8500_ldo_tvout_reg: ab8500_ldo_tvout {
+						regulator-name = "V-TVOUT";
+					};
+
+					ab8500_ldo_usb_reg: ab8500_ldo_usb {
+						regulator-name = "dummy";
+					};
+
+					ab8500_ldo_audio_reg: ab8500_ldo_audio {
+						regulator-name = "V-AUD";
+					};
+
+					ab8500_ldo_anamic1_reg: ab8500_ldo_anamic1 {
+						regulator-name = "V-AMIC1";
+					};
+
+					ab8500_ldo_amamic2_reg: ab8500_ldo_amamic2 {
+						regulator-name = "V-AMIC2";
+					};
+
+					ab8500_ldo_dmic_reg: ab8500_ldo_dmic {
+						regulator-name = "V-DMIC";
+					};
+
+					ab8500_ldo_ana_reg: ab8500_ldo_ana {
+						regulator-name = "V-CSI/DSI";
+					};
+				};
 			};
 		};
-
-		i2c@80128000 {
-			lp5521@0x33 {
-				compatible = "lp5521";
-				reg = <0x33>;
-			};
-
-			lp5521@0x34 {
-				compatible = "lp5521";
-				reg = <0x34>;
-			};
-
-			bh1780@0x29 {
-				compatible = "rohm,bh1780gli";
-				reg = <0x33>;
-			};
-		};
-
-		sound {
-			compatible = "stericsson,snd-soc-mop500";
-
-			stericsson,cpu-dai = <&msp1 &msp3>;
-			stericsson,audio-codec = <&codec>;
-		};
-
-		msp1: msp@80124000 {
-			status = "okay";
-		};
-
-		msp3: msp@80125000 {
-			status = "okay";
-		};
 	};
 };
diff --git a/arch/arm/boot/dts/imx23-olinuxino.dts b/arch/arm/boot/dts/imx23-olinuxino.dts
index 384d8b6..7c43b8e 100644
--- a/arch/arm/boot/dts/imx23-olinuxino.dts
+++ b/arch/arm/boot/dts/imx23-olinuxino.dts
@@ -40,6 +40,15 @@
 					reg = <0>;
 					fsl,pinmux-ids = <
 						0x2013 /* MX23_PAD_SSP1_DETECT__GPIO_2_1 */
+					>;
+					fsl,drive-strength = <0>;
+					fsl,voltage = <1>;
+					fsl,pull-up = <0>;
+				};
+
+				led_pin_gpio0_17: led_gpio0_17@0 {
+					reg = <0>;
+					fsl,pinmux-ids = <
 						0x0113 /* MX23_PAD_GPMI_ALE__GPIO_0_17 */
 					>;
 					fsl,drive-strength = <0>;
@@ -47,6 +56,15 @@
 					fsl,pull-up = <0>;
 				};
 			};
+
+			ssp1: ssp@80034000 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,imx23-spi";
+				pinctrl-names = "default";
+				pinctrl-0 = <&spi2_pins_a>;
+				status = "okay";
+			};
 		};
 
 		apbx@80040000 {
@@ -91,11 +109,12 @@
 
 	leds {
 		compatible = "gpio-leds";
+		pinctrl-names = "default";
+		pinctrl-0 = <&led_pin_gpio0_17>;
 
 		user {
 			label = "green";
-			gpios = <&gpio2 1 0>;
-			linux,default-trigger = "default-on";
+			gpios = <&gpio2 1 1>;
 		};
 	};
 };
diff --git a/arch/arm/boot/dts/imx23.dtsi b/arch/arm/boot/dts/imx23.dtsi
index 6d31aa3..65415c5 100644
--- a/arch/arm/boot/dts/imx23.dtsi
+++ b/arch/arm/boot/dts/imx23.dtsi
@@ -279,6 +279,19 @@
 					fsl,voltage = <1>;
 					fsl,pull-up = <0>;
 				};
+
+				spi2_pins_a: spi2@0 {
+					reg = <0>;
+					fsl,pinmux-ids = <
+						0x0182 /* MX23_PAD_GPMI_WRN__SSP2_SCK */
+						0x0142 /* MX23_PAD_GPMI_RDY1__SSP2_CMD */
+						0x0002 /* MX23_PAD_GPMI_D00__SSP2_DATA0 */
+						0x0032 /* MX23_PAD_GPMI_D03__SSP2_DATA3 */
+					>;
+					fsl,drive-strength = <1>;
+					fsl,voltage = <1>;
+					fsl,pull-up = <1>;
+				};
 			};
 
 			digctl@8001c000 {
diff --git a/arch/arm/boot/dts/imx25-karo-tx25.dts b/arch/arm/boot/dts/imx25-karo-tx25.dts
new file mode 100644
index 0000000..d81f8a0
--- /dev/null
+++ b/arch/arm/boot/dts/imx25-karo-tx25.dts
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2012 Sascha Hauer, Pengutronix
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/dts-v1/;
+/include/ "imx25.dtsi"
+
+/ {
+	model = "Ka-Ro TX25";
+	compatible = "karo,imx25-tx25", "fsl,imx25";
+
+	memory {
+		reg = <0x80000000 0x02000000 0x90000000 0x02000000>;
+	};
+
+	soc {
+		aips@43f00000 {
+			uart1: serial@43f90000 {
+				status = "okay";
+			};
+		};
+
+		spba@50000000 {
+			fec: ethernet@50038000 {
+				status = "okay";
+				phy-mode = "rmii";
+			};
+		};
+
+		emi@80000000 {
+			nand@bb000000 {
+				nand-on-flash-bbt;
+				status = "okay";
+			};
+		};
+	};
+};
diff --git a/arch/arm/boot/dts/imx25.dtsi b/arch/arm/boot/dts/imx25.dtsi
new file mode 100644
index 0000000..e1b13eb
--- /dev/null
+++ b/arch/arm/boot/dts/imx25.dtsi
@@ -0,0 +1,515 @@
+/*
+ * Copyright 2012 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de>
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/include/ "skeleton.dtsi"
+
+/ {
+	aliases {
+		serial0 = &uart1;
+		serial1 = &uart2;
+		serial2 = &uart3;
+		serial3 = &uart4;
+		serial4 = &uart5;
+		gpio0 = &gpio1;
+		gpio1 = &gpio2;
+		gpio2 = &gpio3;
+		gpio3 = &gpio4;
+		usb0 = &usbotg;
+		usb1 = &usbhost1;
+	};
+
+	asic: asic-interrupt-controller@68000000 {
+		compatible = "fsl,imx25-asic", "fsl,avic";
+		interrupt-controller;
+		#interrupt-cells = <1>;
+		reg = <0x68000000 0x8000000>;
+	};
+
+	clocks {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		osc {
+			compatible = "fsl,imx-osc", "fixed-clock";
+			clock-frequency = <24000000>;
+		};
+	};
+
+	soc {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "simple-bus";
+		interrupt-parent = <&asic>;
+		ranges;
+
+		aips@43f00000 { /* AIPS1 */
+			compatible = "fsl,aips-bus", "simple-bus";
+			#address-cells = <1>;
+			#size-cells = <1>;
+			reg = <0x43f00000 0x100000>;
+			ranges;
+
+			i2c1: i2c@43f80000 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,imx25-i2c", "fsl,imx21-i2c";
+				reg = <0x43f80000 0x4000>;
+				clocks = <&clks 48>;
+				clock-names = "";
+				interrupts = <3>;
+				status = "disabled";
+			};
+
+			i2c3: i2c@43f84000 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,imx25-i2c", "fsl,imx21-i2c";
+				reg = <0x43f84000 0x4000>;
+				clocks = <&clks 48>;
+				clock-names = "";
+				interrupts = <10>;
+				status = "disabled";
+			};
+
+			can1: can@43f88000 {
+				compatible = "fsl,imx25-flexcan", "fsl,p1010-flexcan";
+				reg = <0x43f88000 0x4000>;
+				interrupts = <43>;
+				clocks = <&clks 75>, <&clks 75>;
+				clock-names = "ipg", "per";
+				status = "disabled";
+			};
+
+			can2: can@43f8c000 {
+				compatible = "fsl,imx25-flexcan", "fsl,p1010-flexcan";
+				reg = <0x43f8c000 0x4000>;
+				interrupts = <44>;
+				clocks = <&clks 76>, <&clks 76>;
+				clock-names = "ipg", "per";
+				status = "disabled";
+			};
+
+			uart1: serial@43f90000 {
+				compatible = "fsl,imx25-uart", "fsl,imx21-uart";
+				reg = <0x43f90000 0x4000>;
+				interrupts = <45>;
+				clocks = <&clks 120>, <&clks 57>;
+				clock-names = "ipg", "per";
+				status = "disabled";
+			};
+
+			uart2: serial@43f94000 {
+				compatible = "fsl,imx25-uart", "fsl,imx21-uart";
+				reg = <0x43f94000 0x4000>;
+				interrupts = <32>;
+				clocks = <&clks 121>, <&clks 57>;
+				clock-names = "ipg", "per";
+				status = "disabled";
+			};
+
+			i2c2: i2c@43f98000 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,imx25-i2c", "fsl,imx21-i2c";
+				reg = <0x43f98000 0x4000>;
+				clocks = <&clks 48>;
+				clock-names = "";
+				interrupts = <4>;
+				status = "disabled";
+			};
+
+			owire@43f9c000 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				reg = <0x43f9c000 0x4000>;
+				clocks = <&clks 51>;
+				clock-names = "";
+				interrupts = <2>;
+				status = "disabled";
+			};
+
+			spi1: cspi@43fa4000 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,imx25-cspi", "fsl,imx35-cspi";
+				reg = <0x43fa4000 0x4000>;
+				clocks = <&clks 62>;
+				clock-names = "ipg";
+				interrupts = <14>;
+				status = "disabled";
+			};
+
+			kpp@43fa8000 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				reg = <0x43fa8000 0x4000>;
+				clocks = <&clks 102>;
+				clock-names = "";
+				interrupts = <24>;
+				status = "disabled";
+			};
+
+			iomuxc@43fac000{
+				compatible = "fsl,imx25-iomuxc";
+				reg = <0x43fac000 0x4000>;
+			};
+
+			audmux@43fb0000 {
+				compatible = "fsl,imx25-audmux", "fsl,imx31-audmux";
+				reg = <0x43fb0000 0x4000>;
+				status = "disabled";
+			};
+		};
+
+		spba@50000000 {
+			compatible = "fsl,spba-bus", "simple-bus";
+			#address-cells = <1>;
+			#size-cells = <1>;
+			reg = <0x50000000 0x40000>;
+			ranges;
+
+			spi3: cspi@50004000 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,imx25-cspi", "fsl,imx35-cspi";
+				reg = <0x50004000 0x4000>;
+				interrupts = <0>;
+				clocks = <&clks 80>;
+				clock-names = "ipg";
+				status = "disabled";
+			};
+
+			uart4: serial@50008000 {
+				compatible = "fsl,imx25-uart", "fsl,imx21-uart";
+				reg = <0x50008000 0x4000>;
+				interrupts = <5>;
+				clocks = <&clks 123>, <&clks 57>;
+				clock-names = "ipg", "per";
+				status = "disabled";
+			};
+
+			uart3: serial@5000c000 {
+				compatible = "fsl,imx25-uart", "fsl,imx21-uart";
+				reg = <0x5000c000 0x4000>;
+				interrupts = <18>;
+				clocks = <&clks 122>, <&clks 57>;
+				clock-names = "ipg", "per";
+				status = "disabled";
+			};
+
+			spi2: cspi@50010000 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,imx25-cspi", "fsl,imx35-cspi";
+				reg = <0x50010000 0x4000>;
+				clocks = <&clks 79>;
+				clock-names = "ipg";
+				interrupts = <13>;
+				status = "disabled";
+			};
+
+			ssi2: ssi@50014000 {
+				compatible = "fsl,imx25-ssi", "fsl,imx21-ssi";
+				reg = <0x50014000 0x4000>;
+				interrupts = <11>;
+				status = "disabled";
+			};
+
+			esai@50018000 {
+				reg = <0x50018000 0x4000>;
+				interrupts = <7>;
+			};
+
+			uart5: serial@5002c000 {
+				compatible = "fsl,imx25-uart", "fsl,imx21-uart";
+				reg = <0x5002c000 0x4000>;
+				interrupts = <40>;
+				clocks = <&clks 124>, <&clks 57>;
+				clock-names = "ipg", "per";
+				status = "disabled";
+			};
+
+			tsc: tsc@50030000 {
+				compatible = "fsl,imx25-adc", "fsl,imx21-tsc";
+				reg = <0x50030000 0x4000>;
+				interrupts = <46>;
+				clocks = <&clks 119>;
+				clock-names = "ipg";
+				status = "disabled";
+			};
+
+			ssi1: ssi@50034000 {
+				compatible = "fsl,imx25-ssi", "fsl,imx21-ssi";
+				reg = <0x50034000 0x4000>;
+				interrupts = <12>;
+				status = "disabled";
+			};
+
+			fec: ethernet@50038000 {
+				compatible = "fsl,imx25-fec";
+				reg = <0x50038000 0x4000>;
+				interrupts = <57>;
+				clocks = <&clks 88>, <&clks 65>;
+				clock-names = "ipg", "ahb";
+				status = "disabled";
+			};
+		};
+
+		aips@53f00000 { /* AIPS2 */
+			compatible = "fsl,aips-bus", "simple-bus";
+			#address-cells = <1>;
+			#size-cells = <1>;
+			reg = <0x53f00000 0x100000>;
+			ranges;
+
+			clks: ccm@53f80000 {
+				compatible = "fsl,imx25-ccm";
+				reg = <0x53f80000 0x4000>;
+				interrupts = <31>;
+				#clock-cells = <1>;
+			};
+
+			gpt4: timer@53f84000 {
+				compatible = "fsl,imx25-gpt", "fsl,imx31-gpt";
+				reg = <0x53f84000 0x4000>;
+				clocks = <&clks 9>, <&clks 45>;
+				clock-names = "ipg", "per";
+				interrupts = <1>;
+			};
+
+			gpt3: timer@53f88000 {
+				compatible = "fsl,imx25-gpt", "fsl,imx31-gpt";
+				reg = <0x53f88000 0x4000>;
+				clocks = <&clks 9>, <&clks 47>;
+				clock-names = "ipg", "per";
+				interrupts = <29>;
+			};
+
+			gpt2: timer@53f8c000 {
+				compatible = "fsl,imx25-gpt", "fsl,imx31-gpt";
+				reg = <0x53f8c000 0x4000>;
+				clocks = <&clks 9>, <&clks 47>;
+				clock-names = "ipg", "per";
+				interrupts = <53>;
+			};
+
+			gpt1: timer@53f90000 {
+				compatible = "fsl,imx25-gpt", "fsl,imx31-gpt";
+				reg = <0x53f90000 0x4000>;
+				clocks = <&clks 9>, <&clks 47>;
+				clock-names = "ipg", "per";
+				interrupts = <54>;
+			};
+
+			epit1: timer@53f94000 {
+				compatible = "fsl,imx25-epit";
+				reg = <0x53f94000 0x4000>;
+				interrupts = <28>;
+			};
+
+			epit2: timer@53f98000 {
+				compatible = "fsl,imx25-epit";
+				reg = <0x53f98000 0x4000>;
+				interrupts = <27>;
+			};
+
+			gpio4: gpio@53f9c000 {
+				compatible = "fsl,imx25-gpio", "fsl,imx35-gpio";
+				reg = <0x53f9c000 0x4000>;
+				interrupts = <23>;
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-controller;
+				#interrupt-cells = <2>;
+			};
+
+			pwm2: pwm@53fa0000 {
+				compatible = "fsl,imx25-pwm", "fsl,imx27-pwm";
+				#pwm-cells = <2>;
+				reg = <0x53fa0000 0x4000>;
+				clocks = <&clks 106>, <&clks 36>;
+				clock-names = "ipg", "per";
+				interrupts = <36>;
+			};
+
+			gpio3: gpio@53fa4000 {
+				compatible = "fsl,imx25-gpio", "fsl,imx35-gpio";
+				reg = <0x53fa4000 0x4000>;
+				interrupts = <16>;
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-controller;
+				#interrupt-cells = <2>;
+			};
+
+			pwm3: pwm@53fa8000 {
+				compatible = "fsl,imx25-pwm", "fsl,imx27-pwm";
+				#pwm-cells = <2>;
+				reg = <0x53fa8000 0x4000>;
+				clocks = <&clks 107>, <&clks 36>;
+				clock-names = "ipg", "per";
+				interrupts = <41>;
+			};
+
+			esdhc1: esdhc@53fb4000 {
+				compatible = "fsl,imx25-esdhc";
+				reg = <0x53fb4000 0x4000>;
+				interrupts = <9>;
+				clocks = <&clks 86>, <&clks 63>, <&clks 45>;
+				clock-names = "ipg", "ahb", "per";
+				status = "disabled";
+			};
+
+			esdhc2: esdhc@53fb8000 {
+				compatible = "fsl,imx25-esdhc";
+				reg = <0x53fb8000 0x4000>;
+				interrupts = <8>;
+				clocks = <&clks 87>, <&clks 64>, <&clks 46>;
+				clock-names = "ipg", "ahb", "per";
+				status = "disabled";
+			};
+
+			lcdc@53fbc000 {
+				reg = <0x53fbc000 0x4000>;
+				interrupts = <39>;
+				clocks = <&clks 103>, <&clks 66>, <&clks 49>;
+				clock-names = "ipg", "ahb", "per";
+				status = "disabled";
+			};
+
+			slcdc@53fc0000 {
+				reg = <0x53fc0000 0x4000>;
+				interrupts = <38>;
+				status = "disabled";
+			};
+
+			pwm4: pwm@53fc8000 {
+				compatible = "fsl,imx25-pwm", "fsl,imx27-pwm";
+				reg = <0x53fc8000 0x4000>;
+				clocks = <&clks 108>, <&clks 36>;
+				clock-names = "ipg", "per";
+				interrupts = <42>;
+			};
+
+			gpio1: gpio@53fcc000 {
+				compatible = "fsl,imx25-gpio", "fsl,imx35-gpio";
+				reg = <0x53fcc000 0x4000>;
+				interrupts = <52>;
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-controller;
+				#interrupt-cells = <2>;
+			};
+
+			gpio2: gpio@53fd0000 {
+				compatible = "fsl,imx25-gpio", "fsl,imx35-gpio";
+				reg = <0x53fd0000 0x4000>;
+				interrupts = <51>;
+				gpio-controller;
+				#gpio-cells = <2>;
+				interrupt-controller;
+				#interrupt-cells = <2>;
+			};
+
+			sdma@53fd4000 {
+				compatible = "fsl,imx25-sdma", "fsl,imx35-sdma";
+				reg = <0x53fd4000 0x4000>;
+				clocks = <&clks 112>, <&clks 68>;
+				clock-names = "ipg", "ahb";
+				interrupts = <34>;
+			};
+
+			wdog@53fdc000 {
+				compatible = "fsl,imx25-wdt", "fsl,imx21-wdt";
+				reg = <0x53fdc000 0x4000>;
+				clocks = <&clks 126>;
+				clock-names = "";
+				interrupts = <55>;
+			};
+
+			pwm1: pwm@53fe0000 {
+				compatible = "fsl,imx25-pwm", "fsl,imx27-pwm";
+				#pwm-cells = <2>;
+				reg = <0x53fe0000 0x4000>;
+				clocks = <&clks 105>, <&clks 36>;
+				clock-names = "ipg", "per";
+				interrupts = <26>;
+			};
+
+			usbphy1: usbphy@1 {
+				compatible = "nop-usbphy";
+				status = "disabled";
+			};
+
+			usbphy2: usbphy@2 {
+				compatible = "nop-usbphy";
+				status = "disabled";
+			};
+
+			usbotg: usb@53ff4000 {
+				compatible = "fsl,imx25-usb", "fsl,imx27-usb";
+				reg = <0x53ff4000 0x0200>;
+				interrupts = <37>;
+				clocks = <&clks 9>, <&clks 70>, <&clks 8>;
+				clock-names = "ipg", "ahb", "per";
+				fsl,usbmisc = <&usbmisc 0>;
+				status = "disabled";
+			};
+
+			usbhost1: usb@53ff4400 {
+				compatible = "fsl,imx25-usb", "fsl,imx27-usb";
+				reg = <0x53ff4400 0x0200>;
+				interrupts = <35>;
+				clocks = <&clks 9>, <&clks 70>, <&clks 8>;
+				clock-names = "ipg", "ahb", "per";
+				fsl,usbmisc = <&usbmisc 1>;
+				status = "disabled";
+			};
+
+			usbmisc: usbmisc@53ff4600 {
+				#index-cells = <1>;
+				compatible = "fsl,imx25-usbmisc";
+				clocks = <&clks 9>, <&clks 70>, <&clks 8>;
+				clock-names = "ipg", "ahb", "per";
+				reg = <0x53ff4600 0x00f>;
+				status = "disabled";
+			};
+
+			dryice@53ffc000 {
+				compatible = "fsl,imx25-dryice", "fsl,imx25-rtc";
+				reg = <0x53ffc000 0x4000>;
+				clocks = <&clks 81>;
+				clock-names = "ipg";
+				interrupts = <25>;
+			};
+		};
+
+		emi@80000000 {
+			compatible = "fsl,emi-bus", "simple-bus";
+			#address-cells = <1>;
+			#size-cells = <1>;
+			reg = <0x80000000 0x3b002000>;
+			ranges;
+
+			nand@bb000000 {
+				#address-cells = <1>;
+				#size-cells = <1>;
+
+				compatible = "fsl,imx25-nand";
+				reg = <0xbb000000 0x2000>;
+				clocks = <&clks 50>;
+				clock-names = "";
+				interrupts = <33>;
+				status = "disabled";
+			};
+		};
+	};
+};
diff --git a/arch/arm/boot/dts/imx27-apf27.dts b/arch/arm/boot/dts/imx27-apf27.dts
new file mode 100644
index 0000000..c0327c0
--- /dev/null
+++ b/arch/arm/boot/dts/imx27-apf27.dts
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2012 Philippe Reynes <tremyfr@yahoo.fr>
+ * Copyright 2012 Armadeus Systems <support@armadeus.com>
+ *
+ * Based on code which is: Copyright 2012 Sascha Hauer, Pengutronix
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/dts-v1/;
+/include/ "imx27.dtsi"
+
+/ {
+	model = "Armadeus Systems APF27 module";
+	compatible = "armadeus,imx27-apf27", "fsl,imx27";
+
+	memory {
+		reg = <0xa0000000 0x04000000>;
+	};
+
+	clocks {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		osc26m {
+			compatible = "fsl,imx-osc26m", "fixed-clock";
+			clock-frequency = <0>;
+		};
+	};
+
+	soc {
+		aipi@10000000 {
+			serial@1000a000 {
+				status = "okay";
+			};
+
+			ethernet@1002b000 {
+				status = "okay";
+			};
+		};
+
+		nand@d8000000 {
+			status = "okay";
+			nand-bus-width = <16>;
+			nand-ecc-mode = "hw";
+			nand-on-flash-bbt;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x100000>;
+			};
+
+			partition@100000 {
+				label = "env";
+				reg = <0x100000 0x80000>;
+			};
+
+			partition@180000 {
+				label = "env2";
+				reg = <0x180000 0x80000>;
+			};
+
+			partition@200000 {
+				label = "firmware";
+				reg = <0x200000 0x80000>;
+			};
+
+			partition@280000 {
+				label = "dtb";
+				reg = <0x280000 0x80000>;
+			};
+
+			partition@300000 {
+				label = "kernel";
+				reg = <0x300000 0x500000>;
+			};
+
+			partition@800000 {
+				label = "rootfs";
+				reg = <0x800000 0xf800000>;
+			};
+		};
+	};
+};
diff --git a/arch/arm/boot/dts/imx27.dtsi b/arch/arm/boot/dts/imx27.dtsi
index 67d6727..b8d3905 100644
--- a/arch/arm/boot/dts/imx27.dtsi
+++ b/arch/arm/boot/dts/imx27.dtsi
@@ -58,7 +58,7 @@
 			reg = <0x10000000 0x10000000>;
 			ranges;
 
-			wdog@10002000 {
+			wdog: wdog@10002000 {
 				compatible = "fsl,imx27-wdt", "fsl,imx21-wdt";
 				reg = <0x10002000 0x4000>;
 				interrupts = <27>;
@@ -218,7 +218,8 @@
 				status = "disabled";
 			};
 		};
-		nand@d8000000 {
+
+		nfc: nand@d8000000 {
 			#address-cells = <1>;
 			#size-cells = <1>;
 
diff --git a/arch/arm/boot/dts/imx28-apf28.dts b/arch/arm/boot/dts/imx28-apf28.dts
new file mode 100644
index 0000000..7eb0758
--- /dev/null
+++ b/arch/arm/boot/dts/imx28-apf28.dts
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2012 Armadeus Systems - <support@armadeus.com>
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/dts-v1/;
+/include/ "imx28.dtsi"
+
+/ {
+	model = "Armadeus Systems APF28 module";
+	compatible = "armadeus,imx28-apf28", "fsl,imx28";
+
+	memory {
+		reg = <0x40000000 0x08000000>;
+	};
+
+	apb@80000000 {
+		apbh@80000000 {
+			gpmi-nand@8000c000 {
+				pinctrl-names = "default";
+				pinctrl-0 = <&gpmi_pins_a &gpmi_status_cfg>;
+				status = "okay";
+
+				partition@0 {
+					label = "u-boot";
+					reg = <0x0 0x300000>;
+				};
+
+				partition@300000 {
+					label = "env";
+					reg = <0x300000 0x80000>;
+				};
+
+				partition@380000 {
+					label = "env2";
+					reg = <0x380000 0x80000>;
+				};
+
+				partition@400000 {
+					label = "dtb";
+					reg = <0x400000 0x80000>;
+				};
+
+				partition@480000 {
+					label = "splash";
+					reg = <0x480000 0x80000>;
+				};
+
+				partition@500000 {
+					label = "kernel";
+					reg = <0x500000 0x800000>;
+				};
+
+				partition@d00000 {
+					label = "rootfs";
+					reg = <0xd00000 0xf300000>;
+				};
+			};
+		};
+
+		apbx@80040000 {
+			duart: serial@80074000 {
+				pinctrl-names = "default";
+				pinctrl-0 = <&duart_pins_a>;
+				status = "okay";
+			};
+		};
+	};
+
+	ahb@80080000 {
+		mac0: ethernet@800f0000 {
+			phy-mode = "rmii";
+			pinctrl-names = "default";
+			pinctrl-0 = <&mac0_pins_a>;
+			phy-reset-gpios = <&gpio4 13 0>;
+			status = "okay";
+		};
+	};
+};
diff --git a/arch/arm/boot/dts/imx28-apf28dev.dts b/arch/arm/boot/dts/imx28-apf28dev.dts
new file mode 100644
index 0000000..6d8865b
--- /dev/null
+++ b/arch/arm/boot/dts/imx28-apf28dev.dts
@@ -0,0 +1,154 @@
+/*
+ * Copyright 2012 Armadeus Systems - <support@armadeus.com>
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/* APF28Dev is a docking board for the APF28 SOM */
+/include/ "imx28-apf28.dts"
+
+/ {
+	model = "Armadeus Systems APF28Dev docking/development board";
+	compatible = "armadeus,imx28-apf28dev", "armadeus,imx28-apf28", "fsl,imx28";
+
+	apb@80000000 {
+		apbh@80000000 {
+			ssp0: ssp@80010000 {
+				compatible = "fsl,imx28-mmc";
+				pinctrl-names = "default";
+				pinctrl-0 = <&mmc0_4bit_pins_a
+					&mmc0_cd_cfg &mmc0_sck_cfg>;
+				bus-width = <4>;
+				status = "okay";
+			};
+
+			ssp2: ssp@80014000 {
+				compatible = "fsl,imx28-spi";
+				pinctrl-names = "default";
+				pinctrl-0 = <&spi2_pins_a>;
+				status = "okay";
+			};
+
+			pinctrl@80018000 {
+				pinctrl-names = "default";
+				pinctrl-0 = <&hog_pins_apf28dev>;
+
+				hog_pins_apf28dev: hog@0 {
+					reg = <0>;
+					fsl,pinmux-ids = <
+						0x1103 /* MX28_PAD_LCD_D16__GPIO_1_16 */
+						0x1113 /* MX28_PAD_LCD_D17__GPIO_1_17 */
+						0x1123 /* MX28_PAD_LCD_D18__GPIO_1_18 */
+						0x1133 /* MX28_PAD_LCD_D19__GPIO_1_19 */
+						0x1143 /* MX28_PAD_LCD_D20__GPIO_1_20 */
+						0x1153 /* MX28_PAD_LCD_D21__GPIO_1_21 */
+						0x1163 /* MX28_PAD_LCD_D22__GPIO_1_22 */
+					>;
+					fsl,drive-strength = <0>;
+					fsl,voltage = <1>;
+					fsl,pull-up = <0>;
+				};
+
+				lcdif_pins_apf28dev: lcdif-apf28dev@0 {
+					reg = <0>;
+					fsl,pinmux-ids = <
+						0x1181 /* MX28_PAD_LCD_RD_E__LCD_VSYNC */
+						0x1191 /* MX28_PAD_LCD_WR_RWN__LCD_HSYNC */
+						0x11a1 /* MX28_PAD_LCD_RS__LCD_DOTCLK */
+						0x11b1 /* MX28_PAD_LCD_CS__LCD_ENABLE */
+					>;
+					fsl,drive-strength = <0>;
+					fsl,voltage = <1>;
+					fsl,pull-up = <0>;
+				};
+			};
+
+			lcdif@80030000 {
+				pinctrl-names = "default";
+				pinctrl-0 = <&lcdif_16bit_pins_a
+						&lcdif_pins_apf28dev>;
+				status = "okay";
+			};
+		};
+
+		apbx@80040000 {
+			lradc@80050000 {
+				status = "okay";
+			};
+
+			i2c0: i2c@80058000 {
+				pinctrl-names = "default";
+				pinctrl-0 = <&i2c0_pins_a>;
+				status = "okay";
+			};
+
+			pwm: pwm@80064000 {
+				pinctrl-names = "default";
+				pinctrl-0 = <&pwm3_pins_a &pwm4_pins_a>;
+				status = "okay";
+			};
+
+			usbphy0: usbphy@8007c000 {
+				status = "okay";
+			};
+
+			usbphy1: usbphy@8007e000 {
+				status = "okay";
+			};
+		};
+	};
+
+	ahb@80080000 {
+		usb0: usb@80080000 {
+			vbus-supply = <&reg_usb0_vbus>;
+			status = "okay";
+		};
+
+		usb1: usb@80090000 {
+			status = "okay";
+		};
+
+		mac1: ethernet@800f4000 {
+			phy-mode = "rmii";
+			pinctrl-names = "default";
+			pinctrl-0 = <&mac1_pins_a>;
+			phy-reset-gpios = <&gpio0 23 0>;
+			status = "okay";
+		};
+	};
+
+	regulators {
+		compatible = "simple-bus";
+
+		reg_usb0_vbus: usb0_vbus {
+			compatible = "regulator-fixed";
+			regulator-name = "usb0_vbus";
+			regulator-min-microvolt = <5000000>;
+			regulator-max-microvolt = <5000000>;
+			gpio = <&gpio1 23 1>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		user {
+			label = "Heartbeat";
+			gpios = <&gpio0 21 0>;
+			linux,default-trigger = "heartbeat";
+		};
+	};
+
+	backlight {
+		compatible = "pwm-backlight";
+
+		pwms = <&pwm 3 191000>;
+		brightness-levels = <0 4 8 16 32 64 128 255>;
+		default-brightness-level = <6>;
+	};
+};
diff --git a/arch/arm/boot/dts/imx28-cfa10036.dts b/arch/arm/boot/dts/imx28-cfa10036.dts
index c03a577..1594694 100644
--- a/arch/arm/boot/dts/imx28-cfa10036.dts
+++ b/arch/arm/boot/dts/imx28-cfa10036.dts
@@ -22,6 +22,31 @@
 
 	apb@80000000 {
 		apbh@80000000 {
+			pinctrl@80018000 {
+				pinctrl-names = "default";
+				pinctrl-0 = <&hog_pins_cfa10036>;
+
+				hog_pins_cfa10036: hog-10036@0 {
+					reg = <0>;
+					fsl,pinmux-ids = <
+						0x2073 /* MX28_PAD_SSP0_D7__GPIO_2_7 */
+					>;
+					fsl,drive-strength = <0>;
+					fsl,voltage = <1>;
+					fsl,pull-up = <0>;
+				};
+
+				led_pins_cfa10036: leds-10036@0 {
+					reg = <0>;
+					fsl,pinmux-ids = <
+						0x3043 /* MX28_PAD_AUART1_RX__GPIO_3_4 */
+					>;
+					fsl,drive-strength = <0>;
+					fsl,voltage = <1>;
+					fsl,pull-up = <0>;
+				};
+			};
+
 			ssp0: ssp@80010000 {
 				compatible = "fsl,imx28-mmc";
 				pinctrl-names = "default";
@@ -33,16 +58,37 @@
 		};
 
 		apbx@80040000 {
+			pwm: pwm@80064000 {
+				pinctrl-names = "default";
+				pinctrl-0 = <&pwm4_pins_a>;
+				status = "okay";
+			};
+
 			duart: serial@80074000 {
 				pinctrl-names = "default";
 				pinctrl-0 = <&duart_pins_b>;
 				status = "okay";
 			};
+
+			i2c0: i2c@80058000 {
+				pinctrl-names = "default";
+				pinctrl-0 = <&i2c0_pins_b>;
+				status = "okay";
+
+				ssd1307: oled@3c {
+					compatible = "solomon,ssd1307fb-i2c";
+					reg = <0x3c>;
+					pwms = <&pwm 4 3000>;
+					reset-gpios = <&gpio2 7 0>;
+				};
+			};
 		};
 	};
 
 	leds {
 		compatible = "gpio-leds";
+		pinctrl-names = "default";
+		pinctrl-0 = <&led_pins_cfa10036>;
 
 		power {
 			gpios = <&gpio3 4 1>;
diff --git a/arch/arm/boot/dts/imx28-cfa10049.dts b/arch/arm/boot/dts/imx28-cfa10049.dts
index 05c892e..b222614 100644
--- a/arch/arm/boot/dts/imx28-cfa10049.dts
+++ b/arch/arm/boot/dts/imx28-cfa10049.dts
@@ -22,6 +22,22 @@
 	apb@80000000 {
 		apbh@80000000 {
 			pinctrl@80018000 {
+				pinctrl-names = "default", "default";
+				pinctrl-1 = <&hog_pins_cfa10049>;
+
+				hog_pins_cfa10049: hog-10049@0 {
+					reg = <0>;
+					fsl,pinmux-ids = <
+						0x0073 /* MX28_PAD_GPMI_D7__GPIO_0_7 */
+						0x1163 /* MX28_PAD_LCD_D22__GPIO_1_22 */
+						0x1173 /* MX28_PAD_LCD_D22__GPIO_1_23 */
+						0x2153 /* MX28_PAD_SSP2_D5__GPIO_2_21 */
+					>;
+					fsl,drive-strength = <0>;
+					fsl,voltage = <1>;
+					fsl,pull-up = <0>;
+				};
+
 				spi3_pins_cfa10049: spi3-cfa10049@0 {
 					reg = <0>;
 					fsl,pinmux-ids = <
@@ -29,6 +45,7 @@
 						0x01c1 /* MX28_PAD_GPMI_RESETN__SSP3_CMD */
 						0x0111 /* MX28_PAD_GPMI_CE1N__SSP3_D3 */
 						0x01a2 /* MX28_PAD_GPMI_ALE__SSP3_D4 */
+						0x01b2 /* MX28_PAD_GPMI_CLE__SSP3_D5 */
 					>;
 					fsl,drive-strength = <1>;
 					fsl,voltage = <1>;
@@ -60,6 +77,11 @@
 					spi-max-frequency = <100000>;
 				};
 
+				dac0: dh2228@2 {
+					compatible = "rohm,dh2228fv";
+					reg = <2>;
+					spi-max-frequency = <100000>;
+				};
 			};
 		};
 
@@ -96,4 +118,15 @@
 			gpio = <&gpio0 7 1>;
 		};
 	};
+
+	ahb@80080000 {
+		mac0: ethernet@800f0000 {
+			phy-mode = "rmii";
+			pinctrl-names = "default";
+			pinctrl-0 = <&mac0_pins_a>;
+			phy-reset-gpios = <&gpio2 21 0>;
+			phy-reset-duration = <100>;
+			status = "okay";
+		};
+	};
 };
diff --git a/arch/arm/boot/dts/imx28-evk.dts b/arch/arm/boot/dts/imx28-evk.dts
index a0ad71c..2da316e 100644
--- a/arch/arm/boot/dts/imx28-evk.dts
+++ b/arch/arm/boot/dts/imx28-evk.dts
@@ -76,7 +76,6 @@
 						0x20c3 /* MX28_PAD_SSP1_SCK__GPIO_2_12 */
 						0x31c3 /* MX28_PAD_PWM3__GPIO_3_28 */
 						0x31e3 /* MX28_PAD_LCD_RESET__GPIO_3_30 */
-						0x3053 /* MX28_PAD_AUART1_TX__GPIO_3_5 */
 						0x3083 /* MX28_PAD_AUART2_RX__GPIO_3_8 */
 						0x3093 /* MX28_PAD_AUART2_TX__GPIO_3_9 */
 					>;
@@ -85,6 +84,16 @@
 					fsl,pull-up = <0>;
 				};
 
+				led_pin_gpio3_5: led_gpio3_5@0 {
+					reg = <0>;
+					fsl,pinmux-ids = <
+						0x3053 /* MX28_PAD_AUART1_TX__GPIO_3_5 */
+					>;
+					fsl,drive-strength = <0>;
+					fsl,voltage = <1>;
+					fsl,pull-up = <0>;
+				};
+
 				gpmi_pins_evk: gpmi-nand-evk@0 {
 					reg = <0>;
 					fsl,pinmux-ids = <
@@ -288,6 +297,8 @@
 
 	leds {
 		compatible = "gpio-leds";
+		pinctrl-names = "default";
+		pinctrl-0 = <&led_pin_gpio3_5>;
 
 		user {
 			label = "Heartbeat";
diff --git a/arch/arm/boot/dts/imx28-sps1.dts b/arch/arm/boot/dts/imx28-sps1.dts
new file mode 100644
index 0000000..e6cde8a
--- /dev/null
+++ b/arch/arm/boot/dts/imx28-sps1.dts
@@ -0,0 +1,169 @@
+/*
+ * Copyright (C) 2012 Marek Vasut <marex@denx.de>
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/dts-v1/;
+/include/ "imx28.dtsi"
+
+/ {
+	model = "SchulerControl GmbH, SC SPS 1";
+	compatible = "schulercontrol,imx28-sps1", "fsl,imx28";
+
+	memory {
+		reg = <0x40000000 0x08000000>;
+	};
+
+	apb@80000000 {
+		apbh@80000000 {
+			pinctrl@80018000 {
+				pinctrl-names = "default";
+				pinctrl-0 = <&hog_pins_a>;
+
+				hog_pins_a: hog-gpios@0 {
+					reg = <0>;
+					fsl,pinmux-ids = <
+						0x0003 /* MX28_PAD_GPMI_D00__GPIO_0_0 */
+						0x0033 /* MX28_PAD_GPMI_D03__GPIO_0_3 */
+						0x0063 /* MX28_PAD_GPMI_D06__GPIO_0_6 */
+					>;
+					fsl,drive-strength = <0>;
+					fsl,voltage = <1>;
+					fsl,pull-up = <0>;
+				};
+
+			};
+
+			ssp0: ssp@80010000 {
+				compatible = "fsl,imx28-mmc";
+				pinctrl-names = "default";
+				pinctrl-0 = <&mmc0_4bit_pins_a>;
+				bus-width = <4>;
+				status = "okay";
+			};
+
+			ssp2: ssp@80014000 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,imx28-spi";
+				pinctrl-names = "default";
+				pinctrl-0 = <&spi2_pins_a>;
+				status = "okay";
+
+				flash: m25p80@0 {
+					#address-cells = <1>;
+					#size-cells = <1>;
+					compatible = "everspin,mr25h256", "mr25h256";
+					spi-max-frequency = <40000000>;
+					reg = <0>;
+				};
+			};
+		};
+
+		apbx@80040000 {
+			i2c0: i2c@80058000 {
+				pinctrl-names = "default";
+				pinctrl-0 = <&i2c0_pins_a>;
+				clock-frequency = <400000>;
+				status = "okay";
+
+				rtc: rtc@51 {
+					compatible = "nxp,pcf8563";
+					reg = <0x51>;
+				};
+
+				eeprom: eeprom@52 {
+					compatible = "atmel,24c64";
+					reg = <0x52>;
+					pagesize = <32>;
+				};
+			};
+
+			duart: serial@80074000 {
+				pinctrl-names = "default";
+				pinctrl-0 = <&duart_pins_a>;
+				status = "okay";
+			};
+
+			usbphy0: usbphy@8007c000 {
+				status = "okay";
+			};
+
+			auart0: serial@8006a000 {
+				pinctrl-names = "default";
+				pinctrl-0 = <&auart0_pins_a>;
+				status = "okay";
+			};
+		};
+	};
+
+	ahb@80080000 {
+		usb0: usb@80080000 {
+			vbus-supply = <&reg_usb0_vbus>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&usbphy0_pins_b>;
+			status = "okay";
+		};
+
+		mac0: ethernet@800f0000 {
+			phy-mode = "rmii";
+			pinctrl-names = "default";
+			pinctrl-0 = <&mac0_pins_a>;
+			status = "okay";
+		};
+
+		mac1: ethernet@800f4000 {
+			phy-mode = "rmii";
+			pinctrl-names = "default";
+			pinctrl-0 = <&mac1_pins_a>;
+			status = "okay";
+		};
+	};
+
+	regulators {
+		compatible = "simple-bus";
+
+		reg_usb0_vbus: usb0_vbus {
+			compatible = "regulator-fixed";
+			regulator-name = "usb0_vbus";
+			regulator-min-microvolt = <5000000>;
+			regulator-max-microvolt = <5000000>;
+			gpio = <&gpio3 9 0>;
+		};
+	};
+
+	leds {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		compatible = "gpio-leds";
+		status = "okay";
+
+		led@1 {
+			label = "sps1-1:yellow:user";
+			gpios = <&gpio0 6 0>;
+			linux,default-trigger = "heartbeat";
+			reg = <0>;
+		};
+
+		led@2 {
+			label = "sps1-2:red:user";
+			gpios = <&gpio0 3 0>;
+			linux,default-trigger = "heartbeat";
+			reg = <1>;
+		};
+
+		led@3 {
+			label = "sps1-3:red:user";
+			gpios = <&gpio0 0 0>;
+			default-trigger = "heartbeat";
+			reg = <2>;
+		};
+
+	};
+};
diff --git a/arch/arm/boot/dts/imx28.dtsi b/arch/arm/boot/dts/imx28.dtsi
index b4587b27..13b7053 100644
--- a/arch/arm/boot/dts/imx28.dtsi
+++ b/arch/arm/boot/dts/imx28.dtsi
@@ -492,6 +492,16 @@
 					fsl,pull-up = <0>;
 				};
 
+				pwm3_pins_a: pwm3@0 {
+					reg = <0>;
+					fsl,pinmux-ids = <
+						0x31c0 /* MX28_PAD_PWM3__PWM_3 */
+					>;
+					fsl,drive-strength = <0>;
+					fsl,voltage = <1>;
+					fsl,pull-up = <0>;
+				};
+
 				pwm4_pins_a: pwm4@0 {
 					reg = <0>;
 					fsl,pinmux-ids = <
@@ -535,6 +545,31 @@
 					fsl,pull-up = <0>;
 				};
 
+				lcdif_16bit_pins_a: lcdif-16bit@0 {
+					reg = <0>;
+					fsl,pinmux-ids = <
+						0x1000 /* MX28_PAD_LCD_D00__LCD_D0 */
+						0x1010 /* MX28_PAD_LCD_D01__LCD_D1 */
+						0x1020 /* MX28_PAD_LCD_D02__LCD_D2 */
+						0x1030 /* MX28_PAD_LCD_D03__LCD_D3 */
+						0x1040 /* MX28_PAD_LCD_D04__LCD_D4 */
+						0x1050 /* MX28_PAD_LCD_D05__LCD_D5 */
+						0x1060 /* MX28_PAD_LCD_D06__LCD_D6 */
+						0x1070 /* MX28_PAD_LCD_D07__LCD_D7 */
+						0x1080 /* MX28_PAD_LCD_D08__LCD_D8 */
+						0x1090 /* MX28_PAD_LCD_D09__LCD_D9 */
+						0x10a0 /* MX28_PAD_LCD_D10__LCD_D10 */
+						0x10b0 /* MX28_PAD_LCD_D11__LCD_D11 */
+						0x10c0 /* MX28_PAD_LCD_D12__LCD_D12 */
+						0x10d0 /* MX28_PAD_LCD_D13__LCD_D13 */
+						0x10e0 /* MX28_PAD_LCD_D14__LCD_D14 */
+						0x10f0 /* MX28_PAD_LCD_D15__LCD_D15 */
+					>;
+					fsl,drive-strength = <0>;
+					fsl,voltage = <1>;
+					fsl,pull-up = <0>;
+				};
+
 				can0_pins_a: can0@0 {
 					reg = <0>;
 					fsl,pinmux-ids = <
diff --git a/arch/arm/boot/dts/imx51.dtsi b/arch/arm/boot/dts/imx51.dtsi
index 2781e47..1f5d45e 100644
--- a/arch/arm/boot/dts/imx51.dtsi
+++ b/arch/arm/boot/dts/imx51.dtsi
@@ -83,7 +83,7 @@
 				reg = <0x70000000 0x40000>;
 				ranges;
 
-				esdhc@70004000 { /* ESDHC1 */
+				esdhc1: esdhc@70004000 {
 					compatible = "fsl,imx51-esdhc";
 					reg = <0x70004000 0x4000>;
 					interrupts = <1>;
@@ -92,12 +92,13 @@
 					status = "disabled";
 				};
 
-				esdhc@70008000 { /* ESDHC2 */
+				esdhc2: esdhc@70008000 {
 					compatible = "fsl,imx51-esdhc";
 					reg = <0x70008000 0x4000>;
 					interrupts = <2>;
 					clocks = <&clks 45>, <&clks 0>, <&clks 72>;
 					clock-names = "ipg", "ahb", "per";
+					bus-width = <4>;
 					status = "disabled";
 				};
 
@@ -110,7 +111,7 @@
 					status = "disabled";
 				};
 
-				ecspi@70010000 { /* ECSPI1 */
+				ecspi1: ecspi@70010000 {
 					#address-cells = <1>;
 					#size-cells = <0>;
 					compatible = "fsl,imx51-ecspi";
@@ -131,47 +132,49 @@
 					status = "disabled";
 				};
 
-				esdhc@70020000 { /* ESDHC3 */
+				esdhc3: esdhc@70020000 {
 					compatible = "fsl,imx51-esdhc";
 					reg = <0x70020000 0x4000>;
 					interrupts = <3>;
 					clocks = <&clks 46>, <&clks 0>, <&clks 73>;
 					clock-names = "ipg", "ahb", "per";
+					bus-width = <4>;
 					status = "disabled";
 				};
 
-				esdhc@70024000 { /* ESDHC4 */
+				esdhc4: esdhc@70024000 {
 					compatible = "fsl,imx51-esdhc";
 					reg = <0x70024000 0x4000>;
 					interrupts = <4>;
 					clocks = <&clks 47>, <&clks 0>, <&clks 74>;
 					clock-names = "ipg", "ahb", "per";
+					bus-width = <4>;
 					status = "disabled";
 				};
 			};
 
-			usb@73f80000 {
+			usbotg: usb@73f80000 {
 				compatible = "fsl,imx51-usb", "fsl,imx27-usb";
 				reg = <0x73f80000 0x0200>;
 				interrupts = <18>;
 				status = "disabled";
 			};
 
-			usb@73f80200 {
+			usbh1: usb@73f80200 {
 				compatible = "fsl,imx51-usb", "fsl,imx27-usb";
 				reg = <0x73f80200 0x0200>;
 				interrupts = <14>;
 				status = "disabled";
 			};
 
-			usb@73f80400 {
+			usbh2: usb@73f80400 {
 				compatible = "fsl,imx51-usb", "fsl,imx27-usb";
 				reg = <0x73f80400 0x0200>;
 				interrupts = <16>;
 				status = "disabled";
 			};
 
-			usb@73f80600 {
+			usbh3: usb@73f80600 {
 				compatible = "fsl,imx51-usb", "fsl,imx27-usb";
 				reg = <0x73f80600 0x0200>;
 				interrupts = <17>;
@@ -218,14 +221,14 @@
 				#interrupt-cells = <2>;
 			};
 
-			wdog@73f98000 { /* WDOG1 */
+			wdog1: wdog@73f98000 {
 				compatible = "fsl,imx51-wdt", "fsl,imx21-wdt";
 				reg = <0x73f98000 0x4000>;
 				interrupts = <58>;
 				clocks = <&clks 0>;
 			};
 
-			wdog@73f9c000 { /* WDOG2 */
+			wdog2: wdog@73f9c000 {
 				compatible = "fsl,imx51-wdt", "fsl,imx21-wdt";
 				reg = <0x73f9c000 0x4000>;
 				interrupts = <59>;
@@ -233,7 +236,7 @@
 				status = "disabled";
 			};
 
-			iomuxc@73fa8000 {
+			iomuxc: iomuxc@73fa8000 {
 				compatible = "fsl,imx51-iomuxc";
 				reg = <0x73fa8000 0x4000>;
 
@@ -460,7 +463,7 @@
 			reg = <0x80000000 0x10000000>;
 			ranges;
 
-			ecspi@83fac000 { /* ECSPI2 */
+			ecspi2: ecspi@83fac000 {
 				#address-cells = <1>;
 				#size-cells = <0>;
 				compatible = "fsl,imx51-ecspi";
@@ -471,7 +474,7 @@
 				status = "disabled";
 			};
 
-			sdma@83fb0000 {
+			sdma: sdma@83fb0000 {
 				compatible = "fsl,imx51-sdma", "fsl,imx35-sdma";
 				reg = <0x83fb0000 0x4000>;
 				interrupts = <6>;
@@ -480,7 +483,7 @@
 				fsl,sdma-ram-script-name = "imx/sdma/sdma-imx51.bin";
 			};
 
-			cspi@83fc0000 {
+			cspi: cspi@83fc0000 {
 				#address-cells = <1>;
 				#size-cells = <0>;
 				compatible = "fsl,imx51-cspi", "fsl,imx35-cspi";
@@ -491,7 +494,7 @@
 				status = "disabled";
 			};
 
-			i2c@83fc4000 { /* I2C2 */
+			i2c2: i2c@83fc4000 {
 				#address-cells = <1>;
 				#size-cells = <0>;
 				compatible = "fsl,imx51-i2c", "fsl,imx21-i2c";
@@ -501,7 +504,7 @@
 				status = "disabled";
 			};
 
-			i2c@83fc8000 { /* I2C1 */
+			i2c1: i2c@83fc8000 {
 				#address-cells = <1>;
 				#size-cells = <0>;
 				compatible = "fsl,imx51-i2c", "fsl,imx21-i2c";
@@ -521,13 +524,13 @@
 				status = "disabled";
 			};
 
-			audmux@83fd0000 {
+			audmux: audmux@83fd0000 {
 				compatible = "fsl,imx51-audmux", "fsl,imx31-audmux";
 				reg = <0x83fd0000 0x4000>;
 				status = "disabled";
 			};
 
-			nand@83fdb000 {
+			nfc: nand@83fdb000 {
 				compatible = "fsl,imx51-nand";
 				reg = <0x83fdb000 0x1000 0xcfff0000 0x10000>;
 				interrupts = <8>;
@@ -545,7 +548,7 @@
 				status = "disabled";
 			};
 
-			ethernet@83fec000 {
+			fec: ethernet@83fec000 {
 				compatible = "fsl,imx51-fec", "fsl,imx27-fec";
 				reg = <0x83fec000 0x4000>;
 				interrupts = <87>;
diff --git a/arch/arm/boot/dts/imx53-qsb.dts b/arch/arm/boot/dts/imx53-qsb.dts
index 08948af..b007553 100644
--- a/arch/arm/boot/dts/imx53-qsb.dts
+++ b/arch/arm/boot/dts/imx53-qsb.dts
@@ -60,10 +60,17 @@
 							697  0x80000000	/* MX53_PAD_EIM_DA12__GPIO3_12 */
 							701  0x80000000	/* MX53_PAD_EIM_DA13__GPIO3_13 */
 							868  0x80000000	/* MX53_PAD_PATA_DA_0__GPIO7_6 */
+							1149 0x80000000 /* MX53_PAD_GPIO_16__GPIO7_11 */
+						>;
+					};
+
+					led_pin_gpio7_7: led_gpio7_7@0 {
+						fsl,pins = <
 							873  0x80000000	/* MX53_PAD_PATA_DA_1__GPIO7_7 */
 						>;
 					};
 				};
+
 			};
 
 			uart1: serial@53fbc000 {
@@ -100,76 +107,93 @@
 				pmic: dialog@48 {
 					compatible = "dlg,da9053-aa", "dlg,da9052";
 					reg = <0x48>;
+					interrupt-parent = <&gpio7>;
+					interrupts = <11 0x8>; /* low-level active IRQ at GPIO7_11 */
 
 					regulators {
-						buck0 {
+						buck1_reg: buck1 {
 							regulator-min-microvolt = <500000>;
 							regulator-max-microvolt = <2075000>;
+							regulator-always-on;
 						};
 
-						buck1 {
+						buck2_reg: buck2 {
 							regulator-min-microvolt = <500000>;
 							regulator-max-microvolt = <2075000>;
+							regulator-always-on;
 						};
 
-						buck2 {
+						buck3_reg: buck3 {
 							regulator-min-microvolt = <925000>;
 					                regulator-max-microvolt = <2500000>;
+							regulator-always-on;
 						};
 
-						buck3 {
+						buck4_reg: buck4 {
 							regulator-min-microvolt = <925000>;
 					                regulator-max-microvolt = <2500000>;
+							regulator-always-on;
 						};
 
-						ldo4 {
+						ldo1_reg: ldo1 {
 							regulator-min-microvolt = <600000>;
 							regulator-max-microvolt = <1800000>;
+							regulator-boot-on;
+							regulator-always-on;
 						};
 
-						ldo5 {
+						ldo2_reg: ldo2 {
+							regulator-min-microvolt = <600000>;
+							regulator-max-microvolt = <1800000>;
+							regulator-always-on;
+						};
+
+						ldo3_reg: ldo3 {
 							regulator-min-microvolt = <600000>;
 					                regulator-max-microvolt = <1800000>;
+							regulator-always-on;
 						};
 
-						ldo6 {
+						ldo4_reg: ldo4 {
 							regulator-min-microvolt = <1725000>;
 					                regulator-max-microvolt = <3300000>;
+							regulator-always-on;
 						};
 
-						ldo7 {
+						ldo5_reg: ldo5 {
 							regulator-min-microvolt = <1725000>;
 					                regulator-max-microvolt = <3300000>;
+							regulator-always-on;
 						};
 
-						ldo8 {
+						ldo6_reg: ldo6 {
 							regulator-min-microvolt = <1200000>;
 					                regulator-max-microvolt = <3600000>;
+							regulator-always-on;
 						};
 
-						ldo9 {
+						ldo7_reg: ldo7 {
 							regulator-min-microvolt = <1200000>;
 					                regulator-max-microvolt = <3600000>;
+							regulator-always-on;
 						};
 
-						ldo10 {
+						ldo8_reg: ldo8 {
 							regulator-min-microvolt = <1200000>;
 					                regulator-max-microvolt = <3600000>;
+							regulator-always-on;
 						};
 
-						ldo11 {
+						ldo9_reg: ldo9 {
 							regulator-min-microvolt = <1200000>;
 					                regulator-max-microvolt = <3600000>;
+							regulator-always-on;
 						};
 
-						ldo12 {
+						ldo10_reg: ldo10 {
 							regulator-min-microvolt = <1250000>;
 					                regulator-max-microvolt = <3650000>;
-						};
-
-						ldo13 {
-							regulator-min-microvolt = <1200000>;
-					                regulator-max-microvolt = <3600000>;
+							regulator-always-on;
 						};
 					};
 				};
@@ -216,6 +240,8 @@
 
 	leds {
 		compatible = "gpio-leds";
+		pinctrl-names = "default";
+		pinctrl-0 = <&led_pin_gpio7_7>;
 
 		user {
 			label = "Heartbeat";
diff --git a/arch/arm/boot/dts/imx53.dtsi b/arch/arm/boot/dts/imx53.dtsi
index da9a047..552aed4 100644
--- a/arch/arm/boot/dts/imx53.dtsi
+++ b/arch/arm/boot/dts/imx53.dtsi
@@ -88,21 +88,23 @@
 				reg = <0x50000000 0x40000>;
 				ranges;
 
-				esdhc@50004000 { /* ESDHC1 */
+				esdhc1: esdhc@50004000 {
 					compatible = "fsl,imx53-esdhc";
 					reg = <0x50004000 0x4000>;
 					interrupts = <1>;
 					clocks = <&clks 44>, <&clks 0>, <&clks 71>;
 					clock-names = "ipg", "ahb", "per";
+					bus-width = <4>;
 					status = "disabled";
 				};
 
-				esdhc@50008000 { /* ESDHC2 */
+				esdhc2: esdhc@50008000 {
 					compatible = "fsl,imx53-esdhc";
 					reg = <0x50008000 0x4000>;
 					interrupts = <2>;
 					clocks = <&clks 45>, <&clks 0>, <&clks 72>;
 					clock-names = "ipg", "ahb", "per";
+					bus-width = <4>;
 					status = "disabled";
 				};
 
@@ -115,7 +117,7 @@
 					status = "disabled";
 				};
 
-				ecspi@50010000 { /* ECSPI1 */
+				ecspi1: ecspi@50010000 {
 					#address-cells = <1>;
 					#size-cells = <0>;
 					compatible = "fsl,imx53-ecspi", "fsl,imx51-ecspi";
@@ -136,47 +138,49 @@
 					status = "disabled";
 				};
 
-				esdhc@50020000 { /* ESDHC3 */
+				esdhc3: esdhc@50020000 {
 					compatible = "fsl,imx53-esdhc";
 					reg = <0x50020000 0x4000>;
 					interrupts = <3>;
 					clocks = <&clks 46>, <&clks 0>, <&clks 73>;
 					clock-names = "ipg", "ahb", "per";
+					bus-width = <4>;
 					status = "disabled";
 				};
 
-				esdhc@50024000 { /* ESDHC4 */
+				esdhc4: esdhc@50024000 {
 					compatible = "fsl,imx53-esdhc";
 					reg = <0x50024000 0x4000>;
 					interrupts = <4>;
 					clocks = <&clks 47>, <&clks 0>, <&clks 74>;
 					clock-names = "ipg", "ahb", "per";
+					bus-width = <4>;
 					status = "disabled";
 				};
 			};
 
-			usb@53f80000 {
+			usbotg: usb@53f80000 {
 				compatible = "fsl,imx53-usb", "fsl,imx27-usb";
 				reg = <0x53f80000 0x0200>;
 				interrupts = <18>;
 				status = "disabled";
 			};
 
-			usb@53f80200 {
+			usbh1: usb@53f80200 {
 				compatible = "fsl,imx53-usb", "fsl,imx27-usb";
 				reg = <0x53f80200 0x0200>;
 				interrupts = <14>;
 				status = "disabled";
 			};
 
-			usb@53f80400 {
+			usbh2: usb@53f80400 {
 				compatible = "fsl,imx53-usb", "fsl,imx27-usb";
 				reg = <0x53f80400 0x0200>;
 				interrupts = <16>;
 				status = "disabled";
 			};
 
-			usb@53f80600 {
+			usbh3: usb@53f80600 {
 				compatible = "fsl,imx53-usb", "fsl,imx27-usb";
 				reg = <0x53f80600 0x0200>;
 				interrupts = <17>;
@@ -223,14 +227,14 @@
 				#interrupt-cells = <2>;
 			};
 
-			wdog@53f98000 { /* WDOG1 */
+			wdog1: wdog@53f98000 {
 				compatible = "fsl,imx53-wdt", "fsl,imx21-wdt";
 				reg = <0x53f98000 0x4000>;
 				interrupts = <58>;
 				clocks = <&clks 0>;
 			};
 
-			wdog@53f9c000 { /* WDOG2 */
+			wdog2: wdog@53f9c000 {
 				compatible = "fsl,imx53-wdt", "fsl,imx21-wdt";
 				reg = <0x53f9c000 0x4000>;
 				interrupts = <59>;
@@ -238,7 +242,7 @@
 				status = "disabled";
 			};
 
-			iomuxc@53fa8000 {
+			iomuxc: iomuxc@53fa8000 {
 				compatible = "fsl,imx53-iomuxc";
 				reg = <0x53fa8000 0x4000>;
 
@@ -338,6 +342,24 @@
 					};
 				};
 
+				can1 {
+					pinctrl_can1_1: can1grp-1 {
+						fsl,pins = <
+							847 0x80000000  /* MX53_PAD_PATA_INTRQ__CAN1_TXCAN */
+							853 0x80000000  /* MX53_PAD_PATA_DIOR__CAN1_RXCAN */
+						>;
+					};
+				};
+
+				can2 {
+					pinctrl_can2_1: can2grp-1 {
+						fsl,pins = <
+							67  0x80000000  /* MX53_PAD_KEY_COL4__CAN2_TXCAN */
+							74  0x80000000  /* MX53_PAD_KEY_ROW4__CAN2_RXCAN */
+						>;
+					};
+				};
+
 				i2c1 {
 					pinctrl_i2c1_1: i2c1grp-1 {
 						fsl,pins = <
@@ -356,6 +378,15 @@
 					};
 				};
 
+				i2c3 {
+					pinctrl_i2c3_1: i2c3grp-1 {
+						fsl,pins = <
+							1102 0xc0000000	/* MX53_PAD_GPIO_6__I2C3_SDA */
+							1130 0xc0000000	/* MX53_PAD_GPIO_5__I2C3_SCL */
+						>;
+					};
+				};
+
 				uart1 {
 					pinctrl_uart1_1: uart1grp-1 {
 						fsl,pins = <
@@ -391,6 +422,25 @@
 						>;
 					};
 				};
+
+				uart4 {
+					pinctrl_uart4_1: uart4grp-1 {
+						fsl,pins = <
+							11 0x1c5	/* MX53_PAD_KEY_COL0__UART4_TXD_MUX */
+							18 0x1c5	/* MX53_PAD_KEY_ROW0__UART4_RXD_MUX */
+						>;
+					};
+				};
+
+				uart5 {
+					pinctrl_uart5_1: uart5grp-1 {
+						fsl,pins = <
+							24 0x1c5	/* MX53_PAD_KEY_COL1__UART5_TXD_MUX */
+							31 0x1c5	/* MX53_PAD_KEY_ROW1__UART5_RXD_MUX */
+						>;
+					};
+				};
+
 			};
 
 			pwm1: pwm@53fb4000 {
@@ -484,7 +534,7 @@
 				#interrupt-cells = <2>;
 			};
 
-			i2c@53fec000 { /* I2C3 */
+			i2c3: i2c@53fec000 {
 				#address-cells = <1>;
 				#size-cells = <0>;
 				compatible = "fsl,imx53-i2c", "fsl,imx21-i2c";
@@ -520,7 +570,7 @@
 				status = "disabled";
 			};
 
-			ecspi@63fac000 { /* ECSPI2 */
+			ecspi2: ecspi@63fac000 {
 				#address-cells = <1>;
 				#size-cells = <0>;
 				compatible = "fsl,imx53-ecspi", "fsl,imx51-ecspi";
@@ -531,7 +581,7 @@
 				status = "disabled";
 			};
 
-			sdma@63fb0000 {
+			sdma: sdma@63fb0000 {
 				compatible = "fsl,imx53-sdma", "fsl,imx35-sdma";
 				reg = <0x63fb0000 0x4000>;
 				interrupts = <6>;
@@ -540,7 +590,7 @@
 				fsl,sdma-ram-script-name = "imx/sdma/sdma-imx53.bin";
 			};
 
-			cspi@63fc0000 {
+			cspi: cspi@63fc0000 {
 				#address-cells = <1>;
 				#size-cells = <0>;
 				compatible = "fsl,imx53-cspi", "fsl,imx35-cspi";
@@ -551,7 +601,7 @@
 				status = "disabled";
 			};
 
-			i2c@63fc4000 { /* I2C2 */
+			i2c2: i2c@63fc4000 {
 				#address-cells = <1>;
 				#size-cells = <0>;
 				compatible = "fsl,imx53-i2c", "fsl,imx21-i2c";
@@ -561,7 +611,7 @@
 				status = "disabled";
 			};
 
-			i2c@63fc8000 { /* I2C1 */
+			i2c1: i2c@63fc8000 {
 				#address-cells = <1>;
 				#size-cells = <0>;
 				compatible = "fsl,imx53-i2c", "fsl,imx21-i2c";
@@ -581,13 +631,13 @@
 				status = "disabled";
 			};
 
-			audmux@63fd0000 {
+			audmux: audmux@63fd0000 {
 				compatible = "fsl,imx53-audmux", "fsl,imx31-audmux";
 				reg = <0x63fd0000 0x4000>;
 				status = "disabled";
 			};
 
-			nand@63fdb000 {
+			nfc: nand@63fdb000 {
 				compatible = "fsl,imx53-nand";
 				reg = <0x63fdb000 0x1000 0xf7ff0000 0x10000>;
 				interrupts = <8>;
@@ -605,7 +655,7 @@
 				status = "disabled";
 			};
 
-			ethernet@63fec000 {
+			fec: ethernet@63fec000 {
 				compatible = "fsl,imx53-fec", "fsl,imx25-fec";
 				reg = <0x63fec000 0x4000>;
 				interrupts = <87>;
diff --git a/arch/arm/boot/dts/imx6q-sabreauto.dts b/arch/arm/boot/dts/imx6q-sabreauto.dts
new file mode 100644
index 0000000..826e4ad
--- /dev/null
+++ b/arch/arm/boot/dts/imx6q-sabreauto.dts
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2012 Freescale Semiconductor, Inc.
+ * Copyright 2011 Linaro Ltd.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/dts-v1/;
+/include/ "imx6q.dtsi"
+
+/ {
+	model = "Freescale i.MX6 Quad SABRE Automotive Board";
+	compatible = "fsl,imx6q-sabreauto", "fsl,imx6q";
+
+	memory {
+		reg = <0x10000000 0x80000000>;
+	};
+
+	soc {
+		aips-bus@02000000 { /* AIPS1 */
+			iomuxc@020e0000 {
+				pinctrl-names = "default";
+				pinctrl-0 = <&pinctrl_hog>;
+
+				hog {
+					pinctrl_hog: hoggrp {
+						fsl,pins = <
+							1376 0x80000000	/* MX6Q_PAD_NANDF_CS2__GPIO_6_15 */
+							13   0x80000000	/* MX6Q_PAD_SD2_DAT2__GPIO_1_13 */
+						>;
+					};
+				};
+			};
+		};
+
+		aips-bus@02100000 { /* AIPS2 */
+			uart4: serial@021f0000 {
+				pinctrl-names = "default";
+				pinctrl-0 = <&pinctrl_uart4_1>;
+				status = "okay";
+			};
+
+			ethernet@02188000 {
+				pinctrl-names = "default";
+				pinctrl-0 = <&pinctrl_enet_2>;
+				phy-mode = "rgmii";
+				status = "okay";
+			};
+
+			usdhc@02198000 { /* uSDHC3 */
+				pinctrl-names = "default";
+				pinctrl-0 = <&pinctrl_usdhc3_1>;
+				cd-gpios = <&gpio6 15 0>;
+				wp-gpios = <&gpio1 13 0>;
+				status = "okay";
+			};
+		};
+	};
+};
diff --git a/arch/arm/boot/dts/imx6q-sabresd.dts b/arch/arm/boot/dts/imx6q-sabresd.dts
index e596c28c..a424025 100644
--- a/arch/arm/boot/dts/imx6q-sabresd.dts
+++ b/arch/arm/boot/dts/imx6q-sabresd.dts
@@ -38,6 +38,8 @@
 				hog {
 					pinctrl_hog: hoggrp {
 						fsl,pins = <
+							1004 0x80000000 /* MX6Q_PAD_GPIO_4__GPIO_1_4 */
+							1012 0x80000000 /* MX6Q_PAD_GPIO_5__GPIO_1_5 */
 							1402 0x80000000	/* MX6Q_PAD_NANDF_D0__GPIO_2_0 */
 							1410 0x80000000	/* MX6Q_PAD_NANDF_D1__GPIO_2_1 */
 							1418 0x80000000	/* MX6Q_PAD_NANDF_D2__GPIO_2_2 */
@@ -73,4 +75,20 @@
 			};
 		};
 	};
+
+	gpio-keys {
+		compatible = "gpio-keys";
+
+		volume-up {
+			label = "Volume Up";
+			gpios = <&gpio1 4 0>;
+			linux,code = <115>; /* KEY_VOLUMEUP */
+		};
+
+		volume-down {
+			label = "Volume Down";
+			gpios = <&gpio1 5 0>;
+			linux,code = <114>; /* KEY_VOLUMEDOWN */
+		};
+	};
 };
diff --git a/arch/arm/boot/dts/imx6q.dtsi b/arch/arm/boot/dts/imx6q.dtsi
index cce1d87..d6265ca 100644
--- a/arch/arm/boot/dts/imx6q.dtsi
+++ b/arch/arm/boot/dts/imx6q.dtsi
@@ -36,6 +36,14 @@
 			compatible = "arm,cortex-a9";
 			reg = <0>;
 			next-level-cache = <&L2>;
+			operating-points = <
+				/* kHz    uV */
+				792000  1100000
+				396000  950000
+				198000  850000
+			>;
+			clock-latency = <61036>; /* two CLK32 periods */
+			cpu0-supply = <&reg_cpu>;
 		};
 
 		cpu@1 {
@@ -100,7 +108,7 @@
 			clocks = <&clks 106>;
 		};
 
-		gpmi-nand@00112000 {
+		nfc: gpmi-nand@00112000 {
 			compatible = "fsl,imx6q-gpmi-nand";
 			#address-cells = <1>;
 			#size-cells = <1>;
@@ -144,12 +152,12 @@
 				reg = <0x02000000 0x40000>;
 				ranges;
 
-				spdif@02004000 {
+				spdif: spdif@02004000 {
 					reg = <0x02004000 0x4000>;
 					interrupts = <0 52 0x04>;
 				};
 
-				ecspi@02008000 { /* eCSPI1 */
+				ecspi1: ecspi@02008000 {
 					#address-cells = <1>;
 					#size-cells = <0>;
 					compatible = "fsl,imx6q-ecspi", "fsl,imx51-ecspi";
@@ -160,7 +168,7 @@
 					status = "disabled";
 				};
 
-				ecspi@0200c000 { /* eCSPI2 */
+				ecspi2: ecspi@0200c000 {
 					#address-cells = <1>;
 					#size-cells = <0>;
 					compatible = "fsl,imx6q-ecspi", "fsl,imx51-ecspi";
@@ -171,7 +179,7 @@
 					status = "disabled";
 				};
 
-				ecspi@02010000 { /* eCSPI3 */
+				ecspi3: ecspi@02010000 {
 					#address-cells = <1>;
 					#size-cells = <0>;
 					compatible = "fsl,imx6q-ecspi", "fsl,imx51-ecspi";
@@ -182,7 +190,7 @@
 					status = "disabled";
 				};
 
-				ecspi@02014000 { /* eCSPI4 */
+				ecspi4: ecspi@02014000 {
 					#address-cells = <1>;
 					#size-cells = <0>;
 					compatible = "fsl,imx6q-ecspi", "fsl,imx51-ecspi";
@@ -193,7 +201,7 @@
 					status = "disabled";
 				};
 
-				ecspi@02018000 { /* eCSPI5 */
+				ecspi5: ecspi@02018000 {
 					#address-cells = <1>;
 					#size-cells = <0>;
 					compatible = "fsl,imx6q-ecspi", "fsl,imx51-ecspi";
@@ -213,7 +221,7 @@
 					status = "disabled";
 				};
 
-				esai@02024000 {
+				esai: esai@02024000 {
 					reg = <0x02024000 0x4000>;
 					interrupts = <0 51 0x04>;
 				};
@@ -248,7 +256,7 @@
 					status = "disabled";
 				};
 
-				asrc@02034000 {
+				asrc: asrc@02034000 {
 					reg = <0x02034000 0x4000>;
 					interrupts = <0 50 0x04>;
 				};
@@ -258,7 +266,7 @@
 				};
 			};
 
-			vpu@02040000 {
+			vpu: vpu@02040000 {
 				reg = <0x02040000 0x3c000>;
 				interrupts = <0 3 0x04 0 12 0x04>;
 			};
@@ -267,7 +275,7 @@
 				reg = <0x0207c000 0x4000>;
 			};
 
-			pwm@02080000 { /* PWM1 */
+			pwm1: pwm@02080000 {
 				#pwm-cells = <2>;
 				compatible = "fsl,imx6q-pwm", "fsl,imx27-pwm";
 				reg = <0x02080000 0x4000>;
@@ -276,7 +284,7 @@
 				clock-names = "ipg", "per";
 			};
 
-			pwm@02084000 { /* PWM2 */
+			pwm2: pwm@02084000 {
 				#pwm-cells = <2>;
 				compatible = "fsl,imx6q-pwm", "fsl,imx27-pwm";
 				reg = <0x02084000 0x4000>;
@@ -285,7 +293,7 @@
 				clock-names = "ipg", "per";
 			};
 
-			pwm@02088000 { /* PWM3 */
+			pwm3: pwm@02088000 {
 				#pwm-cells = <2>;
 				compatible = "fsl,imx6q-pwm", "fsl,imx27-pwm";
 				reg = <0x02088000 0x4000>;
@@ -294,7 +302,7 @@
 				clock-names = "ipg", "per";
 			};
 
-			pwm@0208c000 { /* PWM4 */
+			pwm4: pwm@0208c000 {
 				#pwm-cells = <2>;
 				compatible = "fsl,imx6q-pwm", "fsl,imx27-pwm";
 				reg = <0x0208c000 0x4000>;
@@ -303,17 +311,17 @@
 				clock-names = "ipg", "per";
 			};
 
-			flexcan@02090000 { /* CAN1 */
+			can1: flexcan@02090000 {
 				reg = <0x02090000 0x4000>;
 				interrupts = <0 110 0x04>;
 			};
 
-			flexcan@02094000 { /* CAN2 */
+			can2: flexcan@02094000 {
 				reg = <0x02094000 0x4000>;
 				interrupts = <0 111 0x04>;
 			};
 
-			gpt@02098000 {
+			gpt: gpt@02098000 {
 				compatible = "fsl,imx6q-gpt";
 				reg = <0x02098000 0x4000>;
 				interrupts = <0 55 0x04>;
@@ -389,19 +397,19 @@
 				#interrupt-cells = <2>;
 			};
 
-			kpp@020b8000 {
+			kpp: kpp@020b8000 {
 				reg = <0x020b8000 0x4000>;
 				interrupts = <0 82 0x04>;
 			};
 
-			wdog@020bc000 { /* WDOG1 */
+			wdog1: wdog@020bc000 {
 				compatible = "fsl,imx6q-wdt", "fsl,imx21-wdt";
 				reg = <0x020bc000 0x4000>;
 				interrupts = <0 80 0x04>;
 				clocks = <&clks 0>;
 			};
 
-			wdog@020c0000 { /* WDOG2 */
+			wdog2: wdog@020c0000 {
 				compatible = "fsl,imx6q-wdt", "fsl,imx21-wdt";
 				reg = <0x020c0000 0x4000>;
 				interrupts = <0 81 0x04>;
@@ -463,7 +471,7 @@
 					anatop-max-voltage = <2750000>;
 				};
 
-				regulator-vddcore@140 {
+				reg_cpu: regulator-vddcore@140 {
 					compatible = "fsl,anatop-regulator";
 					regulator-name = "cpu";
 					regulator-min-microvolt = <725000>;
@@ -521,27 +529,35 @@
 			};
 
 			snvs@020cc000 {
-				reg = <0x020cc000 0x4000>;
-				interrupts = <0 19 0x04 0 20 0x04>;
+				compatible = "fsl,sec-v4.0-mon", "simple-bus";
+				#address-cells = <1>;
+				#size-cells = <1>;
+				ranges = <0 0x020cc000 0x4000>;
+
+				snvs-rtc-lp@34 {
+					compatible = "fsl,sec-v4.0-mon-rtc-lp";
+					reg = <0x34 0x58>;
+					interrupts = <0 19 0x04 0 20 0x04>;
+				};
 			};
 
-			epit@020d0000 { /* EPIT1 */
+			epit1: epit@020d0000 { /* EPIT1 */
 				reg = <0x020d0000 0x4000>;
 				interrupts = <0 56 0x04>;
 			};
 
-			epit@020d4000 { /* EPIT2 */
+			epit2: epit@020d4000 { /* EPIT2 */
 				reg = <0x020d4000 0x4000>;
 				interrupts = <0 57 0x04>;
 			};
 
-			src@020d8000 {
+			src: src@020d8000 {
 				compatible = "fsl,imx6q-src";
 				reg = <0x020d8000 0x4000>;
 				interrupts = <0 91 0x04 0 96 0x04>;
 			};
 
-			gpc@020dc000 {
+			gpc: gpc@020dc000 {
 				compatible = "fsl,imx6q-gpc";
 				reg = <0x020dc000 0x4000>;
 				interrupts = <0 89 0x04 0 90 0x04>;
@@ -552,7 +568,7 @@
 				reg = <0x020e0000 0x38>;
 			};
 
-			iomuxc@020e0000 {
+			iomuxc: iomuxc@020e0000 {
 				compatible = "fsl,imx6q-iomuxc";
 				reg = <0x020e0000 0x4000>;
 
@@ -765,17 +781,17 @@
 				};
 			};
 
-			dcic@020e4000 { /* DCIC1 */
+			dcic1: dcic@020e4000 {
 				reg = <0x020e4000 0x4000>;
 				interrupts = <0 124 0x04>;
 			};
 
-			dcic@020e8000 { /* DCIC2 */
+			dcic2: dcic@020e8000 {
 				reg = <0x020e8000 0x4000>;
 				interrupts = <0 125 0x04>;
 			};
 
-			sdma@020ec000 {
+			sdma: sdma@020ec000 {
 				compatible = "fsl,imx6q-sdma", "fsl,imx35-sdma";
 				reg = <0x020ec000 0x4000>;
 				interrupts = <0 2 0x04>;
@@ -801,7 +817,7 @@
 				reg = <0x0217c000 0x4000>;
 			};
 
-			usb@02184000 { /* USB OTG */
+			usbotg: usb@02184000 {
 				compatible = "fsl,imx6q-usb", "fsl,imx27-usb";
 				reg = <0x02184000 0x200>;
 				interrupts = <0 43 0x04>;
@@ -811,7 +827,7 @@
 				status = "disabled";
 			};
 
-			usb@02184200 { /* USB1 */
+			usbh1: usb@02184200 {
 				compatible = "fsl,imx6q-usb", "fsl,imx27-usb";
 				reg = <0x02184200 0x200>;
 				interrupts = <0 40 0x04>;
@@ -821,7 +837,7 @@
 				status = "disabled";
 			};
 
-			usb@02184400 { /* USB2 */
+			usbh2: usb@02184400 {
 				compatible = "fsl,imx6q-usb", "fsl,imx27-usb";
 				reg = <0x02184400 0x200>;
 				interrupts = <0 41 0x04>;
@@ -830,7 +846,7 @@
 				status = "disabled";
 			};
 
-			usb@02184600 { /* USB3 */
+			usbh3: usb@02184600 {
 				compatible = "fsl,imx6q-usb", "fsl,imx27-usb";
 				reg = <0x02184600 0x200>;
 				interrupts = <0 42 0x04>;
@@ -839,14 +855,14 @@
 				status = "disabled";
 			};
 
-			usbmisc: usbmisc@02184800 {
+			usbmisc: usbmisc: usbmisc@02184800 {
 				#index-cells = <1>;
 				compatible = "fsl,imx6q-usbmisc";
 				reg = <0x02184800 0x200>;
 				clocks = <&clks 162>;
 			};
 
-			ethernet@02188000 {
+			fec: ethernet@02188000 {
 				compatible = "fsl,imx6q-fec";
 				reg = <0x02188000 0x4000>;
 				interrupts = <0 118 0x04 0 119 0x04>;
@@ -860,43 +876,47 @@
 				interrupts = <0 53 0x04 0 117 0x04 0 126 0x04>;
 			};
 
-			usdhc@02190000 { /* uSDHC1 */
+			usdhc1: usdhc@02190000 {
 				compatible = "fsl,imx6q-usdhc";
 				reg = <0x02190000 0x4000>;
 				interrupts = <0 22 0x04>;
 				clocks = <&clks 163>, <&clks 163>, <&clks 163>;
 				clock-names = "ipg", "ahb", "per";
+				bus-width = <4>;
 				status = "disabled";
 			};
 
-			usdhc@02194000 { /* uSDHC2 */
+			usdhc2: usdhc@02194000 {
 				compatible = "fsl,imx6q-usdhc";
 				reg = <0x02194000 0x4000>;
 				interrupts = <0 23 0x04>;
 				clocks = <&clks 164>, <&clks 164>, <&clks 164>;
 				clock-names = "ipg", "ahb", "per";
+				bus-width = <4>;
 				status = "disabled";
 			};
 
-			usdhc@02198000 { /* uSDHC3 */
+			usdhc3: usdhc@02198000 {
 				compatible = "fsl,imx6q-usdhc";
 				reg = <0x02198000 0x4000>;
 				interrupts = <0 24 0x04>;
 				clocks = <&clks 165>, <&clks 165>, <&clks 165>;
 				clock-names = "ipg", "ahb", "per";
+				bus-width = <4>;
 				status = "disabled";
 			};
 
-			usdhc@0219c000 { /* uSDHC4 */
+			usdhc4: usdhc@0219c000 {
 				compatible = "fsl,imx6q-usdhc";
 				reg = <0x0219c000 0x4000>;
 				interrupts = <0 25 0x04>;
 				clocks = <&clks 166>, <&clks 166>, <&clks 166>;
 				clock-names = "ipg", "ahb", "per";
+				bus-width = <4>;
 				status = "disabled";
 			};
 
-			i2c@021a0000 { /* I2C1 */
+			i2c1: i2c@021a0000 {
 				#address-cells = <1>;
 				#size-cells = <0>;
 				compatible = "fsl,imx6q-i2c", "fsl,imx21-i2c";
@@ -906,7 +926,7 @@
 				status = "disabled";
 			};
 
-			i2c@021a4000 { /* I2C2 */
+			i2c2: i2c@021a4000 {
 				#address-cells = <1>;
 				#size-cells = <0>;
 				compatible = "fsl,imx6q-i2c", "fsl,imx21-i2c";
@@ -916,7 +936,7 @@
 				status = "disabled";
 			};
 
-			i2c@021a8000 { /* I2C3 */
+			i2c3: i2c@021a8000 {
 				#address-cells = <1>;
 				#size-cells = <0>;
 				compatible = "fsl,imx6q-i2c", "fsl,imx21-i2c";
@@ -930,12 +950,12 @@
 				reg = <0x021ac000 0x4000>;
 			};
 
-			mmdc@021b0000 { /* MMDC0 */
+			mmdc0: mmdc@021b0000 { /* MMDC0 */
 				compatible = "fsl,imx6q-mmdc";
 				reg = <0x021b0000 0x4000>;
 			};
 
-			mmdc@021b4000 { /* MMDC1 */
+			mmdc1: mmdc@021b4000 { /* MMDC1 */
 				reg = <0x021b4000 0x4000>;
 			};
 
@@ -963,7 +983,7 @@
 				interrupts = <0 109 0x04>;
 			};
 
-			audmux@021d8000 {
+			audmux: audmux@021d8000 {
 				compatible = "fsl,imx6q-audmux", "fsl,imx31-audmux";
 				reg = <0x021d8000 0x4000>;
 				status = "disabled";
diff --git a/arch/arm/boot/dts/kirkwood-6281.dtsi b/arch/arm/boot/dts/kirkwood-6281.dtsi
new file mode 100644
index 0000000..d6c9d65
--- /dev/null
+++ b/arch/arm/boot/dts/kirkwood-6281.dtsi
@@ -0,0 +1,44 @@
+/ {
+	ocp@f1000000 {
+		pinctrl: pinctrl@10000 {
+			compatible = "marvell,88f6281-pinctrl";
+			reg = <0x10000 0x20>;
+
+			pmx_nand: pmx-nand {
+				marvell,pins = "mpp0", "mpp1", "mpp2", "mpp3",
+					       "mpp4", "mpp5", "mpp18",
+					       "mpp19";
+				marvell,function = "nand";
+			};
+			pmx_sata0: pmx-sata0 {
+				marvell,pins = "mpp5", "mpp21", "mpp23";
+				marvell,function = "sata0";
+			};
+			pmx_sata1: pmx-sata1 {
+				marvell,pins = "mpp4", "mpp20", "mpp22";
+				marvell,function = "sata1";
+			};
+			pmx_spi: pmx-spi {
+				marvell,pins = "mpp0", "mpp1", "mpp2", "mpp3";
+				marvell,function = "spi";
+			};
+			pmx_twsi0: pmx-twsi0 {
+				marvell,pins = "mpp8", "mpp9";
+				marvell,function = "twsi0";
+			};
+			pmx_uart0: pmx-uart0 {
+				marvell,pins = "mpp10", "mpp11";
+				marvell,function = "uart0";
+			};
+			pmx_uart1: pmx-uart1 {
+				marvell,pins = "mpp13", "mpp14";
+				marvell,function = "uart1";
+			};
+			pmx_sdio: pmx-sdio {
+				marvell,pins = "mpp12", "mpp13", "mpp14",
+					       "mpp15", "mpp16", "mpp17";
+				marvell,function = "sdio";
+			};
+		};
+	};
+};
diff --git a/arch/arm/boot/dts/kirkwood-6282.dtsi b/arch/arm/boot/dts/kirkwood-6282.dtsi
new file mode 100644
index 0000000..9ae2004
--- /dev/null
+++ b/arch/arm/boot/dts/kirkwood-6282.dtsi
@@ -0,0 +1,45 @@
+/ {
+	ocp@f1000000 {
+
+		pinctrl: pinctrl@10000 {
+			compatible = "marvell,88f6282-pinctrl";
+			reg = <0x10000 0x20>;
+
+			pmx_sata0: pmx-sata0 {
+				marvell,pins = "mpp5", "mpp21", "mpp23";
+				marvell,function = "sata0";
+			};
+			pmx_sata1: pmx-sata1 {
+				marvell,pins = "mpp4", "mpp20", "mpp22";
+				marvell,function = "sata1";
+			};
+			pmx_spi: pmx-spi {
+				marvell,pins = "mpp0", "mpp1", "mpp2", "mpp3";
+				marvell,function = "spi";
+			};
+			pmx_twsi0: pmx-twsi0 {
+				marvell,pins = "mpp8", "mpp9";
+				marvell,function = "twsi0";
+			};
+			pmx_uart0: pmx-uart0 {
+				marvell,pins = "mpp10", "mpp11";
+				marvell,function = "uart0";
+			};
+
+			pmx_uart1: pmx-uart1 {
+				marvell,pins = "mpp13", "mpp14";
+				marvell,function = "uart1";
+			};
+		};
+
+		i2c@11100 {
+			compatible = "marvell,mv64xxx-i2c";
+			reg = <0x11100 0x20>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			interrupts = <32>;
+			clock-frequency = <100000>;
+			status = "disabled";
+		};
+	};
+};
diff --git a/arch/arm/boot/dts/kirkwood-98dx4122.dtsi b/arch/arm/boot/dts/kirkwood-98dx4122.dtsi
new file mode 100644
index 0000000..3271e4c
--- /dev/null
+++ b/arch/arm/boot/dts/kirkwood-98dx4122.dtsi
@@ -0,0 +1,31 @@
+/ {
+	ocp@f1000000 {
+		pinctrl: pinctrl@10000 {
+			compatible = "marvell,98dx4122-pinctrl";
+			reg = <0x10000 0x20>;
+
+			pmx_nand: pmx-nand {
+				marvell,pins = "mpp0", "mpp1", "mpp2", "mpp3",
+					       "mpp4", "mpp5", "mpp18",
+					       "mpp19";
+				marvell,function = "nand";
+			};
+			pmx_spi: pmx-spi {
+				marvell,pins = "mpp0", "mpp1", "mpp2", "mpp3";
+				marvell,function = "spi";
+			};
+			pmx_twsi0: pmx-twsi0 {
+				marvell,pins = "mpp8", "mpp9";
+				marvell,function = "twsi0";
+			};
+			pmx_uart0: pmx-uart0 {
+				marvell,pins = "mpp10", "mpp11";
+				marvell,function = "uart0";
+			};
+			pmx_uart1: pmx-uart1 {
+				marvell,pins = "mpp13", "mpp14";
+				marvell,function = "uart1";
+			};
+		};
+	};
+};
diff --git a/arch/arm/boot/dts/kirkwood-dnskw.dtsi b/arch/arm/boot/dts/kirkwood-dnskw.dtsi
index 9b32d02..6875ac0 100644
--- a/arch/arm/boot/dts/kirkwood-dnskw.dtsi
+++ b/arch/arm/boot/dts/kirkwood-dnskw.dtsi
@@ -1,4 +1,5 @@
 /include/ "kirkwood.dtsi"
+/include/ "kirkwood-6281.dtsi"
 
 / {
 	model = "D-Link DNS NASes (kirkwood-based)";
@@ -35,7 +36,116 @@
 				      6000 2>;
 	};
 
+	gpio_poweroff {
+		compatible = "gpio-poweroff";
+		gpios = <&gpio1 4 0>;
+	};
+
 	ocp@f1000000 {
+		pinctrl: pinctrl@10000 {
+
+			pinctrl-0 = < &pmx_nand &pmx_uart1
+				      &pmx_sata0 &pmx_sata1
+				      &pmx_led_power
+				      &pmx_led_red_right_hdd
+				      &pmx_led_red_left_hdd
+				      &pmx_led_red_usb_325
+				      &pmx_button_power
+				      &pmx_led_red_usb_320
+				      &pmx_power_off &pmx_power_back_on
+				      &pmx_power_sata0 &pmx_power_sata1
+				      &pmx_present_sata0 &pmx_present_sata1
+				      &pmx_led_white_usb &pmx_fan_tacho
+				      &pmx_fan_high_speed &pmx_fan_low_speed
+				      &pmx_button_unmount &pmx_button_reset
+				      &pmx_temp_alarm >;
+			pinctrl-names = "default";
+
+			pmx_sata0: pmx-sata0 {
+				marvell,pins = "mpp20";
+				marvell,function = "sata1";
+			};
+			pmx_sata1: pmx-sata1 {
+				marvell,pins = "mpp21";
+				marvell,function = "sata0";
+			};
+			pmx_led_power: pmx-led-power {
+				marvell,pins = "mpp26";
+				marvell,function = "gpio";
+			};
+			pmx_led_red_right_hdd: pmx-led-red-right-hdd {
+				marvell,pins = "mpp27";
+				marvell,function = "gpio";
+			};
+			pmx_led_red_left_hdd: pmx-led-red-left-hdd {
+				marvell,pins = "mpp28";
+				marvell,function = "gpio";
+			};
+			pmx_led_red_usb_325: pmx-led-red-usb-325 {
+				marvell,pins = "mpp29";
+				marvell,function = "gpio";
+			};
+			pmx_button_power: pmx-button-power {
+				marvell,pins = "mpp34";
+				marvell,function = "gpio";
+			};
+			pmx_led_red_usb_320: pmx-led-red-usb-320 {
+				marvell,pins = "mpp35";
+				marvell,function = "gpio";
+			};
+			pmx_power_off: pmx-power-off {
+				marvell,pins = "mpp36";
+				marvell,function = "gpio";
+			};
+			pmx_power_back_on: pmx-power-back-on {
+				marvell,pins = "mpp37";
+				marvell,function = "gpio";
+			};
+			pmx_power_sata0: pmx-power-sata0 {
+				marvell,pins = "mpp39";
+				marvell,function = "gpio";
+			};
+			pmx_power_sata1: pmx-power-sata1 {
+				marvell,pins = "mpp40";
+				marvell,function = "gpio";
+			};
+			pmx_present_sata0: pmx-present-sata0 {
+				marvell,pins = "mpp41";
+				marvell,function = "gpio";
+			};
+			pmx_present_sata1: pmx-present-sata1 {
+				marvell,pins = "mpp42";
+				marvell,function = "gpio";
+			};
+			pmx_led_white_usb: pmx-led-white-usb {
+				marvell,pins = "mpp43";
+				marvell,function = "gpio";
+			};
+			pmx_fan_tacho: pmx-fan-tacho {
+				marvell,pins = "mpp44";
+				marvell,function = "gpio";
+			};
+			pmx_fan_high_speed: pmx-fan-high-speed {
+				marvell,pins = "mpp45";
+				marvell,function = "gpio";
+			};
+			pmx_fan_low_speed: pmx-fan-low-speed {
+				marvell,pins = "mpp46";
+				marvell,function = "gpio";
+			};
+			pmx_button_unmount: pmx-button-unmount {
+				marvell,pins = "mpp47";
+				marvell,function = "gpio";
+			};
+			pmx_button_reset: pmx-button-reset {
+				marvell,pins = "mpp48";
+				marvell,function = "gpio";
+			};
+			pmx_temp_alarm: pmx-temp-alarm {
+				marvell,pins = "mpp49";
+				marvell,function = "gpio";
+			};
+		};
 		sata@80000 {
 			status = "okay";
 			nr-ports = <2>;
@@ -43,6 +153,7 @@
 
 		nand@3000000 {
 			status = "okay";
+			chip-delay = <35>;
 
 			partition@0 {
 				label = "u-boot";
@@ -76,4 +187,33 @@
 			};
 		};
 	};
+
+	regulators {
+		compatible = "simple-bus";
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		sata0_power: regulator@1 {
+			compatible = "regulator-fixed";
+			reg = <1>;
+			regulator-name = "SATA0 Power";
+			regulator-min-microvolt = <5000000>;
+			regulator-max-microvolt = <5000000>;
+			enable-active-high;
+			regulator-always-on;
+			regulator-boot-on;
+			gpio = <&gpio1 7 0>;
+		};
+		sata1_power: regulator@2 {
+			compatible = "regulator-fixed";
+			reg = <2>;
+			regulator-name = "SATA1 Power";
+			regulator-min-microvolt = <5000000>;
+			regulator-max-microvolt = <5000000>;
+			enable-active-high;
+			regulator-always-on;
+			regulator-boot-on;
+			gpio = <&gpio1 8 0>;
+		};
+	};
 };
diff --git a/arch/arm/boot/dts/kirkwood-dockstar.dts b/arch/arm/boot/dts/kirkwood-dockstar.dts
index 08a5824..2e3dd34 100644
--- a/arch/arm/boot/dts/kirkwood-dockstar.dts
+++ b/arch/arm/boot/dts/kirkwood-dockstar.dts
@@ -1,6 +1,7 @@
 /dts-v1/;
 
 /include/ "kirkwood.dtsi"
+/include/ "kirkwood-6281.dtsi"
 
 / {
 	model = "Seagate FreeAgent Dockstar";
@@ -16,6 +17,25 @@
 	};
 
 	ocp@f1000000 {
+		pinctrl: pinctrl@10000 {
+
+			pinctrl-0 = < &pmx_usb_power_enable
+				      &pmx_led_green &pmx_led_orange >;
+			pinctrl-names = "default";
+
+			pmx_usb_power_enable: pmx-usb-power-enable {
+				marvell,pins = "mpp29";
+				marvell,function = "gpio";
+			};
+			pmx_led_green: pmx-led-green {
+				marvell,pins = "mpp46";
+				marvell,function = "gpio";
+			};
+			pmx_led_orange: pmx-led-orange {
+				marvell,pins = "mpp47";
+				marvell,function = "gpio";
+			};
+		};
 		serial@12000 {
 			clock-frequency = <200000000>;
 			status = "ok";
@@ -54,4 +74,21 @@
 			gpios = <&gpio1 15 1>;
 		};
 	};
+	regulators {
+		compatible = "simple-bus";
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		usb_power: regulator@1 {
+			compatible = "regulator-fixed";
+			reg = <1>;
+			regulator-name = "USB Power";
+			regulator-min-microvolt = <5000000>;
+			regulator-max-microvolt = <5000000>;
+			enable-active-high;
+			regulator-always-on;
+			regulator-boot-on;
+			gpio = <&gpio0 29 0>;
+		};
+	};
 };
diff --git a/arch/arm/boot/dts/kirkwood-dreamplug.dts b/arch/arm/boot/dts/kirkwood-dreamplug.dts
index 26e281f..f2d386c 100644
--- a/arch/arm/boot/dts/kirkwood-dreamplug.dts
+++ b/arch/arm/boot/dts/kirkwood-dreamplug.dts
@@ -1,6 +1,7 @@
 /dts-v1/;
 
 /include/ "kirkwood.dtsi"
+/include/ "kirkwood-6281.dtsi"
 
 / {
 	model = "Globalscale Technologies Dreamplug";
@@ -16,6 +17,26 @@
 	};
 
 	ocp@f1000000 {
+		pinctrl: pinctrl@10000 {
+
+			pinctrl-0 = < &pmx_spi
+				      &pmx_led_bluetooth &pmx_led_wifi
+				      &pmx_led_wifi_ap >;
+			pinctrl-names = "default";
+
+			pmx_led_bluetooth: pmx-led-bluetooth {
+				marvell,pins = "mpp47";
+				marvell,function = "gpio";
+			};
+			pmx_led_wifi: pmx-led-wifi {
+				marvell,pins = "mpp48";
+				marvell,function = "gpio";
+			};
+			pmx_led_wifi_ap: pmx-led-wifi-ap {
+				marvell,pins = "mpp49";
+				marvell,function = "gpio";
+			};
+		};
 		serial@12000 {
 			clock-frequency = <200000000>;
 			status = "ok";
diff --git a/arch/arm/boot/dts/kirkwood-goflexnet.dts b/arch/arm/boot/dts/kirkwood-goflexnet.dts
index 7c8238f..1b133e0 100644
--- a/arch/arm/boot/dts/kirkwood-goflexnet.dts
+++ b/arch/arm/boot/dts/kirkwood-goflexnet.dts
@@ -1,6 +1,7 @@
 /dts-v1/;
 
 /include/ "kirkwood.dtsi"
+/include/ "kirkwood-6281.dtsi"
 
 / {
 	model = "Seagate GoFlex Net";
@@ -16,6 +17,61 @@
 	};
 
 	ocp@f1000000 {
+		pinctrl: pinctrl@10000 {
+
+			pinctrl-0 = < &pmx_usb_power_enable &pmx_led_orange
+				      &pmx_led_left_cap_0 &pmx_led_left_cap_1
+				      &pmx_led_left_cap_2 &pmx_led_left_cap_3
+				      &pmx_led_right_cap_0 &pmx_led_right_cap_1
+				      &pmx_led_right_cap_2 &pmx_led_right_cap_3
+				    >;
+			pinctrl-names = "default";
+
+			pmx_usb_power_enable: pmx-usb-power-enable {
+				marvell,pins = "mpp29";
+				marvell,function = "gpio";
+			};
+			pmx_led_right_cap_0: pmx-led_right_cap_0 {
+				marvell,pins = "mpp38";
+				marvell,function = "gpio";
+			};
+			pmx_led_right_cap_1: pmx-led_right_cap_1 {
+				marvell,pins = "mpp39";
+				marvell,function = "gpio";
+			};
+			pmx_led_right_cap_2: pmx-led_right_cap_2 {
+				marvell,pins = "mpp40";
+				marvell,function = "gpio";
+			};
+			pmx_led_right_cap_3: pmx-led_right_cap_3 {
+				marvell,pins = "mpp41";
+				marvell,function = "gpio";
+			};
+			pmx_led_left_cap_0: pmx-led_left_cap_0 {
+				marvell,pins = "mpp42";
+				marvell,function = "gpio";
+			};
+			pmx_led_left_cap_1: pmx-led_left_cap_1 {
+				marvell,pins = "mpp43";
+				marvell,function = "gpio";
+			};
+			pmx_led_left_cap_2: pmx-led_left_cap_2 {
+				marvell,pins = "mpp44";
+				marvell,function = "gpio";
+			};
+			pmx_led_left_cap_3: pmx-led_left_cap_3 {
+				marvell,pins = "mpp45";
+				marvell,function = "gpio";
+			};
+			pmx_led_green: pmx-led_green {
+				marvell,pins = "mpp46";
+				marvell,function = "gpio";
+			};
+			pmx_led_orange: pmx-led_orange {
+				marvell,pins = "mpp47";
+				marvell,function = "gpio";
+			};
+		};
 		serial@12000 {
 			clock-frequency = <200000000>;
 			status = "ok";
@@ -96,4 +152,21 @@
 			gpios = <&gpio1 9 0>;
 		};
 	};
+	regulators {
+		compatible = "simple-bus";
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		usb_power: regulator@1 {
+			compatible = "regulator-fixed";
+			reg = <1>;
+			regulator-name = "USB Power";
+			regulator-min-microvolt = <5000000>;
+			regulator-max-microvolt = <5000000>;
+			enable-active-high;
+			regulator-always-on;
+			regulator-boot-on;
+			gpio = <&gpio0 29 0>;
+		};
+	};
 };
diff --git a/arch/arm/boot/dts/kirkwood-ib62x0.dts b/arch/arm/boot/dts/kirkwood-ib62x0.dts
index 66794ed..71902da 100644
--- a/arch/arm/boot/dts/kirkwood-ib62x0.dts
+++ b/arch/arm/boot/dts/kirkwood-ib62x0.dts
@@ -1,6 +1,7 @@
 /dts-v1/;
 
 /include/ "kirkwood.dtsi"
+/include/ "kirkwood-6281.dtsi"
 
 / {
 	model = "RaidSonic ICY BOX IB-NAS62x0 (Rev B)";
@@ -16,6 +17,39 @@
 	};
 
 	ocp@f1000000 {
+		pinctrl: pinctrl@10000 {
+
+			pinctrl-0 = < &pmx_nand
+				      &pmx_led_os_red &pmx_power_off
+				      &pmx_led_os_green &pmx_led_usb_transfer
+				      &pmx_button_reset &pmx_button_usb_copy >;
+			pinctrl-names = "default";
+
+			pmx_led_os_red: pmx-led-os-red {
+				marvell,pins = "mpp22";
+				marvell,function = "gpio";
+			};
+			pmx_power_off: pmx-power-off {
+				marvell,pins = "mpp24";
+				marvell,function = "gpio";
+			};
+			pmx_led_os_green: pmx-led-os-green {
+				marvell,pins = "mpp25";
+				marvell,function = "gpio";
+			};
+			pmx_led_usb_transfer: pmx-led-usb-transfer {
+				marvell,pins = "mpp27";
+				marvell,function = "gpio";
+			};
+			pmx_button_reset: pmx-button-reset {
+				marvell,pins = "mpp28";
+				marvell,function = "gpio";
+			};
+			pmx_button_usb_copy: pmx-button-usb-copy {
+				marvell,pins = "mpp29";
+				marvell,function = "gpio";
+			};
+		};
 		serial@12000 {
 			clock-frequency = <200000000>;
 			status = "okay";
@@ -79,4 +113,10 @@
 			gpios = <&gpio0 27 0>;
 		};
 	};
+	gpio_poweroff {
+		compatible = "gpio-poweroff";
+		gpios = <&gpio0 24 0>;
+	};
+
+
 };
diff --git a/arch/arm/boot/dts/kirkwood-iconnect.dts b/arch/arm/boot/dts/kirkwood-iconnect.dts
index d97cd9d..504f16b 100644
--- a/arch/arm/boot/dts/kirkwood-iconnect.dts
+++ b/arch/arm/boot/dts/kirkwood-iconnect.dts
@@ -1,6 +1,7 @@
 /dts-v1/;
 
 /include/ "kirkwood.dtsi"
+/include/ "kirkwood-6281.dtsi"
 
 / {
 	model = "Iomega Iconnect";
@@ -18,6 +19,56 @@
 	};
 
 	ocp@f1000000 {
+		pinctrl: pinctrl@10000 {
+
+			pinctrl-0 = < &pmx_gpio_12 &pmx_gpio_35
+				      &pmx_gpio_41 &pmx_gpio_42
+				      &pmx_gpio_43 &pmx_gpio_44
+				      &pmx_gpio_45 &pmx_gpio_46
+				      &pmx_gpio_47 &pmx_gpio_48 >;
+			pinctrl-names = "default";
+
+			pmx_gpio_12: pmx-gpio-12 {
+				marvell,pins = "mpp12";
+				marvell,function = "gpio";
+			};
+			pmx_gpio_35: pmx-gpio-35 {
+				marvell,pins = "mpp35";
+				marvell,function = "gpio";
+			};
+			pmx_gpio_41: pmx-gpio-41 {
+				marvell,pins = "mpp41";
+				marvell,function = "gpio";
+			};
+			pmx_gpio_42: pmx-gpio-42 {
+				marvell,pins = "mpp42";
+				marvell,function = "gpio";
+			};
+			pmx_gpio_43: pmx-gpio-43 {
+				marvell,pins = "mpp43";
+				marvell,function = "gpio";
+			};
+			pmx_gpio_44: pmx-gpio-44 {
+				marvell,pins = "mpp44";
+				marvell,function = "gpio";
+			};
+			pmx_gpio_45: pmx-gpio-45 {
+				marvell,pins = "mpp45";
+				marvell,function = "gpio";
+			};
+			pmx_gpio_46: pmx-gpio-46 {
+				marvell,pins = "mpp46";
+				marvell,function = "gpio";
+			};
+			pmx_gpio_47: pmx-gpio-47 {
+				marvell,pins = "mpp47";
+				marvell,function = "gpio";
+			};
+			pmx_gpio_48: pmx-gpio-48 {
+				marvell,pins = "mpp48";
+				marvell,function = "gpio";
+			};
+		};
 		i2c@11000 {
 			status = "okay";
 
diff --git a/arch/arm/boot/dts/kirkwood-iomega_ix2_200.dts b/arch/arm/boot/dts/kirkwood-iomega_ix2_200.dts
index 865aeec..6cae459 100644
--- a/arch/arm/boot/dts/kirkwood-iomega_ix2_200.dts
+++ b/arch/arm/boot/dts/kirkwood-iomega_ix2_200.dts
@@ -1,6 +1,7 @@
 /dts-v1/;
 
 /include/ "kirkwood.dtsi"
+/include/ "kirkwood-6281.dtsi"
 
 / {
 	model = "Iomega StorCenter ix2-200";
@@ -16,6 +17,94 @@
 	};
 
 	ocp@f1000000 {
+		pinctrl: pinctrl@10000 {
+
+			pinctrl-0 = < &pmx_button_reset &pmx_button_power
+				      &pmx_led_backup &pmx_led_power
+				      &pmx_button_otb &pmx_led_rebuild
+				      &pmx_led_health
+				      &pmx_led_sata_brt_ctrl_1
+				      &pmx_led_sata_brt_ctrl_2
+				      &pmx_led_backup_brt_ctrl_1
+				      &pmx_led_backup_brt_ctrl_2
+				      &pmx_led_power_brt_ctrl_1
+				      &pmx_led_power_brt_ctrl_2
+				      &pmx_led_health_brt_ctrl_1
+				      &pmx_led_health_brt_ctrl_2
+				      &pmx_led_rebuild_brt_ctrl_1
+				      &pmx_led_rebuild_brt_ctrl_2 >;
+			pinctrl-names = "default";
+
+			pmx_button_reset: pmx-button-reset {
+				marvell,pins = "mpp12";
+				marvell,function = "gpio";
+			};
+			pmx_button_power: pmx-button-power {
+				marvell,pins = "mpp14";
+				marvell,function = "gpio";
+			};
+			pmx_led_backup: pmx-led-backup {
+				marvell,pins = "mpp15";
+				marvell,function = "gpio";
+			};
+			pmx_led_power: pmx-led-power {
+				marvell,pins = "mpp16";
+				marvell,function = "gpio";
+			};
+			pmx_button_otb: pmx-button-otb {
+				marvell,pins = "mpp35";
+				marvell,function = "gpio";
+			};
+			pmx_led_rebuild: pmx-led-rebuild {
+				marvell,pins = "mpp36";
+				marvell,function = "gpio";
+			};
+			pmx_led_health: pmx-led_health {
+				marvell,pins = "mpp37";
+				marvell,function = "gpio";
+			};
+			pmx_led_sata_brt_ctrl_1: pmx-led-sata-brt-ctrl-1 {
+				marvell,pins = "mpp38";
+				marvell,function = "gpio";
+			};
+			pmx_led_sata_brt_ctrl_2: pmx-led-sata-brt-ctrl-2 {
+				marvell,pins = "mpp39";
+				marvell,function = "gpio";
+			};
+			pmx_led_backup_brt_ctrl_1: pmx-led-backup-brt-ctrl-1 {
+				marvell,pins = "mpp40";
+				marvell,function = "gpio";
+			};
+			pmx_led_backup_brt_ctrl_2: pmx-led-backup-brt-ctrl-2 {
+				marvell,pins = "mpp41";
+				marvell,function = "gpio";
+			};
+			pmx_led_power_brt_ctrl_1: pmx-led-power-brt-ctrl-1 {
+				marvell,pins = "mpp42";
+				marvell,function = "gpio";
+			};
+			pmx_led_power_brt_ctrl_2: pmx-led-power-brt-ctrl-2 {
+				marvell,pins = "mpp43";
+				marvell,function = "gpio";
+			};
+			pmx_led_health_brt_ctrl_1: pmx-led-health-brt-ctrl-1 {
+				marvell,pins = "mpp44";
+				marvell,function = "gpio";
+			};
+			pmx_led_health_brt_ctrl_2: pmx-led-health-brt-ctrl-2 {
+				marvell,pins = "mpp45";
+				marvell,function = "gpio";
+			};
+			pmx_led_rebuild_brt_ctrl_1: pmx-led-rebuild-brt-ctrl-1 {
+				marvell,pins = "mpp44";
+				marvell,function = "gpio";
+			};
+			pmx_led_rebuild_brt_ctrl_2: pmx-led-rebuild-brt-ctrl-2 {
+				marvell,pins = "mpp45";
+				marvell,function = "gpio";
+			};
+
+		};
 		i2c@11000 {
 			status = "okay";
 
diff --git a/arch/arm/boot/dts/kirkwood-km_kirkwood.dts b/arch/arm/boot/dts/kirkwood-km_kirkwood.dts
index 75bdb93..8db3123 100644
--- a/arch/arm/boot/dts/kirkwood-km_kirkwood.dts
+++ b/arch/arm/boot/dts/kirkwood-km_kirkwood.dts
@@ -1,6 +1,7 @@
 /dts-v1/;
 
 /include/ "kirkwood.dtsi"
+/include/ "kirkwood-98dx4122.dtsi"
 
 / {
 	model = "Keymile Kirkwood Reference Design";
@@ -16,6 +17,22 @@
 	};
 
 	ocp@f1000000 {
+		pinctrl: pinctrl@10000 {
+
+			pinctrl-0 = < &pmx_nand &pmx_i2c_gpio_sda
+				&pmx_i2c_gpio_scl >;
+			pinctrl-names = "default";
+
+			pmx_i2c_gpio_sda: pmx-gpio-sda {
+				marvell,pins = "mpp8";
+				marvell,function = "gpio";
+			};
+			pmx_i2c_gpio_scl: pmx-gpio-scl {
+				marvell,pins = "mpp9";
+				marvell,function = "gpio";
+			};
+		};
+
 		serial@12000 {
 			clock-frequency = <200000000>;
 			status = "ok";
diff --git a/arch/arm/boot/dts/kirkwood-lsxl.dtsi b/arch/arm/boot/dts/kirkwood-lsxl.dtsi
index 798e60e..37d45c4 100644
--- a/arch/arm/boot/dts/kirkwood-lsxl.dtsi
+++ b/arch/arm/boot/dts/kirkwood-lsxl.dtsi
@@ -1,4 +1,5 @@
 /include/ "kirkwood.dtsi"
+/include/ "kirkwood-6281.dtsi"
 
 / {
 	chosen {
@@ -6,6 +7,71 @@
 	};
 
 	ocp@f1000000 {
+		pinctrl: pinctrl@10000 {
+
+			pinctrl-0 = < &pmx_power_hdd &pmx_usb_vbus
+				      &pmx_fan_low &pmx_fan_high
+				      &pmx_led_function_red &pmx_led_alarm
+				      &pmx_led_info &pmx_led_power
+				      &pmx_fan_lock &pmx_button_function
+				      &pmx_power_switch &pmx_power_auto_switch
+				      &pmx_led_function_blue >;
+			pinctrl-names = "default";
+
+			pmx_power_hdd: pmx-power-hdd {
+				marvell,pins = "mpp10";
+				marvell,function = "gpo";
+			};
+			pmx_usb_vbus: pmx-usb-vbus {
+				marvell,pins = "mpp11";
+				marvell,function = "gpio";
+			};
+			pmx_fan_high: pmx-fan-high {
+				marvell,pins = "mpp18";
+				marvell,function = "gpo";
+			};
+			pmx_fan_low: pmx-fan-low {
+				marvell,pins = "mpp19";
+				marvell,function = "gpo";
+			};
+			pmx_led_function_blue: pmx-led-function-blue {
+				marvell,pins = "mpp36";
+				marvell,function = "gpio";
+			};
+			pmx_led_alarm: pmx-led-alarm {
+				marvell,pins = "mpp37";
+				marvell,function = "gpio";
+			};
+			pmx_led_info: pmx-led-info {
+				marvell,pins = "mpp38";
+				marvell,function = "gpio";
+			};
+			pmx_led_power: pmx-led-power {
+				marvell,pins = "mpp39";
+				marvell,function = "gpio";
+			};
+			pmx_fan_lock: pmx-fan-lock {
+				marvell,pins = "mpp40";
+				marvell,function = "gpio";
+			};
+			pmx_button_function: pmx-button-function {
+				marvell,pins = "mpp41";
+				marvell,function = "gpio";
+			};
+			pmx_power_switch: pmx-power-switch {
+				marvell,pins = "mpp42";
+				marvell,function = "gpio";
+			};
+			pmx_power_auto_switch: pmx-power-auto-switch {
+				marvell,pins = "mpp43";
+				marvell,function = "gpio";
+			};
+			pmx_led_function_red: pmx-led-function_red {
+				marvell,pins = "mpp48";
+				marvell,function = "gpio";
+			};
+
+		};
 		sata@80000 {
 			status = "okay";
 			nr-ports = <1>;
@@ -105,4 +171,33 @@
 		                      5000 0>;
 		alarm-gpios = <&gpio1 8 0>;
 	};
+
+	regulators {
+		compatible = "simple-bus";
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		usb_power: regulator@1 {
+			compatible = "regulator-fixed";
+			reg = <1>;
+			regulator-name = "USB Power";
+			regulator-min-microvolt = <5000000>;
+			regulator-max-microvolt = <5000000>;
+			enable-active-high;
+			regulator-always-on;
+			regulator-boot-on;
+			gpio = <&gpio0 11 0>;
+		};
+		hdd_power: regulator@2 {
+			compatible = "regulator-fixed";
+			reg = <2>;
+			regulator-name = "HDD Power";
+			regulator-min-microvolt = <5000000>;
+			regulator-max-microvolt = <5000000>;
+			enable-active-high;
+			regulator-always-on;
+			regulator-boot-on;
+			gpio = <&gpio0 10 0>;
+		};
+	};
 };
diff --git a/arch/arm/boot/dts/kirkwood-mplcec4.dts b/arch/arm/boot/dts/kirkwood-mplcec4.dts
index ac3c080..262c654 100644
--- a/arch/arm/boot/dts/kirkwood-mplcec4.dts
+++ b/arch/arm/boot/dts/kirkwood-mplcec4.dts
@@ -1,6 +1,7 @@
 /dts-v1/;
 
 /include/ "kirkwood.dtsi"
+/include/ "kirkwood-6281.dtsi"
 
 / {
 	model = "MPL CEC4";
@@ -16,6 +17,64 @@
         };
 
 	ocp@f1000000 {
+		pinctrl: pinctrl@10000 {
+
+			pinctrl-0 = < &pmx_nand &pmx_uart0
+				      &pmx_led_health &pmx_sdio
+				      &pmx_sata0 &pmx_sata1
+				      &pmx_led_user1o
+				      &pmx_led_user1g &pmx_led_user0o
+				      &pmx_led_user0g &pmx_led_misc
+				      &pmx_sdio_cd
+				    >;
+			pinctrl-names = "default";
+
+			pmx_led_health: pmx-led-health {
+				marvell,pins = "mpp7";
+				marvell,function = "gpo";
+			};
+
+			pmx_sata1: pmx-sata1 {
+				marvell,pins = "mpp34";
+				marvell,function = "sata1";
+			};
+
+			pmx_sata0: pmx-sata0 {
+				marvell,pins = "mpp35";
+				marvell,function = "sata0";
+			};
+
+			pmx_led_user1o: pmx-led-user1o {
+				marvell,pins = "mpp40";
+				marvell,function = "gpio";
+			};
+
+			pmx_led_user1g: pmx-led-user1g {
+				marvell,pins = "mpp41";
+				marvell,function = "gpio";
+			};
+
+			pmx_led_user0o: pmx-led-user0o {
+				marvell,pins = "mpp44";
+				marvell,function = "gpio";
+			};
+
+			pmx_led_user0g: pmx-led-user0g {
+				marvell,pins = "mpp45";
+				marvell,function = "gpio";
+			};
+
+			pmx_led_misc: pmx-led-misc {
+				marvell,pins = "mpp46";
+				marvell,function = "gpio";
+			};
+
+			pmx_sdio_cd: pmx-sdio-cd {
+				marvell,pins = "mpp47";
+				marvell,function = "gpio";
+			};
+		};
+
                 i2c@11000 {
                         status = "okay";
 
diff --git a/arch/arm/boot/dts/kirkwood-openblocks_a6.dts b/arch/arm/boot/dts/kirkwood-openblocks_a6.dts
index 9a2606c..49d3d74 100644
--- a/arch/arm/boot/dts/kirkwood-openblocks_a6.dts
+++ b/arch/arm/boot/dts/kirkwood-openblocks_a6.dts
@@ -1,6 +1,7 @@
 /dts-v1/;
 
 /include/ "kirkwood.dtsi"
+/include/ "kirkwood-6282.dtsi"
 
 / {
 	model = "Plat'Home OpenBlocksA6";
@@ -29,11 +30,69 @@
 		nand@3000000 {
 			chip-delay = <25>;
 			status = "okay";
+
+			partition@0 {
+				label = "uboot";
+				reg = <0x0 0x90000>;
+			};
+
+			partition@90000 {
+				label = "env";
+				reg = <0x90000 0x44000>;
+			};
+
+			partition@d4000 {
+				label = "test";
+				reg = <0xd4000 0x24000>;
+			};
+
+			partition@f4000 {
+				label = "conf";
+				reg = <0xf4000 0x400000>;
+			};
+
+			partition@4f4000 {
+				label = "linux";
+				reg = <0x4f4000 0x1d20000>;
+			};
+
+			partition@2214000 {
+				label = "user";
+				reg = <0x2214000 0x1dec000>;
+			};
 		};
 
 		sata@80000 {
 			nr-ports = <1>;
 			status = "okay";
 		};
+
+		i2c@11100 {
+			status = "okay";
+
+			s35390a: s35390a@30 {
+				compatible = "s35390a";
+				reg = <0x30>;
+			};
+		};
 	};
+
+	gpio-leds {
+		compatible = "gpio-leds";
+
+		led-red {
+			label = "obsa6:red:stat";
+			gpios = <&gpio1 9 1>;
+		};
+
+		led-green {
+			label = "obsa6:green:stat";
+			gpios = <&gpio1 10 1>;
+		};
+
+		led-yellow {
+			label = "obsa6:yellow:stat";
+			gpios = <&gpio1 11 1>;
+		};
+        };
 };
diff --git a/arch/arm/boot/dts/kirkwood-ts219-6281.dts b/arch/arm/boot/dts/kirkwood-ts219-6281.dts
index ccbf327..8295c83 100644
--- a/arch/arm/boot/dts/kirkwood-ts219-6281.dts
+++ b/arch/arm/boot/dts/kirkwood-ts219-6281.dts
@@ -1,8 +1,39 @@
 /dts-v1/;
 
 /include/ "kirkwood-ts219.dtsi"
+/include/ "kirkwood-6281.dtsi"
 
 / {
+	ocp@f1000000 {
+		pinctrl: pinctrl@10000 {
+
+			pinctrl-0 = < &pmx_uart0 &pmx_uart1 &pmx_spi
+				      &pmx_twsi0 &pmx_sata0 &pmx_sata1
+				      &pmx_ram_size &pmx_reset_button
+				      &pmx_USB_copy_button &pmx_board_id>;
+			pinctrl-names = "default";
+
+			pmx_ram_size: pmx-ram-size {
+				/* RAM: 0: 256 MB, 1: 512 MB */
+				marvell,pins = "mpp36";
+				marvell,function = "gpio";
+			};
+			pmx_USB_copy_button: pmx-USB-copy-button {
+				marvell,pins = "mpp15";
+				marvell,function = "gpio";
+			};
+			pmx_reset_button: pmx-reset-button {
+				marvell,pins = "mpp16";
+				marvell,function = "gpio";
+			};
+			pmx_board_id: pmx-board-id {
+				/* 0: TS-11x, 1: TS-21x */
+				marvell,pins = "mpp44";
+				marvell,function = "gpio";
+			};
+		};
+	};
+
 	gpio_keys {
 		compatible = "gpio-keys";
 		#address-cells = <1>;
diff --git a/arch/arm/boot/dts/kirkwood-ts219-6282.dts b/arch/arm/boot/dts/kirkwood-ts219-6282.dts
index fbe9932..df3f95d 100644
--- a/arch/arm/boot/dts/kirkwood-ts219-6282.dts
+++ b/arch/arm/boot/dts/kirkwood-ts219-6282.dts
@@ -1,8 +1,39 @@
 /dts-v1/;
 
 /include/ "kirkwood-ts219.dtsi"
+/include/ "kirkwood-6282.dtsi"
 
 / {
+	ocp@f1000000 {
+		pinctrl: pinctrl@10000 {
+
+			pinctrl-0 = < &pmx_uart0 &pmx_uart1 &pmx_spi
+				      &pmx_twsi0 &pmx_sata0 &pmx_sata1
+				      &pmx_ram_size &pmx_reset_button
+				      &pmx_USB_copy_button &pmx_board_id>;
+			pinctrl-names = "default";
+
+			pmx_ram_size: pmx-ram-size {
+				/* RAM: 0: 256 MB, 1: 512 MB */
+				marvell,pins = "mpp36";
+				marvell,function = "gpio";
+			};
+			pmx_reset_button: pmx-reset-button {
+				marvell,pins = "mpp37";
+				marvell,function = "gpio";
+			};
+			pmx_USB_copy_button: pmx-USB-copy-button {
+				marvell,pins = "mpp43";
+				marvell,function = "gpio";
+			};
+			pmx_board_id: pmx-board-id {
+				/* 0: TS-11x, 1: TS-21x */
+				marvell,pins = "mpp44";
+				marvell,function = "gpio";
+			};
+		};
+	};
+
 	gpio_keys {
 		compatible = "gpio-keys";
 		#address-cells = <1>;
diff --git a/arch/arm/boot/dts/kirkwood.dtsi b/arch/arm/boot/dts/kirkwood.dtsi
index 4e5b815..a990c30 100644
--- a/arch/arm/boot/dts/kirkwood.dtsi
+++ b/arch/arm/boot/dts/kirkwood.dtsi
@@ -4,6 +4,10 @@
 	compatible = "marvell,kirkwood";
 	interrupt-parent = <&intc>;
 
+	aliases {
+	       gpio0 = &gpio0;
+	       gpio1 = &gpio1;
+	};
 	intc: interrupt-controller {
 		compatible = "marvell,orion-intc", "marvell,intc";
 		interrupt-controller;
@@ -24,7 +28,8 @@
 			#gpio-cells = <2>;
 			gpio-controller;
 			reg = <0x10100 0x40>;
-			ngpio = <32>;
+			ngpios = <32>;
+			interrupt-controller;
 			interrupts = <35>, <36>, <37>, <38>;
 		};
 
@@ -33,7 +38,8 @@
 			#gpio-cells = <2>;
 			gpio-controller;
 			reg = <0x10140 0x40>;
-			ngpio = <18>;
+			ngpios = <18>;
+			interrupt-controller;
 			interrupts = <39>, <40>, <41>;
 		};
 
@@ -77,6 +83,13 @@
 			status = "okay";
 		};
 
+		ehci@50000 {
+			compatible = "marvell,orion-ehci";
+			reg = <0x50000 0x1000>;
+			interrupts = <19>;
+			status = "okay";
+		};
+
 		sata@80000 {
 			compatible = "marvell,orion-sata";
 			reg = <0x80000 0x5000>;
diff --git a/arch/arm/boot/dts/lpc32xx.dtsi b/arch/arm/boot/dts/lpc32xx.dtsi
index e5ffe96..1582f48 100644
--- a/arch/arm/boot/dts/lpc32xx.dtsi
+++ b/arch/arm/boot/dts/lpc32xx.dtsi
@@ -182,6 +182,13 @@
 				pnx,timeout = <0x64>;
 			};
 
+			mpwm: mpwm@400E8000 {
+				compatible = "nxp,lpc3220-motor-pwm";
+				reg = <0x400E8000 0x78>;
+				status = "disabled";
+				#pwm-cells = <2>;
+			};
+
 			i2cusb: i2c@31020300 {
 				compatible = "nxp,pnx-i2c";
 				reg = <0x31020300 0x100>;
diff --git a/arch/arm/boot/dts/snowball.dts b/arch/arm/boot/dts/snowball.dts
index c6f85f0..27f31a5 100644
--- a/arch/arm/boot/dts/snowball.dts
+++ b/arch/arm/boot/dts/snowball.dts
@@ -14,7 +14,7 @@
 
 / {
 	model = "Calao Systems Snowball platform with device tree";
-	compatible = "calaosystems,snowball-a9500";
+	compatible = "calaosystems,snowball-a9500", "st-ericsson,u9500";
 
 	memory {
 		reg = <0x00000000 0x20000000>;
@@ -147,10 +147,10 @@
 		};
 
 		// External Micro SD slot
-		sdi@80126000 {
+		sdi0_per1@80126000 {
 			arm,primecell-periphid = <0x10480180>;
 			max-frequency = <50000000>;
-			bus-width = <8>;
+			bus-width = <4>;
 			mmc-cap-mmc-highspeed;
 			vmmc-supply = <&ab8500_ldo_aux3_reg>;
 
@@ -161,7 +161,7 @@
 		};
 
 		// On-board eMMC
-		sdi@80114000 {
+		sdi4_per2@80114000 {
 			arm,primecell-periphid = <0x10480180>;
 		        max-frequency = <50000000>;
 			bus-width = <8>;
@@ -214,5 +214,137 @@
 		cpufreq-cooling {
 			status = "okay";
 		};
+
+		prcmu@80157000 {
+			db8500-prcmu-regulators {
+				db8500_vape_reg: db8500_vape {
+					regulator-name = "db8500-vape";
+				};
+
+				db8500_varm_reg: db8500_varm {
+					regulator-name = "db8500-varm";
+				};
+
+				db8500_vmodem_reg: db8500_vmodem {
+					regulator-name = "db8500-vmodem";
+				};
+
+				db8500_vpll_reg: db8500_vpll {
+					regulator-name = "db8500-vpll";
+				};
+
+				db8500_vsmps1_reg: db8500_vsmps1 {
+					regulator-name = "db8500-vsmps1";
+				};
+
+				db8500_vsmps2_reg: db8500_vsmps2 {
+					regulator-name = "db8500-vsmps2";
+				};
+
+				db8500_vsmps3_reg: db8500_vsmps3 {
+					regulator-name = "db8500-vsmps3";
+				};
+
+				db8500_vrf1_reg: db8500_vrf1 {
+					regulator-name = "db8500-vrf1";
+				};
+
+				db8500_sva_mmdsp_reg: db8500_sva_mmdsp {
+					regulator-name = "db8500-sva-mmdsp";
+				};
+
+				db8500_sva_mmdsp_ret_reg: db8500_sva_mmdsp_ret {
+					regulator-name = "db8500-sva-mmdsp-ret";
+				};
+
+				db8500_sva_pipe_reg: db8500_sva_pipe {
+					regulator-name = "db8500_sva_pipe";
+				};
+
+				db8500_sia_mmdsp_reg: db8500_sia_mmdsp {
+					regulator-name = "db8500_sia_mmdsp";
+				};
+
+				db8500_sia_mmdsp_ret_reg: db8500_sia_mmdsp_ret {
+					regulator-name = "db8500-sia-mmdsp-ret";
+				};
+
+				db8500_sia_pipe_reg: db8500_sia_pipe {
+					regulator-name = "db8500-sia-pipe";
+				};
+
+				db8500_sga_reg: db8500_sga {
+					regulator-name = "db8500-sga";
+				};
+
+				db8500_b2r2_mcde_reg: db8500_b2r2_mcde {
+					regulator-name = "db8500-b2r2-mcde";
+				};
+
+				db8500_esram12_reg: db8500_esram12 {
+					regulator-name = "db8500-esram12";
+				};
+
+				db8500_esram12_ret_reg: db8500_esram12_ret {
+					regulator-name = "db8500-esram12-ret";
+				};
+
+				db8500_esram34_reg: db8500_esram34 {
+					regulator-name = "db8500-esram34";
+				};
+
+				db8500_esram34_ret_reg: db8500_esram34_ret {
+					regulator-name = "db8500-esram34-ret";
+				};
+			};
+
+			ab8500@5 {
+				ab8500-regulators {
+					ab8500_ldo_aux1_reg: ab8500_ldo_aux1 {
+						regulator-name = "V-DISPLAY";
+					};
+
+					ab8500_ldo_aux2_reg: ab8500_ldo_aux2 {
+						regulator-name = "V-eMMC1";
+					};
+
+					ab8500_ldo_aux3_reg: ab8500_ldo_aux3 {
+						regulator-name = "V-MMC-SD";
+					};
+
+					ab8500_ldo_initcore_reg: ab8500_ldo_initcore {
+						regulator-name = "V-INTCORE";
+					};
+
+					ab8500_ldo_tvout_reg: ab8500_ldo_tvout {
+						regulator-name = "V-TVOUT";
+					};
+
+					ab8500_ldo_usb_reg: ab8500_ldo_usb {
+						regulator-name = "dummy";
+					};
+
+					ab8500_ldo_audio_reg: ab8500_ldo_audio {
+						regulator-name = "V-AUD";
+					};
+
+					ab8500_ldo_anamic1_reg: ab8500_ldo_anamic1 {
+						regulator-name = "V-AMIC1";
+					};
+
+					ab8500_ldo_amamic2_reg: ab8500_ldo_amamic2 {
+						regulator-name = "V-AMIC2";
+					};
+
+					ab8500_ldo_dmic_reg: ab8500_ldo_dmic {
+						regulator-name = "V-DMIC";
+					};
+
+					ab8500_ldo_ana_reg: ab8500_ldo_ana {
+						regulator-name = "V-CSI/DSI";
+					};
+				};
+			};
+		};
 	};
 };
diff --git a/arch/arm/boot/dts/stuib.dtsi b/arch/arm/boot/dts/stuib.dtsi
new file mode 100644
index 0000000..39446a2
--- /dev/null
+++ b/arch/arm/boot/dts/stuib.dtsi
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2012 ST-Ericsson AB
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/ {
+	soc-u9500 {
+		i2c@80004000 {
+			stmpe1601: stmpe1601@40 {
+				compatible = "st,stmpe1601";
+				reg = <0x40>;
+				interrupts = <26 0x1>;
+				interrupt-parent = <&gpio6>;
+				interrupt-controller;
+
+				wakeup-source;
+				st,autosleep-timeout = <1024>;
+
+				stmpe_keypad {
+					compatible = "st,stmpe-keypad";
+
+					debounce-interval = <64>;
+					st,scan-count = <8>;
+					st,no-autorepeat;
+
+					linux,keymap = <0x205006b
+							0x4010074
+							0x3050072
+							0x1030004
+							0x502006a
+							0x500000a
+							0x5008b
+							0x706001c
+							0x405000b
+							0x6070003
+							0x3040067
+							0x303006c
+							0x60400e7
+							0x602009e
+							0x4020073
+							0x5050002
+							0x4030069
+							0x3020008>;
+				};
+			};
+		};
+
+		i2c@80110000 {
+			bu21013_tp@0x5c {
+				compatible = "rhom,bu21013_tp";
+				reg = <0x5c>;
+				touch-gpio = <&gpio2 20 0x4>;
+				avdd-supply = <&ab8500_ldo_aux1_reg>;
+
+				rhom,touch-max-x = <384>;
+				rhom,touch-max-y = <704>;
+				rhom,flip-y;
+			};
+
+			bu21013_tp@0x5d {
+				compatible = "rhom,bu21013_tp";
+				reg = <0x5d>;
+				touch-gpio = <&gpio2 20 0x4>;
+				avdd-supply = <&ab8500_ldo_aux1_reg>;
+
+				rhom,touch-max-x = <384>;
+				rhom,touch-max-y = <704>;
+				rhom,flip-y;
+			};
+		};
+	};
+};
diff --git a/arch/arm/boot/dts/tegra20-harmony.dts b/arch/arm/boot/dts/tegra20-harmony.dts
index 74b8a47..43eb72a 100644
--- a/arch/arm/boot/dts/tegra20-harmony.dts
+++ b/arch/arm/boot/dts/tegra20-harmony.dts
@@ -10,6 +10,18 @@
 		reg = <0x00000000 0x40000000>;
 	};
 
+	host1x {
+		hdmi {
+			status = "okay";
+
+			vdd-supply = <&hdmi_vdd_reg>;
+			pll-supply = <&hdmi_pll_reg>;
+
+			nvidia,ddc-i2c-bus = <&hdmi_ddc>;
+			nvidia,hpd-gpio = <&gpio 111 0>; /* PN7 */
+		};
+	};
+
 	pinmux {
 		pinctrl-names = "default";
 		pinctrl-0 = <&state_default>;
@@ -262,9 +274,9 @@
 		};
 	};
 
-	i2c@7000c400 {
+	hdmi_ddc: i2c@7000c400 {
 		status = "okay";
-		clock-frequency = <400000>;
+		clock-frequency = <100000>;
 	};
 
 	i2c@7000c500 {
@@ -369,13 +381,13 @@
 					regulator-max-microvolt = <1800000>;
 				};
 
-				ldo7 {
+				hdmi_vdd_reg: ldo7 {
 					regulator-name = "vdd_ldo7,avdd_hdmi";
 					regulator-min-microvolt = <3300000>;
 					regulator-max-microvolt = <3300000>;
 				};
 
-				ldo8 {
+				hdmi_pll_reg: ldo8 {
 					regulator-name = "vdd_ldo8,avdd_hdmi_pll";
 					regulator-min-microvolt = <1800000>;
 					regulator-max-microvolt = <1800000>;
@@ -396,6 +408,11 @@
 				};
 			};
 		};
+
+		temperature-sensor@4c {
+			compatible = "adi,adt7461";
+			reg = <0x4c>;
+		};
 	};
 
 	pmc {
diff --git a/arch/arm/boot/dts/tegra20-plutux.dts b/arch/arm/boot/dts/tegra20-plutux.dts
index 331a3ef..2894800 100644
--- a/arch/arm/boot/dts/tegra20-plutux.dts
+++ b/arch/arm/boot/dts/tegra20-plutux.dts
@@ -6,6 +6,12 @@
 	model = "Avionic Design Plutux board";
 	compatible = "ad,plutux", "ad,tamonten", "nvidia,tegra20";
 
+	host1x {
+		hdmi {
+			status = "okay";
+		};
+	};
+
 	i2c@7000c000 {
 		wm8903: wm8903@1a {
 			compatible = "wlf,wm8903";
diff --git a/arch/arm/boot/dts/tegra20-seaboard.dts b/arch/arm/boot/dts/tegra20-seaboard.dts
index e58a0e6..4204598 100644
--- a/arch/arm/boot/dts/tegra20-seaboard.dts
+++ b/arch/arm/boot/dts/tegra20-seaboard.dts
@@ -561,6 +561,12 @@
 		status = "okay";
 	};
 
+	sdhci@c8000000 {
+		status = "okay";
+		power-gpios = <&gpio 86 0>; /* gpio PK6 */
+		bus-width = <4>;
+	};
+
 	sdhci@c8000400 {
 		status = "okay";
 		cd-gpios = <&gpio 69 0>; /* gpio PI5 */
diff --git a/arch/arm/boot/dts/tegra20-tamonten.dtsi b/arch/arm/boot/dts/tegra20-tamonten.dtsi
index 5b3d8b1..a239ccd 100644
--- a/arch/arm/boot/dts/tegra20-tamonten.dtsi
+++ b/arch/arm/boot/dts/tegra20-tamonten.dtsi
@@ -8,6 +8,16 @@
 		reg = <0x00000000 0x20000000>;
 	};
 
+	host1x {
+		hdmi {
+			vdd-supply = <&hdmi_vdd_reg>;
+			pll-supply = <&hdmi_pll_reg>;
+
+			nvidia,ddc-i2c-bus = <&hdmi_ddc>;
+			nvidia,hpd-gpio = <&gpio 111 0>; /* PN7 */
+		};
+	};
+
 	pinmux {
 		pinctrl-names = "default";
 		pinctrl-0 = <&state_default>;
@@ -62,10 +72,6 @@
 				nvidia,pins = "dap4";
 				nvidia,function = "dap4";
 			};
-			ddc {
-				nvidia,pins = "ddc";
-				nvidia,function = "i2c2";
-			};
 			dta {
 				nvidia,pins = "dta", "dtd";
 				nvidia,function = "sdio2";
@@ -91,7 +97,7 @@
 				nvidia,function = "pcie";
 			};
 			hdint {
-				nvidia,pins = "hdint", "pta";
+				nvidia,pins = "hdint";
 				nvidia,function = "hdmi";
 			};
 			i2cp {
@@ -230,6 +236,39 @@
 				nvidia,pull = <1>;
 			};
 		};
+
+		state_i2cmux_ddc: pinmux_i2cmux_ddc {
+			ddc {
+				nvidia,pins = "ddc";
+				nvidia,function = "i2c2";
+			};
+			pta {
+				nvidia,pins = "pta";
+				nvidia,function = "rsvd4";
+			};
+		};
+
+		state_i2cmux_pta: pinmux_i2cmux_pta {
+			ddc {
+				nvidia,pins = "ddc";
+				nvidia,function = "rsvd4";
+			};
+			pta {
+				nvidia,pins = "pta";
+				nvidia,function = "i2c2";
+			};
+		};
+
+		state_i2cmux_idle: pinmux_i2cmux_idle {
+			ddc {
+				nvidia,pins = "ddc";
+				nvidia,function = "rsvd4";
+			};
+			pta {
+				nvidia,pins = "pta";
+				nvidia,function = "rsvd4";
+			};
+		};
 	};
 
 	i2s@70002800 {
@@ -246,6 +285,36 @@
 		status = "okay";
 	};
 
+	i2c@7000c400 {
+		clock-frequency = <100000>;
+		status = "okay";
+	};
+
+	i2cmux {
+		compatible = "i2c-mux-pinctrl";
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		i2c-parent = <&{/i2c@7000c400}>;
+
+		pinctrl-names = "ddc", "pta", "idle";
+		pinctrl-0 = <&state_i2cmux_ddc>;
+		pinctrl-1 = <&state_i2cmux_pta>;
+		pinctrl-2 = <&state_i2cmux_idle>;
+
+		hdmi_ddc: i2c@0 {
+			reg = <0>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+
+		i2c@1 {
+			reg = <1>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+	};
+
 	i2c@7000d000 {
 		clock-frequency = <400000>;
 		status = "okay";
@@ -348,13 +417,13 @@
 					regulator-max-microvolt = <2850000>;
 				};
 
-				ldo7 {
+				hdmi_vdd_reg: ldo7 {
 					regulator-name = "vdd_ldo7,avdd_hdmi";
 					regulator-min-microvolt = <3300000>;
 					regulator-max-microvolt = <3300000>;
 				};
 
-				ldo8 {
+				hdmi_pll_reg: ldo8 {
 					regulator-name = "vdd_ldo8,avdd_hdmi_pll";
 					regulator-min-microvolt = <1800000>;
 					regulator-max-microvolt = <1800000>;
@@ -381,6 +450,11 @@
 				};
 			};
 		};
+
+		temperature-sensor@4c {
+			compatible = "onnn,nct1008";
+			reg = <0x4c>;
+		};
 	};
 
 	pmc {
diff --git a/arch/arm/boot/dts/tegra20-tec.dts b/arch/arm/boot/dts/tegra20-tec.dts
index 9aff31b..402b210 100644
--- a/arch/arm/boot/dts/tegra20-tec.dts
+++ b/arch/arm/boot/dts/tegra20-tec.dts
@@ -6,10 +6,13 @@
 	model = "Avionic Design Tamonten Evaluation Carrier";
 	compatible = "ad,tec", "ad,tamonten", "nvidia,tegra20";
 
-	i2c@7000c000 {
-		clock-frequency = <400000>;
-		status = "okay";
+	host1x {
+		hdmi {
+			status = "okay";
+		};
+	};
 
+	i2c@7000c000 {
 		wm8903: wm8903@1a {
 			compatible = "wlf,wm8903";
 			reg = <0x1a>;
diff --git a/arch/arm/boot/dts/tegra20-trimslice.dts b/arch/arm/boot/dts/tegra20-trimslice.dts
index 27fb8a6..b70b4cb 100644
--- a/arch/arm/boot/dts/tegra20-trimslice.dts
+++ b/arch/arm/boot/dts/tegra20-trimslice.dts
@@ -10,6 +10,18 @@
 		reg = <0x00000000 0x40000000>;
 	};
 
+	host1x {
+		hdmi {
+			status = "okay";
+
+			vdd-supply = <&hdmi_vdd_reg>;
+			pll-supply = <&hdmi_pll_reg>;
+
+			nvidia,ddc-i2c-bus = <&hdmi_ddc>;
+			nvidia,hpd-gpio = <&gpio 111 0>; /* PN7 */
+		};
+	};
+
 	pinmux {
 		pinctrl-names = "default";
 		pinctrl-0 = <&state_default>;
@@ -249,14 +261,24 @@
 		clock-frequency = <216000000>;
 	};
 
-	i2c@7000c000 {
+	dvi_ddc: i2c@7000c000 {
 		status = "okay";
-		clock-frequency = <400000>;
+		clock-frequency = <100000>;
 	};
 
-	i2c@7000c400 {
+	spi@7000c380 {
 		status = "okay";
-		clock-frequency = <400000>;
+		spi-max-frequency = <48000000>;
+		spi-flash@0 {
+			compatible = "winbond,w25q80bl";
+			reg = <0>;
+			spi-max-frequency = <48000000>;
+		};
+	};
+
+	hdmi_ddc: i2c@7000c400 {
+		status = "okay";
+		clock-frequency = <100000>;
 	};
 
 	i2c@7000c500 {
@@ -300,6 +322,30 @@
 		bus-width = <4>;
 	};
 
+	regulators {
+		compatible = "simple-bus";
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		hdmi_vdd_reg: regulator@0 {
+			compatible = "regulator-fixed";
+			reg = <0>;
+			regulator-name = "avdd_hdmi";
+			regulator-min-microvolt = <3300000>;
+			regulator-max-microvolt = <3300000>;
+			regulator-always-on;
+		};
+
+		hdmi_pll_reg: regulator@1 {
+			compatible = "regulator-fixed";
+			reg = <1>;
+			regulator-name = "avdd_hdmi_pll";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+			regulator-always-on;
+		};
+	};
+
 	sound {
 		compatible = "nvidia,tegra-audio-trimslice";
 		nvidia,i2s-controller = <&tegra_i2s1>;
diff --git a/arch/arm/boot/dts/tegra20-ventana.dts b/arch/arm/boot/dts/tegra20-ventana.dts
index 86854f1..adc4754 100644
--- a/arch/arm/boot/dts/tegra20-ventana.dts
+++ b/arch/arm/boot/dts/tegra20-ventana.dts
@@ -64,11 +64,6 @@
 				nvidia,pins = "dap4";
 				nvidia,function = "dap4";
 			};
-			ddc {
-				nvidia,pins = "ddc", "owc", "spdi", "spdo",
-					"uac";
-				nvidia,function = "rsvd2";
-			};
 			dta {
 				nvidia,pins = "dta", "dtb", "dtc", "dtd", "dte";
 				nvidia,function = "vi";
@@ -98,7 +93,7 @@
 				nvidia,function = "pcie";
 			};
 			hdint {
-				nvidia,pins = "hdint", "pta";
+				nvidia,pins = "hdint";
 				nvidia,function = "hdmi";
 			};
 			i2cp {
@@ -129,6 +124,10 @@
 					"lspi", "lvp1", "lvs";
 				nvidia,function = "displaya";
 			};
+			owc {
+				nvidia,pins = "owc", "spdi", "spdo", "uac";
+				nvidia,function = "rsvd2";
+			};
 			pmc {
 				nvidia,pins = "pmc";
 				nvidia,function = "pwr_on";
@@ -237,6 +236,49 @@
 					"ld23_22";
 				nvidia,pull = <1>;
 			};
+			drive_sdio1 {
+				nvidia,pins = "drive_sdio1";
+				nvidia,high-speed-mode = <0>;
+				nvidia,schmitt = <1>;
+				nvidia,low-power-mode = <3>;
+				nvidia,pull-down-strength = <31>;
+				nvidia,pull-up-strength = <31>;
+				nvidia,slew-rate-rising = <3>;
+				nvidia,slew-rate-falling = <3>;
+			};
+		};
+
+		state_i2cmux_ddc: pinmux_i2cmux_ddc {
+			ddc {
+				nvidia,pins = "ddc";
+				nvidia,function = "i2c2";
+			};
+			pta {
+				nvidia,pins = "pta";
+				nvidia,function = "rsvd4";
+			};
+		};
+
+		state_i2cmux_pta: pinmux_i2cmux_pta {
+			ddc {
+				nvidia,pins = "ddc";
+				nvidia,function = "rsvd4";
+			};
+			pta {
+				nvidia,pins = "pta";
+				nvidia,function = "i2c2";
+			};
+		};
+
+		state_i2cmux_idle: pinmux_i2cmux_idle {
+			ddc {
+				nvidia,pins = "ddc";
+				nvidia,function = "rsvd4";
+			};
+			pta {
+				nvidia,pins = "pta";
+				nvidia,function = "rsvd4";
+			};
 		};
 	};
 
@@ -281,6 +323,31 @@
 		clock-frequency = <400000>;
 	};
 
+	i2cmux {
+		compatible = "i2c-mux-pinctrl";
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		i2c-parent = <&{/i2c@7000c400}>;
+
+		pinctrl-names = "ddc", "pta", "idle";
+		pinctrl-0 = <&state_i2cmux_ddc>;
+		pinctrl-1 = <&state_i2cmux_pta>;
+		pinctrl-2 = <&state_i2cmux_idle>;
+
+		i2c@0 {
+			reg = <0>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+
+		i2c@1 {
+			reg = <1>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+	};
+
 	i2c@7000c500 {
 		status = "okay";
 		clock-frequency = <400000>;
@@ -406,6 +473,11 @@
 				};
 			};
 		};
+
+		temperature-sensor@4c {
+			compatible = "onnn,nct1008";
+			reg = <0x4c>;
+		};
 	};
 
 	pmc {
@@ -425,6 +497,12 @@
 		status = "okay";
 	};
 
+	sdhci@c8000000 {
+		status = "okay";
+		power-gpios = <&gpio 86 0>; /* gpio PK6 */
+		bus-width = <4>;
+	};
+
 	sdhci@c8000400 {
 		status = "okay";
 		cd-gpios = <&gpio 69 0>; /* gpio PI5 */
diff --git a/arch/arm/boot/dts/tegra20-whistler.dts b/arch/arm/boot/dts/tegra20-whistler.dts
index 94a71c9..20d576e 100644
--- a/arch/arm/boot/dts/tegra20-whistler.dts
+++ b/arch/arm/boot/dts/tegra20-whistler.dts
@@ -10,6 +10,18 @@
 		reg = <0x00000000 0x20000000>;
 	};
 
+	host1x {
+		hdmi {
+			status = "okay";
+
+			vdd-supply = <&hdmi_vdd_reg>;
+			pll-supply = <&hdmi_pll_reg>;
+
+			nvidia,ddc-i2c-bus = <&hdmi_ddc>;
+			nvidia,hpd-gpio = <&gpio 111 0>; /* PN7 */
+		};
+	};
+
 	pinmux {
 		pinctrl-names = "default";
 		pinctrl-0 = <&state_default>;
@@ -246,6 +258,11 @@
 		clock-frequency = <216000000>;
 	};
 
+	hdmi_ddc: i2c@7000c400 {
+		status = "okay";
+		clock-frequency = <100000>;
+	};
+
 	i2c@7000d000 {
 		status = "okay";
 		clock-frequency = <100000>;
@@ -356,7 +373,7 @@
 					regulator-always-on;
 				};
 
-				ldo6 {
+				hdmi_pll_reg: ldo6 {
 					regulator-name = "nvvdd_ldo6,avdd_hdmi_pll";
 					regulator-min-microvolt = <1800000>;
 					regulator-max-microvolt = <1800000>;
@@ -388,7 +405,7 @@
 					regulator-always-on;
 				};
 
-				ldo11 {
+				hdmi_vdd_reg: ldo11 {
 					regulator-name = "nvvdd_ldo11,vddio_pex_clk,vcom_33,avdd_hdmi";
 					regulator-min-microvolt = <3300000>;
 					regulator-max-microvolt = <3300000>;
diff --git a/arch/arm/boot/dts/tegra20.dtsi b/arch/arm/boot/dts/tegra20.dtsi
index f40cfba..b8effa1 100644
--- a/arch/arm/boot/dts/tegra20.dtsi
+++ b/arch/arm/boot/dts/tegra20.dtsi
@@ -4,6 +4,99 @@
 	compatible = "nvidia,tegra20";
 	interrupt-parent = <&intc>;
 
+	host1x {
+		compatible = "nvidia,tegra20-host1x", "simple-bus";
+		reg = <0x50000000 0x00024000>;
+		interrupts = <0 65 0x04   /* mpcore syncpt */
+			      0 67 0x04>; /* mpcore general */
+
+		#address-cells = <1>;
+		#size-cells = <1>;
+
+		ranges = <0x54000000 0x54000000 0x04000000>;
+
+		mpe {
+			compatible = "nvidia,tegra20-mpe";
+			reg = <0x54040000 0x00040000>;
+			interrupts = <0 68 0x04>;
+		};
+
+		vi {
+			compatible = "nvidia,tegra20-vi";
+			reg = <0x54080000 0x00040000>;
+			interrupts = <0 69 0x04>;
+		};
+
+		epp {
+			compatible = "nvidia,tegra20-epp";
+			reg = <0x540c0000 0x00040000>;
+			interrupts = <0 70 0x04>;
+		};
+
+		isp {
+			compatible = "nvidia,tegra20-isp";
+			reg = <0x54100000 0x00040000>;
+			interrupts = <0 71 0x04>;
+		};
+
+		gr2d {
+			compatible = "nvidia,tegra20-gr2d";
+			reg = <0x54140000 0x00040000>;
+			interrupts = <0 72 0x04>;
+		};
+
+		gr3d {
+			compatible = "nvidia,tegra20-gr3d";
+			reg = <0x54180000 0x00040000>;
+		};
+
+		dc@54200000 {
+			compatible = "nvidia,tegra20-dc";
+			reg = <0x54200000 0x00040000>;
+			interrupts = <0 73 0x04>;
+
+			rgb {
+				status = "disabled";
+			};
+		};
+
+		dc@54240000 {
+			compatible = "nvidia,tegra20-dc";
+			reg = <0x54240000 0x00040000>;
+			interrupts = <0 74 0x04>;
+
+			rgb {
+				status = "disabled";
+			};
+		};
+
+		hdmi {
+			compatible = "nvidia,tegra20-hdmi";
+			reg = <0x54280000 0x00040000>;
+			interrupts = <0 75 0x04>;
+			status = "disabled";
+		};
+
+		tvo {
+			compatible = "nvidia,tegra20-tvo";
+			reg = <0x542c0000 0x00040000>;
+			interrupts = <0 76 0x04>;
+			status = "disabled";
+		};
+
+		dsi {
+			compatible = "nvidia,tegra20-dsi";
+			reg = <0x54300000 0x00040000>;
+			status = "disabled";
+		};
+	};
+
+	timer@50004600 {
+		compatible = "arm,cortex-a9-twd-timer";
+		reg = <0x50040600 0x20>;
+		interrupts = <1 13 0x304>;
+	};
+
 	cache-controller@50043000 {
 		compatible = "arm,pl310-cache";
 		reg = <0x50043000 0x1000>;
@@ -21,6 +114,15 @@
 		#interrupt-cells = <3>;
 	};
 
+	timer@60005000 {
+		compatible = "nvidia,tegra20-timer";
+		reg = <0x60005000 0x60>;
+		interrupts = <0 0 0x04
+			      0 1 0x04
+			      0 41 0x04
+			      0 42 0x04>;
+	};
+
 	apbdma: dma {
 		compatible = "nvidia,tegra20-apbdma";
 		reg = <0x6000a000 0x1200>;
@@ -138,6 +240,12 @@
 		#pwm-cells = <2>;
 	};
 
+	rtc {
+		compatible = "nvidia,tegra20-rtc";
+		reg = <0x7000e000 0x100>;
+		interrupts = <0 2 0x04>;
+	};
+
 	i2c@7000c000 {
 		compatible = "nvidia,tegra20-i2c";
 		reg = <0x7000c000 0x100>;
@@ -147,6 +255,16 @@
 		status = "disabled";
 	};
 
+	spi@7000c380 {
+		compatible = "nvidia,tegra20-sflash";
+		reg = <0x7000c380 0x80>;
+		interrupts = <0 39 0x04>;
+		nvidia,dma-request-selector = <&apbdma 11>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "disabled";
+	};
+
 	i2c@7000c400 {
 		compatible = "nvidia,tegra20-i2c";
 		reg = <0x7000c400 0x100>;
@@ -174,6 +292,46 @@
 		status = "disabled";
 	};
 
+	spi@7000d400 {
+		compatible = "nvidia,tegra20-slink";
+		reg = <0x7000d400 0x200>;
+		interrupts = <0 59 0x04>;
+		nvidia,dma-request-selector = <&apbdma 15>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "disabled";
+	};
+
+	spi@7000d600 {
+		compatible = "nvidia,tegra20-slink";
+		reg = <0x7000d600 0x200>;
+		interrupts = <0 82 0x04>;
+		nvidia,dma-request-selector = <&apbdma 16>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "disabled";
+	};
+
+	spi@7000d800 {
+		compatible = "nvidia,tegra20-slink";
+		reg = <0x7000d480 0x200>;
+		interrupts = <0 83 0x04>;
+		nvidia,dma-request-selector = <&apbdma 17>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "disabled";
+	};
+
+	spi@7000da00 {
+		compatible = "nvidia,tegra20-slink";
+		reg = <0x7000da00 0x200>;
+		interrupts = <0 93 0x04>;
+		nvidia,dma-request-selector = <&apbdma 18>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "disabled";
+	};
+
 	pmc {
 		compatible = "nvidia,tegra20-pmc";
 		reg = <0x7000e400 0x400>;
diff --git a/arch/arm/boot/dts/tegra30-cardhu-a02.dts b/arch/arm/boot/dts/tegra30-cardhu-a02.dts
index dd4222f..adc88aa 100644
--- a/arch/arm/boot/dts/tegra30-cardhu-a02.dts
+++ b/arch/arm/boot/dts/tegra30-cardhu-a02.dts
@@ -83,5 +83,11 @@
 			gpio = <&gpio 83 0>; /* GPIO PK3 */
 		};
 	};
+
+	sdhci@78000400 {
+		status = "okay";
+		power-gpios = <&gpio 28 0>; /* gpio PD4 */
+		bus-width = <4>;
+	};
 };
 
diff --git a/arch/arm/boot/dts/tegra30-cardhu-a04.dts b/arch/arm/boot/dts/tegra30-cardhu-a04.dts
index 0828f09..08163e1 100644
--- a/arch/arm/boot/dts/tegra30-cardhu-a04.dts
+++ b/arch/arm/boot/dts/tegra30-cardhu-a04.dts
@@ -95,4 +95,10 @@
 			gpio = <&gpio 232 0>; /* GPIO PDD0 */
 		};
 	};
+
+	sdhci@78000400 {
+		status = "okay";
+		power-gpios = <&gpio 27 0>; /* gpio PD3 */
+		bus-width = <4>;
+	};
 };
diff --git a/arch/arm/boot/dts/tegra30-cardhu.dtsi b/arch/arm/boot/dts/tegra30-cardhu.dtsi
index b1271a8..bdb2a66 100644
--- a/arch/arm/boot/dts/tegra30-cardhu.dtsi
+++ b/arch/arm/boot/dts/tegra30-cardhu.dtsi
@@ -52,6 +52,22 @@
 				nvidia,pull = <2>;
 				nvidia,tristate = <0>;
 			};
+			sdmmc3_clk_pa6 {
+				nvidia,pins = "sdmmc3_clk_pa6";
+				nvidia,function = "sdmmc3";
+				nvidia,pull = <0>;
+				nvidia,tristate = <0>;
+			};
+			sdmmc3_cmd_pa7 {
+				nvidia,pins =	"sdmmc3_cmd_pa7",
+						"sdmmc3_dat0_pb7",
+						"sdmmc3_dat1_pb6",
+						"sdmmc3_dat2_pb5",
+						"sdmmc3_dat3_pb4";
+				nvidia,function = "sdmmc3";
+				nvidia,pull = <2>;
+				nvidia,tristate = <0>;
+			};
 			sdmmc4_clk_pcc4 {
 				nvidia,pins =	"sdmmc4_clk_pcc4",
 						"sdmmc4_rst_n_pcc3";
@@ -81,6 +97,15 @@
 				nvidia,pull = <0>;
 				nvidia,tristate = <0>;
 			};
+			sdio3 {
+				nvidia,pins = "drive_sdio3";
+				nvidia,high-speed-mode = <0>;
+				nvidia,schmitt = <0>;
+				nvidia,pull-down-strength = <46>;
+				nvidia,pull-up-strength = <42>;
+				nvidia,slew-rate-rising = <1>;
+				nvidia,slew-rate-falling = <1>;
+			};
 		};
 	};
 
@@ -250,6 +275,16 @@
 		};
 	};
 
+	spi@7000da00 {
+		status = "okay";
+		spi-max-frequency = <25000000>;
+		spi-flash@1 {
+			compatible = "winbond,w25q32";
+			reg = <1>;
+			spi-max-frequency = <20000000>;
+		};
+	};
+
 	ahub {
 		i2s@70080400 {
 			status = "okay";
@@ -384,6 +419,8 @@
 			regulator-name = "vdd_com";
 			regulator-min-microvolt = <3300000>;
 			regulator-max-microvolt = <3300000>;
+			regulator-always-on;
+			regulator-boot-on;
 			enable-active-high;
 			gpio = <&gpio 24 0>; /* gpio PD0 */
 			vin-supply = <&sys_3v3_reg>;
diff --git a/arch/arm/boot/dts/tegra30.dtsi b/arch/arm/boot/dts/tegra30.dtsi
index fed8dca..529fdb8 100644
--- a/arch/arm/boot/dts/tegra30.dtsi
+++ b/arch/arm/boot/dts/tegra30.dtsi
@@ -4,6 +4,99 @@
 	compatible = "nvidia,tegra30";
 	interrupt-parent = <&intc>;
 
+	host1x {
+		compatible = "nvidia,tegra30-host1x", "simple-bus";
+		reg = <0x50000000 0x00024000>;
+		interrupts = <0 65 0x04   /* mpcore syncpt */
+			      0 67 0x04>; /* mpcore general */
+
+		#address-cells = <1>;
+		#size-cells = <1>;
+
+		ranges = <0x54000000 0x54000000 0x04000000>;
+
+		mpe {
+			compatible = "nvidia,tegra30-mpe";
+			reg = <0x54040000 0x00040000>;
+			interrupts = <0 68 0x04>;
+		};
+
+		vi {
+			compatible = "nvidia,tegra30-vi";
+			reg = <0x54080000 0x00040000>;
+			interrupts = <0 69 0x04>;
+		};
+
+		epp {
+			compatible = "nvidia,tegra30-epp";
+			reg = <0x540c0000 0x00040000>;
+			interrupts = <0 70 0x04>;
+		};
+
+		isp {
+			compatible = "nvidia,tegra30-isp";
+			reg = <0x54100000 0x00040000>;
+			interrupts = <0 71 0x04>;
+		};
+
+		gr2d {
+			compatible = "nvidia,tegra30-gr2d";
+			reg = <0x54140000 0x00040000>;
+			interrupts = <0 72 0x04>;
+		};
+
+		gr3d {
+			compatible = "nvidia,tegra30-gr3d";
+			reg = <0x54180000 0x00040000>;
+		};
+
+		dc@54200000 {
+			compatible = "nvidia,tegra30-dc";
+			reg = <0x54200000 0x00040000>;
+			interrupts = <0 73 0x04>;
+
+			rgb {
+				status = "disabled";
+			};
+		};
+
+		dc@54240000 {
+			compatible = "nvidia,tegra30-dc";
+			reg = <0x54240000 0x00040000>;
+			interrupts = <0 74 0x04>;
+
+			rgb {
+				status = "disabled";
+			};
+		};
+
+		hdmi {
+			compatible = "nvidia,tegra30-hdmi";
+			reg = <0x54280000 0x00040000>;
+			interrupts = <0 75 0x04>;
+			status = "disabled";
+		};
+
+		tvo {
+			compatible = "nvidia,tegra30-tvo";
+			reg = <0x542c0000 0x00040000>;
+			interrupts = <0 76 0x04>;
+			status = "disabled";
+		};
+
+		dsi {
+			compatible = "nvidia,tegra30-dsi";
+			reg = <0x54300000 0x00040000>;
+			status = "disabled";
+		};
+	};
+
+	timer@50004600 {
+		compatible = "arm,cortex-a9-twd-timer";
+		reg = <0x50040600 0x20>;
+		interrupts = <1 13 0xf04>;
+	};
+
 	cache-controller@50043000 {
 		compatible = "arm,pl310-cache";
 		reg = <0x50043000 0x1000>;
@@ -21,6 +114,17 @@
 		#interrupt-cells = <3>;
 	};
 
+	timer@60005000 {
+		compatible = "nvidia,tegra30-timer", "nvidia,tegra20-timer";
+		reg = <0x60005000 0x400>;
+		interrupts = <0 0 0x04
+			      0 1 0x04
+			      0 41 0x04
+			      0 42 0x04
+			      0 121 0x04
+			      0 122 0x04>;
+	};
+
 	apbdma: dma {
 		compatible = "nvidia,tegra30-apbdma", "nvidia,tegra20-apbdma";
 		reg = <0x6000a000 0x1400>;
@@ -132,6 +236,12 @@
 		#pwm-cells = <2>;
 	};
 
+	rtc {
+		compatible = "nvidia,tegra30-rtc", "nvidia,tegra20-rtc";
+		reg = <0x7000e000 0x100>;
+		interrupts = <0 2 0x04>;
+	};
+
 	i2c@7000c000 {
 		compatible =  "nvidia,tegra30-i2c", "nvidia,tegra20-i2c";
 		reg = <0x7000c000 0x100>;
@@ -177,6 +287,66 @@
 		status = "disabled";
 	};
 
+	spi@7000d400 {
+		compatible = "nvidia,tegra30-slink", "nvidia,tegra20-slink";
+		reg = <0x7000d400 0x200>;
+		interrupts = <0 59 0x04>;
+		nvidia,dma-request-selector = <&apbdma 15>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "disabled";
+	};
+
+	spi@7000d600 {
+		compatible = "nvidia,tegra30-slink", "nvidia,tegra20-slink";
+		reg = <0x7000d600 0x200>;
+		interrupts = <0 82 0x04>;
+		nvidia,dma-request-selector = <&apbdma 16>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "disabled";
+	};
+
+	spi@7000d800 {
+		compatible = "nvidia,tegra30-slink", "nvidia,tegra20-slink";
+		reg = <0x7000d480 0x200>;
+		interrupts = <0 83 0x04>;
+		nvidia,dma-request-selector = <&apbdma 17>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "disabled";
+	};
+
+	spi@7000da00 {
+		compatible = "nvidia,tegra30-slink", "nvidia,tegra20-slink";
+		reg = <0x7000da00 0x200>;
+		interrupts = <0 93 0x04>;
+		nvidia,dma-request-selector = <&apbdma 18>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "disabled";
+	};
+
+	spi@7000dc00 {
+		compatible = "nvidia,tegra30-slink", "nvidia,tegra20-slink";
+		reg = <0x7000dc00 0x200>;
+		interrupts = <0 94 0x04>;
+		nvidia,dma-request-selector = <&apbdma 27>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "disabled";
+	};
+
+	spi@7000de00 {
+		compatible = "nvidia,tegra30-slink", "nvidia,tegra20-slink";
+		reg = <0x7000de00 0x200>;
+		interrupts = <0 79 0x04>;
+		nvidia,dma-request-selector = <&apbdma 28>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "disabled";
+	};
+
 	pmc {
 		compatible = "nvidia,tegra20-pmc", "nvidia,tegra30-pmc";
 		reg = <0x7000e400 0x400>;
diff --git a/arch/arm/boot/dts/u9540.dts b/arch/arm/boot/dts/u9540.dts
new file mode 100644
index 0000000..95892ec
--- /dev/null
+++ b/arch/arm/boot/dts/u9540.dts
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2012 ST-Ericsson AB
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/dts-v1/;
+/include/ "dbx5x0.dtsi"
+
+/ {
+	model = "ST-Ericsson U9540 platform with Device Tree";
+	compatible = "st-ericsson,u9540";
+
+	memory {
+		reg = <0x00000000 0x20000000>;
+	};
+
+	soc-u9500 {
+		uart@80120000 {
+			status = "okay";
+		};
+
+		uart@80121000 {
+			status = "okay";
+		};
+
+		uart@80007000 {
+			status = "okay";
+		};
+
+		// External Micro SD slot
+		sdi0_per1@80126000 {
+			arm,primecell-periphid = <0x10480180>;
+			max-frequency = <100000000>;
+			bus-width = <4>;
+			mmc-cap-sd-highspeed;
+			mmc-cap-mmc-highspeed;
+			vmmc-supply = <&ab8500_ldo_aux3_reg>;
+
+			cd-gpios  = <&gpio7 6 0x4>; // 230
+			cd-inverted;
+
+			status = "okay";
+		};
+
+
+		// WLAN SDIO channel
+		sdi1_per2@80118000 {
+			arm,primecell-periphid = <0x10480180>;
+			max-frequency = <50000000>;
+			bus-width = <4>;
+
+			status = "okay";
+		};
+
+		// On-board eMMC
+		sdi4_per2@80114000 {
+			arm,primecell-periphid = <0x10480180>;
+		        max-frequency = <100000000>;
+			bus-width = <8>;
+			mmc-cap-mmc-highspeed;
+			vmmc-supply = <&ab8500_ldo_aux2_reg>;
+
+			status = "okay";
+		};
+	};
+};
diff --git a/arch/arm/boot/dts/zynq-7000.dtsi b/arch/arm/boot/dts/zynq-7000.dtsi
new file mode 100644
index 0000000..401c126
--- /dev/null
+++ b/arch/arm/boot/dts/zynq-7000.dtsi
@@ -0,0 +1,166 @@
+/*
+ *  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.
+ */
+/include/ "skeleton.dtsi"
+
+/ {
+	compatible = "xlnx,zynq-7000";
+
+	amba {
+		compatible = "simple-bus";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		interrupt-parent = <&intc>;
+		ranges;
+
+		intc: interrupt-controller@f8f01000 {
+			compatible = "arm,cortex-a9-gic";
+			#interrupt-cells = <3>;
+			#address-cells = <1>;
+			interrupt-controller;
+			reg = <0xF8F01000 0x1000>,
+			      <0xF8F00100 0x100>;
+		};
+
+		L2: cache-controller {
+			compatible = "arm,pl310-cache";
+			reg = <0xF8F02000 0x1000>;
+			arm,data-latency = <2 3 2>;
+			arm,tag-latency = <2 3 2>;
+			cache-unified;
+			cache-level = <2>;
+		};
+
+		uart0: uart@e0000000 {
+			compatible = "xlnx,xuartps";
+			reg = <0xE0000000 0x1000>;
+			interrupts = <0 27 4>;
+			clock = <50000000>;
+		};
+
+		uart1: uart@e0001000 {
+			compatible = "xlnx,xuartps";
+			reg = <0xE0001000 0x1000>;
+			interrupts = <0 50 4>;
+			clock = <50000000>;
+		};
+
+		slcr: slcr@f8000000 {
+			compatible = "xlnx,zynq-slcr";
+			reg = <0xF8000000 0x1000>;
+
+			clocks {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				ps_clk: ps_clk {
+					#clock-cells = <0>;
+					compatible = "fixed-clock";
+					/* clock-frequency set in board-specific file */
+					clock-output-names = "ps_clk";
+				};
+				armpll: armpll {
+					#clock-cells = <0>;
+					compatible = "xlnx,zynq-pll";
+					clocks = <&ps_clk>;
+					reg = <0x100 0x110>;
+					clock-output-names = "armpll";
+				};
+				ddrpll: ddrpll {
+					#clock-cells = <0>;
+					compatible = "xlnx,zynq-pll";
+					clocks = <&ps_clk>;
+					reg = <0x104 0x114>;
+					clock-output-names = "ddrpll";
+				};
+				iopll: iopll {
+					#clock-cells = <0>;
+					compatible = "xlnx,zynq-pll";
+					clocks = <&ps_clk>;
+					reg = <0x108 0x118>;
+					clock-output-names = "iopll";
+				};
+				uart_clk: uart_clk {
+					#clock-cells = <1>;
+					compatible = "xlnx,zynq-periph-clock";
+					clocks = <&iopll &armpll &ddrpll>;
+					reg = <0x154>;
+					clock-output-names = "uart0_ref_clk",
+							     "uart1_ref_clk";
+				};
+				cpu_clk: cpu_clk {
+					#clock-cells = <1>;
+					compatible = "xlnx,zynq-cpu-clock";
+					clocks = <&iopll &armpll &ddrpll>;
+					reg = <0x120 0x1C4>;
+					clock-output-names = "cpu_6x4x",
+							     "cpu_3x2x",
+							     "cpu_2x",
+							     "cpu_1x";
+				};
+			};
+		};
+
+		ttc0: ttc0@f8001000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "xlnx,ttc";
+			reg = <0xF8001000 0x1000>;
+			clocks = <&cpu_clk 3>;
+			clock-names = "cpu_1x";
+			clock-ranges;
+
+			ttc0_0: ttc0.0 {
+				status = "disabled";
+				reg = <0>;
+				interrupts = <0 10 4>;
+			};
+			ttc0_1: ttc0.1 {
+				status = "disabled";
+				reg = <1>;
+				interrupts = <0 11 4>;
+			};
+			ttc0_2: ttc0.2 {
+				status = "disabled";
+				reg = <2>;
+				interrupts = <0 12 4>;
+			};
+		};
+
+		ttc1: ttc1@f8002000 {
+			#interrupt-parent = <&intc>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "xlnx,ttc";
+			reg = <0xF8002000 0x1000>;
+			clocks = <&cpu_clk 3>;
+			clock-names = "cpu_1x";
+			clock-ranges;
+
+			ttc1_0: ttc1.0 {
+				status = "disabled";
+				reg = <0>;
+				interrupts = <0 37 4>;
+			};
+			ttc1_1: ttc1.1 {
+				status = "disabled";
+				reg = <1>;
+				interrupts = <0 38 4>;
+			};
+			ttc1_2: ttc1.2 {
+				status = "disabled";
+				reg = <2>;
+				interrupts = <0 39 4>;
+			};
+		};
+	};
+};
diff --git a/arch/arm/boot/dts/zynq-ep107.dts b/arch/arm/boot/dts/zynq-ep107.dts
deleted file mode 100644
index 574bc04..0000000
--- a/arch/arm/boot/dts/zynq-ep107.dts
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- *  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.
- */
-
-/dts-v1/;
-/ {
-	model = "Xilinx Zynq EP107";
-	compatible = "xlnx,zynq-ep107";
-	#address-cells = <1>;
-	#size-cells = <1>;
-	interrupt-parent = <&intc>;
-
-	memory {
-		device_type = "memory";
-		reg = <0x0 0x10000000>;
-	};
-
-	chosen {
-		bootargs = "console=ttyPS0,9600 root=/dev/ram rw initrd=0x800000,8M earlyprintk";
-		linux,stdout-path = &uart0;
-	};
-
-	amba {
-		compatible = "simple-bus";
-		#address-cells = <1>;
-		#size-cells = <1>;
-		ranges;
-
-		intc: interrupt-controller@f8f01000 {
-			compatible = "arm,cortex-a9-gic";
-			#interrupt-cells = <3>;
-			#address-cells = <1>;
-			interrupt-controller;
-			reg = <0xF8F01000 0x1000>,
-			      <0xF8F00100 0x100>;
-		};
-
-		L2: cache-controller {
-			compatible = "arm,pl310-cache";
-			reg = <0xF8F02000 0x1000>;
-			arm,data-latency = <2 3 2>;
-			arm,tag-latency = <2 3 2>;
-			cache-unified;
-			cache-level = <2>;
-		};
-
-		uart0: uart@e0000000 {
-			compatible = "xlnx,xuartps";
-			reg = <0xE0000000 0x1000>;
-			interrupts = <0 27 4>;
-			clock = <50000000>;
-		};
-	};
-};
diff --git a/arch/arm/boot/dts/zynq-zc702.dts b/arch/arm/boot/dts/zynq-zc702.dts
new file mode 100644
index 0000000..c772942
--- /dev/null
+++ b/arch/arm/boot/dts/zynq-zc702.dts
@@ -0,0 +1,44 @@
+/*
+ *  Copyright (C) 2011 Xilinx
+ *  Copyright (C) 2012 National Instruments Corp.
+ *
+ * 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.
+ */
+/dts-v1/;
+/include/ "zynq-7000.dtsi"
+
+/ {
+	model = "Zynq ZC702 Development Board";
+	compatible = "xlnx,zynq-zc702", "xlnx,zynq-7000";
+
+	memory {
+		device_type = "memory";
+		reg = <0x0 0x40000000>;
+	};
+
+	chosen {
+		bootargs = "console=ttyPS1,115200 earlyprintk";
+	};
+
+};
+
+&ps_clk {
+	clock-frequency = <33333330>;
+};
+
+&ttc0_0 {
+	status = "ok";
+	compatible = "xlnx,ttc-counter-clocksource";
+};
+
+&ttc0_1 {
+	status = "ok";
+	compatible = "xlnx,ttc-counter-clockevent";
+};
diff --git a/arch/arm/configs/marzen_defconfig b/arch/arm/configs/marzen_defconfig
index 5b8215f..728a43c 100644
--- a/arch/arm/configs/marzen_defconfig
+++ b/arch/arm/configs/marzen_defconfig
@@ -47,6 +47,8 @@
 # CONFIG_STANDALONE is not set
 # CONFIG_PREVENT_FIRMWARE_BUILD is not set
 # CONFIG_FW_LOADER is not set
+CONFIG_SCSI=y
+CONFIG_BLK_DEV_SD=y
 CONFIG_NETDEVICES=y
 # CONFIG_NET_VENDOR_BROADCOM is not set
 # CONFIG_NET_VENDOR_FARADAY is not set
@@ -59,9 +61,8 @@
 # CONFIG_NET_VENDOR_STMICRO is not set
 # CONFIG_WLAN is not set
 # CONFIG_INPUT_MOUSEDEV is not set
-# CONFIG_INPUT_KEYBOARD is not set
+CONFIG_INPUT_EVDEV=y
 # CONFIG_INPUT_MOUSE is not set
-# CONFIG_SERIO is not set
 # CONFIG_VT is not set
 # CONFIG_LEGACY_PTYS is not set
 # CONFIG_DEVKMEM is not set
@@ -78,9 +79,16 @@
 CONFIG_THERMAL=y
 CONFIG_RCAR_THERMAL=y
 CONFIG_SSB=y
-# CONFIG_USB_SUPPORT is not set
+CONFIG_USB=y
+CONFIG_USB_RCAR_PHY=y
 CONFIG_MMC=y
 CONFIG_MMC_SDHI=y
+CONFIG_USB=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_OHCI_HCD_PLATFORM=y
+CONFIG_USB_EHCI_HCD_PLATFORM=y
+CONFIG_USB_STORAGE=y
 CONFIG_UIO=y
 CONFIG_UIO_PDRV_GENIRQ=y
 # CONFIG_IOMMU_SUPPORT is not set
diff --git a/arch/arm/configs/mxs_defconfig b/arch/arm/configs/mxs_defconfig
index 048aaca..7bf5351 100644
--- a/arch/arm/configs/mxs_defconfig
+++ b/arch/arm/configs/mxs_defconfig
@@ -61,6 +61,8 @@
 CONFIG_NETDEVICES=y
 CONFIG_NET_ETHERNET=y
 CONFIG_ENC28J60=y
+CONFIG_USB_USBNET=y
+CONFIG_USB_NET_SMSC95XX=y
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
 # CONFIG_WLAN is not set
@@ -158,6 +160,10 @@
 CONFIG_NFS_V3_ACL=y
 CONFIG_NFS_V4=y
 CONFIG_ROOT_NFS=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_CODEPAGE_850=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_ISO8859_15=y
 CONFIG_PRINTK_TIME=y
 CONFIG_FRAME_WARN=2048
 CONFIG_MAGIC_SYSRQ=y
diff --git a/arch/arm/configs/u8500_defconfig b/arch/arm/configs/u8500_defconfig
index 250625d..231dca6 100644
--- a/arch/arm/configs/u8500_defconfig
+++ b/arch/arm/configs/u8500_defconfig
@@ -78,6 +78,7 @@
 CONFIG_REGULATOR=y
 CONFIG_REGULATOR_AB8500=y
 CONFIG_REGULATOR_FIXED_VOLTAGE=y
+CONFIG_REGULATOR_GPIO=y
 # CONFIG_HID_SUPPORT is not set
 CONFIG_USB_GADGET=y
 CONFIG_AB8500_USB=y
diff --git a/arch/arm/include/debug/imx.S b/arch/arm/include/debug/imx.S
index 0b65d79..0c4e17d 100644
--- a/arch/arm/include/debug/imx.S
+++ b/arch/arm/include/debug/imx.S
@@ -10,6 +10,20 @@
  * published by the Free Software Foundation.
  *
  */
+#define IMX6Q_UART1_BASE_ADDR	0x02020000
+#define IMX6Q_UART2_BASE_ADDR	0x021e8000
+#define IMX6Q_UART3_BASE_ADDR	0x021ec000
+#define IMX6Q_UART4_BASE_ADDR	0x021f0000
+#define IMX6Q_UART5_BASE_ADDR	0x021f4000
+
+/*
+ * IMX6Q_UART_BASE_ADDR is put in the middle to force the expansion
+ * of IMX6Q_UART##n##_BASE_ADDR.
+ */
+#define IMX6Q_UART_BASE_ADDR(n)	IMX6Q_UART##n##_BASE_ADDR
+#define IMX6Q_UART_BASE(n)	IMX6Q_UART_BASE_ADDR(n)
+#define IMX6Q_DEBUG_UART_BASE	IMX6Q_UART_BASE(CONFIG_DEBUG_IMX6Q_UART_PORT)
+
 #ifdef CONFIG_DEBUG_IMX1_UART
 #define UART_PADDR	0x00206000
 #elif defined (CONFIG_DEBUG_IMX25_UART)
@@ -22,10 +36,8 @@
 #define UART_PADDR	0x73fbc000
 #elif defined (CONFIG_DEBUG_IMX50_IMX53_UART)
 #define UART_PADDR	0x53fbc000
-#elif defined (CONFIG_DEBUG_IMX6Q_UART2)
-#define UART_PADDR	0x021e8000
-#elif defined (CONFIG_DEBUG_IMX6Q_UART4)
-#define UART_PADDR	0x021f0000
+#elif defined (CONFIG_DEBUG_IMX6Q_UART)
+#define UART_PADDR	IMX6Q_DEBUG_UART_BASE
 #endif
 
 /*
diff --git a/arch/arm/include/debug/tegra.S b/arch/arm/include/debug/tegra.S
new file mode 100644
index 0000000..883d7c2
--- /dev/null
+++ b/arch/arm/include/debug/tegra.S
@@ -0,0 +1,223 @@
+/*
+ * 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
+ * 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/serial_reg.h>
+
+#define UART_SHIFT 2
+
+/* Physical addresses */
+#define TEGRA_CLK_RESET_BASE		0x60006000
+#define TEGRA_APB_MISC_BASE		0x70000000
+#define TEGRA_UARTA_BASE		0x70006000
+#define TEGRA_UARTB_BASE		0x70006040
+#define TEGRA_UARTC_BASE		0x70006200
+#define TEGRA_UARTD_BASE		0x70006300
+#define TEGRA_UARTE_BASE		0x70006400
+#define TEGRA_PMC_BASE			0x7000e400
+
+#define TEGRA_CLK_RST_DEVICES_L		(TEGRA_CLK_RESET_BASE + 0x04)
+#define TEGRA_CLK_RST_DEVICES_H		(TEGRA_CLK_RESET_BASE + 0x08)
+#define TEGRA_CLK_RST_DEVICES_U		(TEGRA_CLK_RESET_BASE + 0x0c)
+#define TEGRA_CLK_OUT_ENB_L		(TEGRA_CLK_RESET_BASE + 0x10)
+#define TEGRA_CLK_OUT_ENB_H		(TEGRA_CLK_RESET_BASE + 0x14)
+#define TEGRA_CLK_OUT_ENB_U		(TEGRA_CLK_RESET_BASE + 0x18)
+#define TEGRA_PMC_SCRATCH20		(TEGRA_PMC_BASE + 0xa0)
+#define TEGRA_APB_MISC_GP_HIDREV	(TEGRA_APB_MISC_BASE + 0x804)
+
+/*
+ * Must be 1MB-aligned since a 1MB mapping is used early on.
+ * Must not overlap with regions in mach-tegra/io.c:tegra_io_desc[].
+ */
+#define UART_VIRTUAL_BASE		0xfe100000
+
+#define checkuart(rp, rv, lhu, bit, uart) \
+		/* Load address of CLK_RST register */ \
+		movw	rp, #TEGRA_CLK_RST_DEVICES_##lhu & 0xffff ; \
+		movt	rp, #TEGRA_CLK_RST_DEVICES_##lhu >> 16 ; \
+		/* Load value from CLK_RST register */ \
+		ldr	rp, [rp, #0] ; \
+		/* Test UART's reset bit */ \
+		tst	rp, #(1 << bit) ; \
+		/* If set, can't use UART; jump to save no UART */ \
+		bne	90f ; \
+		/* Load address of CLK_OUT_ENB register */ \
+		movw	rp, #TEGRA_CLK_OUT_ENB_##lhu & 0xffff ; \
+		movt	rp, #TEGRA_CLK_OUT_ENB_##lhu >> 16 ; \
+		/* Load value from CLK_OUT_ENB register */ \
+		ldr	rp, [rp, #0] ; \
+		/* Test UART's clock enable bit */ \
+		tst	rp, #(1 << bit) ; \
+		/* If clear, can't use UART; jump to save no UART */ \
+		beq	90f ; \
+		/* Passed all tests, load address of UART registers */ \
+		movw	rp, #TEGRA_UART##uart##_BASE & 0xffff ; \
+		movt	rp, #TEGRA_UART##uart##_BASE >> 16 ; \
+		/* Jump to save UART address */ \
+		b 91f
+
+		.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 initialization?
+		bne	100f			@ no; go load the addresses
+		mov	\rv, #0			@ yes; record init is done
+		str	\rv, [\tmp]
+
+#ifdef CONFIG_TEGRA_DEBUG_UART_AUTO_ODMDATA
+		/* Check ODMDATA */
+10:		movw	\rp, #TEGRA_PMC_SCRATCH20 & 0xffff
+		movt	\rp, #TEGRA_PMC_SCRATCH20 >> 16
+		ldr	\rp, [\rp, #0]		@ Load PMC_SCRATCH20
+		ubfx	\rv, \rp, #18, #2	@ 19:18 are console type
+		cmp	\rv, #2			@ 2 and 3 mean DCC, UART
+		beq	11f			@ some boards swap the meaning
+		cmp	\rv, #3			@ so accept either
+		bne	90f
+11:		ubfx	\rv, \rp, #15, #3	@ 17:15 are UART ID
+		cmp	\rv, #0			@ UART 0?
+		beq	20f
+		cmp	\rv, #1			@ UART 1?
+		beq	21f
+		cmp	\rv, #2			@ UART 2?
+		beq	22f
+		cmp	\rv, #3			@ UART 3?
+		beq	23f
+		cmp	\rv, #4			@ UART 4?
+		beq	24f
+		b	90f			@ invalid
+#endif
+
+#if defined(CONFIG_TEGRA_DEBUG_UARTA) || \
+    defined(CONFIG_TEGRA_DEBUG_UART_AUTO_ODMDATA)
+		/* Check UART A validity */
+20:		checkuart(\rp, \rv, L, 6, A)
+#endif
+
+#if defined(CONFIG_TEGRA_DEBUG_UARTB) || \
+    defined(CONFIG_TEGRA_DEBUG_UART_AUTO_ODMDATA)
+		/* Check UART B validity */
+21:		checkuart(\rp, \rv, L, 7, B)
+#endif
+
+#if defined(CONFIG_TEGRA_DEBUG_UARTC) || \
+    defined(CONFIG_TEGRA_DEBUG_UART_AUTO_ODMDATA)
+		/* Check UART C validity */
+22:		checkuart(\rp, \rv, H, 23, C)
+#endif
+
+#if defined(CONFIG_TEGRA_DEBUG_UARTD) || \
+    defined(CONFIG_TEGRA_DEBUG_UART_AUTO_ODMDATA)
+		/* Check UART D validity */
+23:		checkuart(\rp, \rv, U, 1, D)
+#endif
+
+#if defined(CONFIG_TEGRA_DEBUG_UARTE) || \
+    defined(CONFIG_TEGRA_DEBUG_UART_AUTO_ODMDATA)
+		/* Check UART E validity */
+24:
+		checkuart(\rp, \rv, U, 2, E)
+#endif
+
+		/* No valid UART found */
+90:		mov	\rp, #0
+		/* fall through */
+
+		/* Record whichever UART we chose */
+91:		str	\rp, [\tmp, #4]		@ Store in tegra_uart_phys
+		cmp	\rp, #0			@ Valid UART address?
+		bne	92f			@ Yes, go process it
+		str	\rp, [\tmp, #8]		@ Store 0 in tegra_uart_virt
+		b	100f			@ Done
+92:		and	\rv, \rp, #0xffffff	@ offset within 1MB section
+		add	\rv, \rv, #UART_VIRTUAL_BASE
+		str	\rv, [\tmp, #8]		@ Store in tegra_uart_virt
+		movw	\rv, #TEGRA_APB_MISC_GP_HIDREV & 0xffff
+		movt	\rv, #TEGRA_APB_MISC_GP_HIDREV >> 16
+		ldr	\rv, [\rv, #0]		@ Load HIDREV
+		ubfx	\rv, \rv, #8, #8	@ 15:8 are SoC version
+		cmp	\rv, #0x20		@ Tegra20?
+		moveq	\rv, #0x75		@ Tegra20 divisor
+		movne	\rv, #0xdd		@ Tegra30 divisor
+		str	\rv, [\tmp, #12]	@ Save divisor to scratch
+		/* uart[UART_LCR] = UART_LCR_WLEN8 | UART_LCR_DLAB; */
+		mov	\rv, #UART_LCR_WLEN8 | UART_LCR_DLAB
+		str	\rv, [\rp, #UART_LCR << UART_SHIFT]
+		/* uart[UART_DLL] = div & 0xff; */
+		ldr	\rv, [\tmp, #12]
+		and	\rv, \rv, #0xff
+		str	\rv, [\rp, #UART_DLL << UART_SHIFT]
+		/* uart[UART_DLM] = div >> 8; */
+		ldr	\rv, [\tmp, #12]
+		lsr	\rv, \rv, #8
+		str	\rv, [\rp, #UART_DLM << UART_SHIFT]
+		/* uart[UART_LCR] = UART_LCR_WLEN8; */
+		mov	\rv, #UART_LCR_WLEN8
+		str	\rv, [\rp, #UART_LCR << UART_SHIFT]
+		b	100f
+
+		.align
+99:		.word	.
+		.word	tegra_uart_config
+		.ltorg
+
+		/* Load previously selected UART address */
+100:		ldr	\rp, [\tmp, #4]		@ Load tegra_uart_phys
+		ldr	\rv, [\tmp, #8]		@ Load tegra_uart_virt
+		.endm
+
+/*
+ * Code below is swiped from <asm/hardware/debug-8250.S>, but add an extra
+ * check to make sure that the UART address is actually valid.
+ */
+
+		.macro	senduart, rd, rx
+		cmp	\rx, #0
+		strneb	\rd, [\rx, #UART_TX << UART_SHIFT]
+1001:
+		.endm
+
+		.macro	busyuart, rd, rx
+		cmp	\rx, #0
+		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
+		cmp	\rx, #0
+		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-zynq/include/mach/debug-macro.S b/arch/arm/include/debug/zynq.S
similarity index 61%
rename from arch/arm/mach-zynq/include/mach/debug-macro.S
rename to arch/arm/include/debug/zynq.S
index 3ab0be1..f9aa974 100644
--- a/arch/arm/mach-zynq/include/mach/debug-macro.S
+++ b/arch/arm/include/debug/zynq.S
@@ -1,5 +1,4 @@
-/* arch/arm/mach-zynq/include/mach/debug-macro.S
- *
+/*
  * Debugging macro include header
  *
  *  Copyright (C) 2011 Xilinx
@@ -13,9 +12,25 @@
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  */
+#define UART_CR_OFFSET		0x00  /* Control Register [8:0] */
+#define UART_SR_OFFSET		0x2C  /* Channel Status [11:0] */
+#define UART_FIFO_OFFSET	0x30  /* FIFO [15:0] or [7:0] */
 
-#include <mach/zynq_soc.h>
-#include <mach/uart.h>
+#define UART_SR_TXFULL		0x00000010	/* TX FIFO full */
+#define UART_SR_TXEMPTY		0x00000008	/* TX FIFO empty */
+
+#define UART0_PHYS		0xE0000000
+#define UART1_PHYS		0xE0001000
+#define UART_SIZE		SZ_4K
+#define UART_VIRT		0xF0001000
+
+#if IS_ENABLED(CONFIG_DEBUG_ZYNQ_UART1)
+# define LL_UART_PADDR		UART1_PHYS
+#else
+# define LL_UART_PADDR		UART0_PHYS
+#endif
+
+#define LL_UART_VADDR		UART_VIRT
 
 		.macro	addruart, rp, rv, tmp
 		ldr	\rp, =LL_UART_PADDR	@ physical
diff --git a/arch/arm/kernel/kprobes-test.c b/arch/arm/kernel/kprobes-test.c
index 1862d8f..0cd63d0 100644
--- a/arch/arm/kernel/kprobes-test.c
+++ b/arch/arm/kernel/kprobes-test.c
@@ -1598,7 +1598,7 @@
 {
 	int ret = 0;
 
-	pr_info("Begining kprobe tests...\n");
+	pr_info("Beginning kprobe tests...\n");
 
 #ifndef CONFIG_THUMB2_KERNEL
 
diff --git a/arch/arm/mach-at91/at91rm9200.c b/arch/arm/mach-at91/at91rm9200.c
index 8ce0682..7aeb473 100644
--- a/arch/arm/mach-at91/at91rm9200.c
+++ b/arch/arm/mach-at91/at91rm9200.c
@@ -184,9 +184,12 @@
 	CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.1", &tc3_clk),
 	CLKDEV_CON_DEV_ID("t1_clk", "atmel_tcb.1", &tc4_clk),
 	CLKDEV_CON_DEV_ID("t2_clk", "atmel_tcb.1", &tc5_clk),
-	CLKDEV_CON_DEV_ID("pclk", "ssc.0", &ssc0_clk),
-	CLKDEV_CON_DEV_ID("pclk", "ssc.1", &ssc1_clk),
-	CLKDEV_CON_DEV_ID("pclk", "ssc.2", &ssc2_clk),
+	CLKDEV_CON_DEV_ID("pclk", "at91rm9200_ssc.0", &ssc0_clk),
+	CLKDEV_CON_DEV_ID("pclk", "at91rm9200_ssc.1", &ssc1_clk),
+	CLKDEV_CON_DEV_ID("pclk", "at91rm9200_ssc.2", &ssc2_clk),
+	CLKDEV_CON_DEV_ID("pclk", "fffd0000.ssc", &ssc0_clk),
+	CLKDEV_CON_DEV_ID("pclk", "fffd4000.ssc", &ssc1_clk),
+	CLKDEV_CON_DEV_ID("pclk", "fffd8000.ssc", &ssc2_clk),
 	CLKDEV_CON_DEV_ID(NULL, "i2c-at91rm9200.0", &twi_clk),
 	/* fake hclk clock */
 	CLKDEV_CON_DEV_ID("hclk", "at91_ohci", &ohci_clk),
diff --git a/arch/arm/mach-at91/at91rm9200_devices.c b/arch/arm/mach-at91/at91rm9200_devices.c
index 2a1f8e6..3ebc979 100644
--- a/arch/arm/mach-at91/at91rm9200_devices.c
+++ b/arch/arm/mach-at91/at91rm9200_devices.c
@@ -752,7 +752,7 @@
 };
 
 static struct platform_device at91rm9200_ssc0_device = {
-	.name	= "ssc",
+	.name	= "at91rm9200_ssc",
 	.id	= 0,
 	.dev	= {
 		.dma_mask		= &ssc0_dmamask,
@@ -794,7 +794,7 @@
 };
 
 static struct platform_device at91rm9200_ssc1_device = {
-	.name	= "ssc",
+	.name	= "at91rm9200_ssc",
 	.id	= 1,
 	.dev	= {
 		.dma_mask		= &ssc1_dmamask,
@@ -836,7 +836,7 @@
 };
 
 static struct platform_device at91rm9200_ssc2_device = {
-	.name	= "ssc",
+	.name	= "at91rm9200_ssc",
 	.id	= 2,
 	.dev	= {
 		.dma_mask		= &ssc2_dmamask,
diff --git a/arch/arm/mach-at91/at91sam9260.c b/arch/arm/mach-at91/at91sam9260.c
index c65e7b8..b67cd53 100644
--- a/arch/arm/mach-at91/at91sam9260.c
+++ b/arch/arm/mach-at91/at91sam9260.c
@@ -210,7 +210,8 @@
 	CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.1", &tc3_clk),
 	CLKDEV_CON_DEV_ID("t1_clk", "atmel_tcb.1", &tc4_clk),
 	CLKDEV_CON_DEV_ID("t2_clk", "atmel_tcb.1", &tc5_clk),
-	CLKDEV_CON_DEV_ID("pclk", "ssc.0", &ssc_clk),
+	CLKDEV_CON_DEV_ID("pclk", "at91rm9200_ssc.0", &ssc_clk),
+	CLKDEV_CON_DEV_ID("pclk", "fffbc000.ssc", &ssc_clk),
 	CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9260.0", &twi_clk),
 	CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9g20.0", &twi_clk),
 	/* more usart lookup table for DT entries */
diff --git a/arch/arm/mach-at91/at91sam9260_devices.c b/arch/arm/mach-at91/at91sam9260_devices.c
index 1f6fac2..eda8d16 100644
--- a/arch/arm/mach-at91/at91sam9260_devices.c
+++ b/arch/arm/mach-at91/at91sam9260_devices.c
@@ -742,7 +742,7 @@
 };
 
 static struct platform_device at91sam9260_ssc_device = {
-	.name	= "ssc",
+	.name	= "at91rm9200_ssc",
 	.id	= 0,
 	.dev	= {
 		.dma_mask		= &ssc_dmamask,
diff --git a/arch/arm/mach-at91/at91sam9261.c b/arch/arm/mach-at91/at91sam9261.c
index 9d3e9b8..2998a08 100644
--- a/arch/arm/mach-at91/at91sam9261.c
+++ b/arch/arm/mach-at91/at91sam9261.c
@@ -174,9 +174,12 @@
 	CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.0", &tc0_clk),
 	CLKDEV_CON_DEV_ID("t1_clk", "atmel_tcb.0", &tc1_clk),
 	CLKDEV_CON_DEV_ID("t2_clk", "atmel_tcb.0", &tc2_clk),
-	CLKDEV_CON_DEV_ID("pclk", "ssc.0", &ssc0_clk),
-	CLKDEV_CON_DEV_ID("pclk", "ssc.1", &ssc1_clk),
-	CLKDEV_CON_DEV_ID("pclk", "ssc.2", &ssc2_clk),
+	CLKDEV_CON_DEV_ID("pclk", "at91rm9200_ssc.0", &ssc0_clk),
+	CLKDEV_CON_DEV_ID("pclk", "at91rm9200_ssc.1", &ssc1_clk),
+	CLKDEV_CON_DEV_ID("pclk", "at91rm9200_ssc.2", &ssc2_clk),
+	CLKDEV_CON_DEV_ID("pclk", "fffbc000.ssc", &ssc0_clk),
+	CLKDEV_CON_DEV_ID("pclk", "fffc0000.ssc", &ssc1_clk),
+	CLKDEV_CON_DEV_ID("pclk", "fffc4000.ssc", &ssc2_clk),
 	CLKDEV_CON_DEV_ID("hclk", "at91_ohci", &hck0),
 	CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9261.0", &twi_clk),
 	CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9g10.0", &twi_clk),
diff --git a/arch/arm/mach-at91/at91sam9261_devices.c b/arch/arm/mach-at91/at91sam9261_devices.c
index 6ce6d27..92e0f86 100644
--- a/arch/arm/mach-at91/at91sam9261_devices.c
+++ b/arch/arm/mach-at91/at91sam9261_devices.c
@@ -706,7 +706,7 @@
 };
 
 static struct platform_device at91sam9261_ssc0_device = {
-	.name	= "ssc",
+	.name	= "at91rm9200_ssc",
 	.id	= 0,
 	.dev	= {
 		.dma_mask		= &ssc0_dmamask,
@@ -748,7 +748,7 @@
 };
 
 static struct platform_device at91sam9261_ssc1_device = {
-	.name	= "ssc",
+	.name	= "at91rm9200_ssc",
 	.id	= 1,
 	.dev	= {
 		.dma_mask		= &ssc1_dmamask,
@@ -790,7 +790,7 @@
 };
 
 static struct platform_device at91sam9261_ssc2_device = {
-	.name	= "ssc",
+	.name	= "at91rm9200_ssc",
 	.id	= 2,
 	.dev	= {
 		.dma_mask		= &ssc2_dmamask,
diff --git a/arch/arm/mach-at91/at91sam9263.c b/arch/arm/mach-at91/at91sam9263.c
index 82deb4d..b9fc60d 100644
--- a/arch/arm/mach-at91/at91sam9263.c
+++ b/arch/arm/mach-at91/at91sam9263.c
@@ -186,8 +186,10 @@
 static struct clk_lookup periph_clocks_lookups[] = {
 	/* One additional fake clock for macb_hclk */
 	CLKDEV_CON_ID("hclk", &macb_clk),
-	CLKDEV_CON_DEV_ID("pclk", "ssc.0", &ssc0_clk),
-	CLKDEV_CON_DEV_ID("pclk", "ssc.1", &ssc1_clk),
+	CLKDEV_CON_DEV_ID("pclk", "at91rm9200_ssc.0", &ssc0_clk),
+	CLKDEV_CON_DEV_ID("pclk", "at91rm9200_ssc.1", &ssc1_clk),
+	CLKDEV_CON_DEV_ID("pclk", "fff98000.ssc", &ssc0_clk),
+	CLKDEV_CON_DEV_ID("pclk", "fff9c000.ssc", &ssc1_clk),
 	CLKDEV_CON_DEV_ID("mci_clk", "atmel_mci.0", &mmc0_clk),
 	CLKDEV_CON_DEV_ID("mci_clk", "atmel_mci.1", &mmc1_clk),
 	CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.0", &spi0_clk),
diff --git a/arch/arm/mach-at91/at91sam9263_devices.c b/arch/arm/mach-at91/at91sam9263_devices.c
index fb98163b..ed666f5 100644
--- a/arch/arm/mach-at91/at91sam9263_devices.c
+++ b/arch/arm/mach-at91/at91sam9263_devices.c
@@ -1199,7 +1199,7 @@
 };
 
 static struct platform_device at91sam9263_ssc0_device = {
-	.name	= "ssc",
+	.name	= "at91rm9200_ssc",
 	.id	= 0,
 	.dev	= {
 		.dma_mask		= &ssc0_dmamask,
@@ -1241,7 +1241,7 @@
 };
 
 static struct platform_device at91sam9263_ssc1_device = {
-	.name	= "ssc",
+	.name	= "at91rm9200_ssc",
 	.id	= 1,
 	.dev	= {
 		.dma_mask		= &ssc1_dmamask,
diff --git a/arch/arm/mach-at91/at91sam9g45.c b/arch/arm/mach-at91/at91sam9g45.c
index 45d753d..d3addee 100644
--- a/arch/arm/mach-at91/at91sam9g45.c
+++ b/arch/arm/mach-at91/at91sam9g45.c
@@ -239,8 +239,10 @@
 	CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.1", &tcb0_clk),
 	CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9g10.0", &twi0_clk),
 	CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9g10.1", &twi1_clk),
-	CLKDEV_CON_DEV_ID("pclk", "ssc.0", &ssc0_clk),
-	CLKDEV_CON_DEV_ID("pclk", "ssc.1", &ssc1_clk),
+	CLKDEV_CON_DEV_ID("pclk", "at91sam9g45_ssc.0", &ssc0_clk),
+	CLKDEV_CON_DEV_ID("pclk", "at91sam9g45_ssc.1", &ssc1_clk),
+	CLKDEV_CON_DEV_ID("pclk", "fff9c000.ssc", &ssc0_clk),
+	CLKDEV_CON_DEV_ID("pclk", "fffa0000.ssc", &ssc1_clk),
 	CLKDEV_CON_DEV_ID(NULL, "atmel-trng", &trng_clk),
 	CLKDEV_CON_DEV_ID(NULL, "atmel_sha", &aestdessha_clk),
 	CLKDEV_CON_DEV_ID(NULL, "atmel_tdes", &aestdessha_clk),
diff --git a/arch/arm/mach-at91/at91sam9g45_devices.c b/arch/arm/mach-at91/at91sam9g45_devices.c
index e359642..827c9f2 100644
--- a/arch/arm/mach-at91/at91sam9g45_devices.c
+++ b/arch/arm/mach-at91/at91sam9g45_devices.c
@@ -1459,7 +1459,7 @@
 };
 
 static struct platform_device at91sam9g45_ssc0_device = {
-	.name	= "ssc",
+	.name	= "at91sam9g45_ssc",
 	.id	= 0,
 	.dev	= {
 		.dma_mask		= &ssc0_dmamask,
@@ -1501,7 +1501,7 @@
 };
 
 static struct platform_device at91sam9g45_ssc1_device = {
-	.name	= "ssc",
+	.name	= "at91sam9g45_ssc",
 	.id	= 1,
 	.dev	= {
 		.dma_mask		= &ssc1_dmamask,
diff --git a/arch/arm/mach-at91/at91sam9rl.c b/arch/arm/mach-at91/at91sam9rl.c
index 44e3a63..eb98704 100644
--- a/arch/arm/mach-at91/at91sam9rl.c
+++ b/arch/arm/mach-at91/at91sam9rl.c
@@ -184,8 +184,10 @@
 	CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.0", &tc0_clk),
 	CLKDEV_CON_DEV_ID("t1_clk", "atmel_tcb.0", &tc1_clk),
 	CLKDEV_CON_DEV_ID("t2_clk", "atmel_tcb.0", &tc2_clk),
-	CLKDEV_CON_DEV_ID("pclk", "ssc.0", &ssc0_clk),
-	CLKDEV_CON_DEV_ID("pclk", "ssc.1", &ssc1_clk),
+	CLKDEV_CON_DEV_ID("pclk", "at91rm9200_ssc.0", &ssc0_clk),
+	CLKDEV_CON_DEV_ID("pclk", "at91rm9200_ssc.1", &ssc1_clk),
+	CLKDEV_CON_DEV_ID("pclk", "fffc0000.ssc", &ssc0_clk),
+	CLKDEV_CON_DEV_ID("pclk", "fffc4000.ssc", &ssc1_clk),
 	CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9g20.0", &twi0_clk),
 	CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9g20.1", &twi1_clk),
 	CLKDEV_CON_ID("pioA", &pioA_clk),
diff --git a/arch/arm/mach-at91/at91sam9rl_devices.c b/arch/arm/mach-at91/at91sam9rl_devices.c
index 160384d..ddf223f 100644
--- a/arch/arm/mach-at91/at91sam9rl_devices.c
+++ b/arch/arm/mach-at91/at91sam9rl_devices.c
@@ -832,7 +832,7 @@
 };
 
 static struct platform_device at91sam9rl_ssc0_device = {
-	.name	= "ssc",
+	.name	= "at91rm9200_ssc",
 	.id	= 0,
 	.dev	= {
 		.dma_mask		= &ssc0_dmamask,
@@ -874,7 +874,7 @@
 };
 
 static struct platform_device at91sam9rl_ssc1_device = {
-	.name	= "ssc",
+	.name	= "at91rm9200_ssc",
 	.id	= 1,
 	.dev	= {
 		.dma_mask		= &ssc1_dmamask,
diff --git a/arch/arm/mach-at91/at91sam9x5.c b/arch/arm/mach-at91/at91sam9x5.c
index dfb2c0c..44a9a62 100644
--- a/arch/arm/mach-at91/at91sam9x5.c
+++ b/arch/arm/mach-at91/at91sam9x5.c
@@ -233,6 +233,7 @@
 	CLKDEV_CON_DEV_ID("mci_clk", "f000c000.mmc", &mmc1_clk),
 	CLKDEV_CON_DEV_ID("dma_clk", "ffffec00.dma-controller", &dma0_clk),
 	CLKDEV_CON_DEV_ID("dma_clk", "ffffee00.dma-controller", &dma1_clk),
+	CLKDEV_CON_DEV_ID("pclk", "f0010000.ssc", &ssc_clk),
 	CLKDEV_CON_DEV_ID(NULL, "f8010000.i2c", &twi0_clk),
 	CLKDEV_CON_DEV_ID(NULL, "f8014000.i2c", &twi1_clk),
 	CLKDEV_CON_DEV_ID(NULL, "f8018000.i2c", &twi2_clk),
diff --git a/arch/arm/mach-at91/board-sam9g20ek.c b/arch/arm/mach-at91/board-sam9g20ek.c
index 7b51238..1b7dd9f 100644
--- a/arch/arm/mach-at91/board-sam9g20ek.c
+++ b/arch/arm/mach-at91/board-sam9g20ek.c
@@ -353,6 +353,16 @@
         },
 };
 
+static struct platform_device sam9g20ek_audio_device = {
+	.name   = "at91sam9g20ek-audio",
+	.id     = -1,
+};
+
+static void __init ek_add_device_audio(void)
+{
+	platform_device_register(&sam9g20ek_audio_device);
+}
+
 
 static void __init ek_board_init(void)
 {
@@ -394,6 +404,7 @@
 	at91_set_B_periph(AT91_PIN_PC1, 0);
 	/* SSC (for WM8731) */
 	at91_add_device_ssc(AT91SAM9260_ID_SSC, ATMEL_SSC_TX);
+	ek_add_device_audio();
 }
 
 MACHINE_START(AT91SAM9G20EK, "Atmel AT91SAM9G20-EK")
diff --git a/arch/arm/mach-davinci/Makefile.boot b/arch/arm/mach-davinci/Makefile.boot
index 5c5a95a..04a6c4e 100644
--- a/arch/arm/mach-davinci/Makefile.boot
+++ b/arch/arm/mach-davinci/Makefile.boot
@@ -11,5 +11,3 @@
 params_phys-y	:= 0x80000100
 initrd_phys-y	:= 0x80800000
 endif
-
-dtb-$(CONFIG_MACH_DA8XX_DT)	+= da850-enbw-cmc.dtb da850-evm.dtb
diff --git a/arch/arm/mach-davinci/board-da850-evm.c b/arch/arm/mach-davinci/board-da850-evm.c
index d4f4dbf..7211772 100644
--- a/arch/arm/mach-davinci/board-da850-evm.c
+++ b/arch/arm/mach-davinci/board-da850-evm.c
@@ -763,16 +763,19 @@
 };
 
 static struct snd_platform_data da850_evm_snd_data = {
-	.tx_dma_offset	= 0x2000,
-	.rx_dma_offset	= 0x2000,
-	.op_mode	= DAVINCI_MCASP_IIS_MODE,
-	.num_serializer	= ARRAY_SIZE(da850_iis_serializer_direction),
-	.tdm_slots	= 2,
-	.serial_dir	= da850_iis_serializer_direction,
-	.asp_chan_q	= EVENTQ_0,
-	.version	= MCASP_VERSION_2,
-	.txnumevt	= 1,
-	.rxnumevt	= 1,
+	.tx_dma_offset		= 0x2000,
+	.rx_dma_offset		= 0x2000,
+	.op_mode		= DAVINCI_MCASP_IIS_MODE,
+	.num_serializer		= ARRAY_SIZE(da850_iis_serializer_direction),
+	.tdm_slots		= 2,
+	.serial_dir		= da850_iis_serializer_direction,
+	.asp_chan_q		= EVENTQ_0,
+	.ram_chan_q		= EVENTQ_1,
+	.version		= MCASP_VERSION_2,
+	.txnumevt		= 1,
+	.rxnumevt		= 1,
+	.sram_size_playback	= SZ_8K,
+	.sram_size_capture	= SZ_8K,
 };
 
 static const short da850_evm_mcasp_pins[] __initconst = {
@@ -1510,6 +1513,7 @@
 		pr_warning("da850_evm_init: mcasp mux setup failed: %d\n",
 				ret);
 
+	da850_evm_snd_data.sram_pool = sram_get_gen_pool();
 	da8xx_register_mcasp(0, &da850_evm_snd_data);
 
 	ret = davinci_cfg_reg_list(da850_lcdcntl_pins);
diff --git a/arch/arm/mach-exynos/Kconfig b/arch/arm/mach-exynos/Kconfig
index 070c7b6..91d5b6f 100644
--- a/arch/arm/mach-exynos/Kconfig
+++ b/arch/arm/mach-exynos/Kconfig
@@ -63,6 +63,7 @@
 	depends on ARCH_EXYNOS5
 	select S5P_PM if PM
 	select S5P_SLEEP if PM
+	select S5P_DEV_MFC
 	select SAMSUNG_DMADEV
 	help
 	  Enable EXYNOS5250 SoC support
diff --git a/arch/arm/mach-exynos/Makefile b/arch/arm/mach-exynos/Makefile
index 66135ee..b189881 100644
--- a/arch/arm/mach-exynos/Makefile
+++ b/arch/arm/mach-exynos/Makefile
@@ -52,7 +52,6 @@
 obj-$(CONFIG_EXYNOS4_DEV_AHCI)		+= dev-ahci.o
 obj-$(CONFIG_EXYNOS_DEV_DMA)		+= dma.o
 obj-$(CONFIG_EXYNOS4_DEV_USB_OHCI)	+= dev-ohci.o
-obj-$(CONFIG_EXYNOS_DEV_DRM)		+= dev-drm.o
 obj-$(CONFIG_EXYNOS_DEV_SYSMMU)		+= dev-sysmmu.o
 
 obj-$(CONFIG_ARCH_EXYNOS)		+= setup-i2c0.o
diff --git a/arch/arm/mach-exynos/clock-exynos4.c b/arch/arm/mach-exynos/clock-exynos4.c
index fa8a134..efead60 100644
--- a/arch/arm/mach-exynos/clock-exynos4.c
+++ b/arch/arm/mach-exynos/clock-exynos4.c
@@ -576,6 +576,10 @@
 		.enable		= exynos4_clk_ip_peril_ctrl,
 		.ctrlbit	= (1 << 15),
 	}, {
+		.name		= "tmu_apbif",
+		.enable		= exynos4_clk_ip_perir_ctrl,
+		.ctrlbit	= (1 << 17),
+	}, {
 		.name		= "keypad",
 		.enable		= exynos4_clk_ip_perir_ctrl,
 		.ctrlbit	= (1 << 16),
diff --git a/arch/arm/mach-exynos/clock-exynos5.c b/arch/arm/mach-exynos/clock-exynos5.c
index 4478757..7652f5d 100644
--- a/arch/arm/mach-exynos/clock-exynos5.c
+++ b/arch/arm/mach-exynos/clock-exynos5.c
@@ -196,6 +196,11 @@
 	return s5p_gatectrl(EXYNOS5_CLKGATE_IP_ISP1, clk, enable);
 }
 
+static int exynos5_clk_hdmiphy_ctrl(struct clk *clk, int enable)
+{
+	return s5p_gatectrl(S5P_HDMI_PHY_CONTROL, clk, enable);
+}
+
 /* Core list of CMU_CPU side */
 
 static struct clksrc_clk exynos5_clk_mout_apll = {
@@ -616,6 +621,11 @@
 		.enable		= exynos5_clk_ip_peric_ctrl,
 		.ctrlbit	= (1 << 24),
 	}, {
+		.name		= "tmu_apbif",
+		.parent		= &exynos5_clk_aclk_66.clk,
+		.enable		= exynos5_clk_ip_peris_ctrl,
+		.ctrlbit	= (1 << 21),
+	}, {
 		.name		= "rtc",
 		.parent		= &exynos5_clk_aclk_66.clk,
 		.enable		= exynos5_clk_ip_peris_ctrl,
@@ -664,17 +674,22 @@
 		.ctrlbit	= (1 << 25),
 	}, {
 		.name		= "mfc",
-		.devname	= "s5p-mfc",
+		.devname	= "s5p-mfc-v6",
 		.enable		= exynos5_clk_ip_mfc_ctrl,
 		.ctrlbit	= (1 << 0),
 	}, {
 		.name		= "hdmi",
-		.devname	= "exynos4-hdmi",
+		.devname	= "exynos5-hdmi",
 		.enable		= exynos5_clk_ip_disp1_ctrl,
 		.ctrlbit	= (1 << 6),
 	}, {
+		.name		= "hdmiphy",
+		.devname	= "exynos5-hdmi",
+		.enable		= exynos5_clk_hdmiphy_ctrl,
+		.ctrlbit	= (1 << 0),
+	}, {
 		.name		= "mixer",
-		.devname	= "s5p-mixer",
+		.devname	= "exynos5-mixer",
 		.enable		= exynos5_clk_ip_disp1_ctrl,
 		.ctrlbit	= (1 << 5),
 	}, {
diff --git a/arch/arm/mach-exynos/common.c b/arch/arm/mach-exynos/common.c
index e05f6cc..ddd4b72 100644
--- a/arch/arm/mach-exynos/common.c
+++ b/arch/arm/mach-exynos/common.c
@@ -680,6 +680,8 @@
 	 * uses GIC instead of VIC.
 	 */
 	s5p_init_irq(NULL, 0);
+
+	gic_arch_extn.irq_set_wake = s3c_irq_wake;
 }
 
 struct bus_type exynos_subsys = {
@@ -1020,11 +1022,14 @@
 	 * platforms switch over to using the pinctrl driver, the wakeup
 	 * interrupt support code here can be completely removed.
 	 */
+	static const struct of_device_id exynos_pinctrl_ids[] = {
+		{ .compatible = "samsung,pinctrl-exynos4210", },
+		{ .compatible = "samsung,pinctrl-exynos4x12", },
+	};
 	struct device_node *pctrl_np, *wkup_np;
-	const char *pctrl_compat = "samsung,pinctrl-exynos4210";
 	const char *wkup_compat = "samsung,exynos4210-wakeup-eint";
 
-	for_each_compatible_node(pctrl_np, NULL, pctrl_compat) {
+	for_each_matching_node(pctrl_np, exynos_pinctrl_ids) {
 		if (of_device_is_available(pctrl_np)) {
 			wkup_np = of_find_compatible_node(pctrl_np, NULL,
 							wkup_compat);
diff --git a/arch/arm/mach-exynos/cpuidle.c b/arch/arm/mach-exynos/cpuidle.c
index cff0595..8e4ec21 100644
--- a/arch/arm/mach-exynos/cpuidle.c
+++ b/arch/arm/mach-exynos/cpuidle.c
@@ -116,7 +116,8 @@
 	cpu_suspend(0, idle_finisher);
 
 #ifdef CONFIG_SMP
-	scu_enable(S5P_VA_SCU);
+	if (!soc_is_exynos5250())
+		scu_enable(S5P_VA_SCU);
 #endif
 	cpu_pm_exit();
 
diff --git a/arch/arm/mach-exynos/dev-drm.c b/arch/arm/mach-exynos/dev-drm.c
deleted file mode 100644
index 17c9c6e..0000000
--- a/arch/arm/mach-exynos/dev-drm.c
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * linux/arch/arm/mach-exynos/dev-drm.c
- *
- * Copyright (c) 2012 Samsung Electronics Co., Ltd.
- *		http://www.samsung.com
- *
- * EXYNOS - core DRM device
- *
- * This program is free software; 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/kernel.h>
-#include <linux/dma-mapping.h>
-#include <linux/platform_device.h>
-
-#include <plat/devs.h>
-
-static u64 exynos_drm_dma_mask = DMA_BIT_MASK(32);
-
-struct platform_device exynos_device_drm = {
-	.name	= "exynos-drm",
-	.dev	= {
-		.dma_mask		= &exynos_drm_dma_mask,
-		.coherent_dma_mask	= DMA_BIT_MASK(32),
-	}
-};
diff --git a/arch/arm/mach-exynos/hotplug.c b/arch/arm/mach-exynos/hotplug.c
index f4d7dd2..c3f825b 100644
--- a/arch/arm/mach-exynos/hotplug.c
+++ b/arch/arm/mach-exynos/hotplug.c
@@ -20,10 +20,11 @@
 #include <asm/smp_plat.h>
 
 #include <mach/regs-pmu.h>
+#include <plat/cpu.h>
 
 #include "common.h"
 
-static inline void cpu_enter_lowpower(void)
+static inline void cpu_enter_lowpower_a9(void)
 {
 	unsigned int v;
 
@@ -45,6 +46,35 @@
 	  : "cc");
 }
 
+static inline void cpu_enter_lowpower_a15(void)
+{
+	unsigned int v;
+
+	asm volatile(
+	"	mrc	p15, 0, %0, c1, c0, 0\n"
+	"	bic	%0, %0, %1\n"
+	"	mcr	p15, 0, %0, c1, c0, 0\n"
+	  : "=&r" (v)
+	  : "Ir" (CR_C)
+	  : "cc");
+
+	flush_cache_louis();
+
+	asm volatile(
+	/*
+	* Turn off coherency
+	*/
+	"	mrc	p15, 0, %0, c1, c0, 1\n"
+	"	bic	%0, %0, %1\n"
+	"	mcr	p15, 0, %0, c1, c0, 1\n"
+	: "=&r" (v)
+	: "Ir" (0x40)
+	: "cc");
+
+	isb();
+	dsb();
+}
+
 static inline void cpu_leave_lowpower(void)
 {
 	unsigned int v;
@@ -103,11 +133,20 @@
 void __ref exynos_cpu_die(unsigned int cpu)
 {
 	int spurious = 0;
+	int primary_part = 0;
 
 	/*
-	 * we're ready for shutdown now, so do it
+	 * we're ready for shutdown now, so do it.
+	 * Exynos4 is A9 based while Exynos5 is A15; check the CPU part
+	 * number by reading the Main ID register and then perform the
+	 * appropriate sequence for entering low power.
 	 */
-	cpu_enter_lowpower();
+	asm("mrc p15, 0, %0, c0, c0, 0" : "=r"(primary_part) : : "cc");
+	if ((primary_part & 0xfff0) == 0xc0f0)
+		cpu_enter_lowpower_a15();
+	else
+		cpu_enter_lowpower_a9();
+
 	platform_do_lowpower(cpu, &spurious);
 
 	/*
diff --git a/arch/arm/mach-exynos/include/mach/irqs.h b/arch/arm/mach-exynos/include/mach/irqs.h
index e0f0ae3..1f4dc35 100644
--- a/arch/arm/mach-exynos/include/mach/irqs.h
+++ b/arch/arm/mach-exynos/include/mach/irqs.h
@@ -136,6 +136,9 @@
 #define EXYNOS4_IRQ_TSI			IRQ_SPI(115)
 #define EXYNOS4_IRQ_SATA		IRQ_SPI(116)
 
+#define EXYNOS4_IRQ_TMU_TRIG0		COMBINER_IRQ(2, 4)
+#define EXYNOS4_IRQ_TMU_TRIG1		COMBINER_IRQ(3, 4)
+
 #define EXYNOS4_IRQ_SYSMMU_MDMA0_0	COMBINER_IRQ(4, 0)
 #define EXYNOS4_IRQ_SYSMMU_SSS_0	COMBINER_IRQ(4, 1)
 #define EXYNOS4_IRQ_SYSMMU_FIMC0_0	COMBINER_IRQ(4, 2)
diff --git a/arch/arm/mach-exynos/include/mach/map.h b/arch/arm/mach-exynos/include/mach/map.h
index 61b74e1..1df6abb 100644
--- a/arch/arm/mach-exynos/include/mach/map.h
+++ b/arch/arm/mach-exynos/include/mach/map.h
@@ -89,6 +89,8 @@
 #define EXYNOS4_PA_TWD			0x10500600
 #define EXYNOS4_PA_L2CC			0x10502000
 
+#define EXYNOS4_PA_TMU			0x100C0000
+
 #define EXYNOS4_PA_MDMA0		0x10810000
 #define EXYNOS4_PA_MDMA1		0x12850000
 #define EXYNOS4_PA_S_MDMA1		0x12840000
diff --git a/arch/arm/mach-exynos/mach-armlex4210.c b/arch/arm/mach-exynos/mach-armlex4210.c
index 3f37a5e..b938f9f 100644
--- a/arch/arm/mach-exynos/mach-armlex4210.c
+++ b/arch/arm/mach-exynos/mach-armlex4210.c
@@ -147,7 +147,6 @@
 	&s3c_device_hsmmc3,
 	&s3c_device_rtc,
 	&s3c_device_wdt,
-	&samsung_asoc_dma,
 	&armlex4210_smsc911x,
 	&exynos4_device_ahci,
 };
diff --git a/arch/arm/mach-exynos/mach-exynos4-dt.c b/arch/arm/mach-exynos/mach-exynos4-dt.c
index 6df99c0..92757ff 100644
--- a/arch/arm/mach-exynos/mach-exynos4-dt.c
+++ b/arch/arm/mach-exynos/mach-exynos4-dt.c
@@ -78,6 +78,8 @@
 	OF_DEV_AUXDATA("arm,pl330", EXYNOS4_PA_PDMA0, "dma-pl330.0", NULL),
 	OF_DEV_AUXDATA("arm,pl330", EXYNOS4_PA_PDMA1, "dma-pl330.1", NULL),
 	OF_DEV_AUXDATA("arm,pl330", EXYNOS4_PA_MDMA1, "dma-pl330.2", NULL),
+	OF_DEV_AUXDATA("samsung,exynos4210-tmu", EXYNOS4_PA_TMU,
+				"exynos-tmu", NULL),
 	{},
 };
 
@@ -95,6 +97,8 @@
 
 static char const *exynos4_dt_compat[] __initdata = {
 	"samsung,exynos4210",
+	"samsung,exynos4212",
+	"samsung,exynos4412",
 	NULL
 };
 
diff --git a/arch/arm/mach-exynos/mach-exynos5-dt.c b/arch/arm/mach-exynos/mach-exynos5-dt.c
index f1326be..929de76 100644
--- a/arch/arm/mach-exynos/mach-exynos5-dt.c
+++ b/arch/arm/mach-exynos/mach-exynos5-dt.c
@@ -12,6 +12,8 @@
 #include <linux/of_platform.h>
 #include <linux/of_fdt.h>
 #include <linux/serial_core.h>
+#include <linux/memblock.h>
+#include <linux/of_fdt.h>
 
 #include <asm/mach/arch.h>
 #include <asm/hardware/gic.h>
@@ -19,6 +21,7 @@
 
 #include <plat/cpu.h>
 #include <plat/regs-serial.h>
+#include <plat/mfc.h>
 
 #include "common.h"
 
@@ -48,6 +51,20 @@
 				"s3c2440-i2c.0", NULL),
 	OF_DEV_AUXDATA("samsung,s3c2440-i2c", EXYNOS5_PA_IIC(1),
 				"s3c2440-i2c.1", NULL),
+	OF_DEV_AUXDATA("samsung,s3c2440-i2c", EXYNOS5_PA_IIC(2),
+				"s3c2440-i2c.2", NULL),
+	OF_DEV_AUXDATA("samsung,s3c2440-i2c", EXYNOS5_PA_IIC(3),
+				"s3c2440-i2c.3", NULL),
+	OF_DEV_AUXDATA("samsung,s3c2440-i2c", EXYNOS5_PA_IIC(4),
+				"s3c2440-i2c.4", NULL),
+	OF_DEV_AUXDATA("samsung,s3c2440-i2c", EXYNOS5_PA_IIC(5),
+				"s3c2440-i2c.5", NULL),
+	OF_DEV_AUXDATA("samsung,s3c2440-i2c", EXYNOS5_PA_IIC(6),
+				"s3c2440-i2c.6", NULL),
+	OF_DEV_AUXDATA("samsung,s3c2440-i2c", EXYNOS5_PA_IIC(7),
+				"s3c2440-i2c.7", NULL),
+	OF_DEV_AUXDATA("samsung,s3c2440-hdmiphy-i2c", EXYNOS5_PA_IIC(8),
+				"s3c2440-hdmiphy-i2c", NULL),
 	OF_DEV_AUXDATA("samsung,exynos5250-dw-mshc", EXYNOS5_PA_DWMCI0,
 				"dw_mmc.0", NULL),
 	OF_DEV_AUXDATA("samsung,exynos5250-dw-mshc", EXYNOS5_PA_DWMCI1,
@@ -62,6 +79,12 @@
 				"exynos4210-spi.1", NULL),
 	OF_DEV_AUXDATA("samsung,exynos4210-spi", EXYNOS5_PA_SPI2,
 				"exynos4210-spi.2", NULL),
+	OF_DEV_AUXDATA("samsung,exynos5-sata-ahci", 0x122F0000,
+				"exynos5-sata", NULL),
+	OF_DEV_AUXDATA("samsung,exynos5-sata-phy", 0x12170000,
+				"exynos5-sata-phy", NULL),
+	OF_DEV_AUXDATA("samsung,exynos5-sata-phy-i2c", 0x121D0000,
+				"exynos5-sata-phy-i2c", NULL),
 	OF_DEV_AUXDATA("arm,pl330", EXYNOS5_PA_PDMA0, "dma-pl330.0", NULL),
 	OF_DEV_AUXDATA("arm,pl330", EXYNOS5_PA_PDMA1, "dma-pl330.1", NULL),
 	OF_DEV_AUXDATA("arm,pl330", EXYNOS5_PA_MDMA1, "dma-pl330.2", NULL),
@@ -73,6 +96,13 @@
 				"exynos-gsc.2", NULL),
 	OF_DEV_AUXDATA("samsung,exynos5-gsc", EXYNOS5_PA_GSC3,
 				"exynos-gsc.3", NULL),
+	OF_DEV_AUXDATA("samsung,exynos5-hdmi", 0x14530000,
+				"exynos5-hdmi", NULL),
+	OF_DEV_AUXDATA("samsung,exynos5-mixer", 0x14450000,
+				"exynos5-mixer", NULL),
+	OF_DEV_AUXDATA("samsung,mfc-v6", 0x11000000, "s5p-mfc-v6", NULL),
+	OF_DEV_AUXDATA("samsung,exynos5250-tmu", 0x10060000,
+				"exynos-tmu", NULL),
 	{},
 };
 
@@ -108,6 +138,17 @@
 	NULL
 };
 
+static void __init exynos5_reserve(void)
+{
+	struct s5p_mfc_dt_meminfo mfc_mem;
+
+	/* Reserve memory for MFC only if it's available */
+	mfc_mem.compatible = "samsung,mfc-v6";
+	if (of_scan_flat_dt(s5p_fdt_find_mfc_mem, &mfc_mem))
+		s5p_mfc_reserve_mem(mfc_mem.roff, mfc_mem.rsize, mfc_mem.loff,
+				mfc_mem.lsize);
+}
+
 DT_MACHINE_START(EXYNOS5_DT, "SAMSUNG EXYNOS5 (Flattened Device Tree)")
 	/* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */
 	.init_irq	= exynos5_init_irq,
@@ -119,4 +160,5 @@
 	.timer		= &exynos4_timer,
 	.dt_compat	= exynos5_dt_compat,
 	.restart        = exynos5_restart,
+	.reserve	= exynos5_reserve,
 MACHINE_END
diff --git a/arch/arm/mach-exynos/mach-nuri.c b/arch/arm/mach-exynos/mach-nuri.c
index 69359a0..27d4ed8 100644
--- a/arch/arm/mach-exynos/mach-nuri.c
+++ b/arch/arm/mach-exynos/mach-nuri.c
@@ -1326,9 +1326,6 @@
 	&cam_vdda_fixed_rdev,
 	&cam_8m_12v_fixed_rdev,
 	&exynos4_bus_devfreq,
-#ifdef CONFIG_DRM_EXYNOS
-	&exynos_device_drm,
-#endif
 };
 
 static void __init nuri_map_io(void)
diff --git a/arch/arm/mach-exynos/mach-origen.c b/arch/arm/mach-exynos/mach-origen.c
index c606080..e6f4191 100644
--- a/arch/arm/mach-exynos/mach-origen.c
+++ b/arch/arm/mach-exynos/mach-origen.c
@@ -711,9 +711,6 @@
 	&s5p_device_mfc_l,
 	&s5p_device_mfc_r,
 	&s5p_device_mixer,
-#ifdef CONFIG_DRM_EXYNOS
-	&exynos_device_drm,
-#endif
 	&exynos4_device_ohci,
 	&origen_device_gpiokeys,
 	&origen_lcd_hv070wsa,
diff --git a/arch/arm/mach-exynos/mach-smdk4x12.c b/arch/arm/mach-exynos/mach-smdk4x12.c
index ddb9263..a1555a7 100644
--- a/arch/arm/mach-exynos/mach-smdk4x12.c
+++ b/arch/arm/mach-exynos/mach-smdk4x12.c
@@ -317,9 +317,6 @@
 	&s5p_device_mfc,
 	&s5p_device_mfc_l,
 	&s5p_device_mfc_r,
-#ifdef CONFIG_DRM_EXYNOS
-	&exynos_device_drm,
-#endif
 	&samsung_device_keypad,
 };
 
diff --git a/arch/arm/mach-exynos/mach-smdkv310.c b/arch/arm/mach-exynos/mach-smdkv310.c
index 8dd6a1e..b738424 100644
--- a/arch/arm/mach-exynos/mach-smdkv310.c
+++ b/arch/arm/mach-exynos/mach-smdkv310.c
@@ -300,9 +300,6 @@
 	&s5p_device_fimc_md,
 	&s5p_device_g2d,
 	&s5p_device_jpeg,
-#ifdef CONFIG_DRM_EXYNOS
-	&exynos_device_drm,
-#endif
 	&exynos4_device_ac97,
 	&exynos4_device_i2s0,
 	&exynos4_device_ohci,
@@ -311,7 +308,6 @@
 	&s5p_device_mfc_l,
 	&s5p_device_mfc_r,
 	&exynos4_device_spdif,
-	&samsung_asoc_dma,
 	&samsung_asoc_idma,
 	&s5p_device_fimd0,
 	&smdkv310_device_audio,
diff --git a/arch/arm/mach-exynos/mach-universal_c210.c b/arch/arm/mach-exynos/mach-universal_c210.c
index 2d6bc83..9e3340f 100644
--- a/arch/arm/mach-exynos/mach-universal_c210.c
+++ b/arch/arm/mach-exynos/mach-universal_c210.c
@@ -1080,9 +1080,6 @@
 	&s5p_device_onenand,
 	&s5p_device_fimd0,
 	&s5p_device_jpeg,
-#ifdef CONFIG_DRM_EXYNOS
-	&exynos_device_drm,
-#endif
 	&s3c_device_usb_hsotg,
 	&s5p_device_mfc,
 	&s5p_device_mfc_l,
diff --git a/arch/arm/mach-exynos/pm.c b/arch/arm/mach-exynos/pm.c
index c06c992..8df6ec5 100644
--- a/arch/arm/mach-exynos/pm.c
+++ b/arch/arm/mach-exynos/pm.c
@@ -81,6 +81,9 @@
 	outer_flush_all();
 #endif
 
+	if (soc_is_exynos5250())
+		flush_cache_all();
+
 	/* issue the standby signal into the pm unit. */
 	cpu_do_idle();
 
@@ -312,6 +315,10 @@
 	}
 
 early_wakeup:
+
+	/* Clear SLEEP mode set in INFORM1 */
+	__raw_writel(0x0, S5P_INFORM1);
+
 	return;
 }
 
diff --git a/arch/arm/mach-exynos/pm_domains.c b/arch/arm/mach-exynos/pm_domains.c
index c0bc83a..9f1351d 100644
--- a/arch/arm/mach-exynos/pm_domains.c
+++ b/arch/arm/mach-exynos/pm_domains.c
@@ -19,6 +19,8 @@
 #include <linux/pm_domain.h>
 #include <linux/delay.h>
 #include <linux/of_address.h>
+#include <linux/of_platform.h>
+#include <linux/sched.h>
 
 #include <mach/regs-pmu.h>
 #include <plat/devs.h>
@@ -83,12 +85,88 @@
 }
 
 #ifdef CONFIG_OF
+static void exynos_add_device_to_domain(struct exynos_pm_domain *pd,
+					 struct device *dev)
+{
+	int ret;
+
+	dev_dbg(dev, "adding to power domain %s\n", pd->pd.name);
+
+	while (1) {
+		ret = pm_genpd_add_device(&pd->pd, dev);
+		if (ret != -EAGAIN)
+			break;
+		cond_resched();
+	}
+
+	pm_genpd_dev_need_restore(dev, true);
+}
+
+static void exynos_remove_device_from_domain(struct device *dev)
+{
+	struct generic_pm_domain *genpd = dev_to_genpd(dev);
+	int ret;
+
+	dev_dbg(dev, "removing from power domain %s\n", genpd->name);
+
+	while (1) {
+		ret = pm_genpd_remove_device(genpd, dev);
+		if (ret != -EAGAIN)
+			break;
+		cond_resched();
+	}
+}
+
+static void exynos_read_domain_from_dt(struct device *dev)
+{
+	struct platform_device *pd_pdev;
+	struct exynos_pm_domain *pd;
+	struct device_node *node;
+
+	node = of_parse_phandle(dev->of_node, "samsung,power-domain", 0);
+	if (!node)
+		return;
+	pd_pdev = of_find_device_by_node(node);
+	if (!pd_pdev)
+		return;
+	pd = platform_get_drvdata(pd_pdev);
+	exynos_add_device_to_domain(pd, dev);
+}
+
+static int exynos_pm_notifier_call(struct notifier_block *nb,
+				    unsigned long event, void *data)
+{
+	struct device *dev = data;
+
+	switch (event) {
+	case BUS_NOTIFY_BIND_DRIVER:
+		if (dev->of_node)
+			exynos_read_domain_from_dt(dev);
+
+		break;
+
+	case BUS_NOTIFY_UNBOUND_DRIVER:
+		exynos_remove_device_from_domain(dev);
+
+		break;
+	}
+	return NOTIFY_DONE;
+}
+
+static struct notifier_block platform_nb = {
+	.notifier_call = exynos_pm_notifier_call,
+};
+
 static __init int exynos_pm_dt_parse_domains(void)
 {
+	struct platform_device *pdev;
 	struct device_node *np;
 
 	for_each_compatible_node(np, NULL, "samsung,exynos4210-pd") {
 		struct exynos_pm_domain *pd;
+		int on;
+
+		pdev = of_find_device_by_node(np);
 
 		pd = kzalloc(sizeof(*pd), GFP_KERNEL);
 		if (!pd) {
@@ -97,15 +175,22 @@
 			return -ENOMEM;
 		}
 
-		if (of_get_property(np, "samsung,exynos4210-pd-off", NULL))
-			pd->is_off = true;
-		pd->name = np->name;
+		pd->pd.name = kstrdup(np->name, GFP_KERNEL);
+		pd->name = pd->pd.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);
+
+		platform_set_drvdata(pdev, pd);
+
+		on = __raw_readl(pd->base + 0x4) & S5P_INT_LOCAL_PWR_EN;
+
+		pm_genpd_init(&pd->pd, NULL, !on);
 	}
+
+	bus_register_notifier(&platform_bus_type, &platform_nb);
+
 	return 0;
 }
 #else
diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index 4e24b8c..1ad0d76 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -272,6 +272,13 @@
 
 endchoice
 
+config MACH_IMX25_DT
+	bool "Support i.MX25 platforms from device tree"
+	select SOC_IMX25
+	help
+	  Include support for Freescale i.MX25 based platforms
+	  using the device tree for discovery
+
 comment "MX27 platforms:"
 
 config MACH_MX27ADS
@@ -831,7 +838,14 @@
 
 config SOC_IMX6Q
 	bool "i.MX6 Quad support"
+	select ARCH_HAS_CPUFREQ
+	select ARCH_HAS_OPP
 	select ARM_CPU_SUSPEND if PM
+	select ARM_ERRATA_743622
+	select ARM_ERRATA_751472
+	select ARM_ERRATA_754322
+	select ARM_ERRATA_764369 if SMP
+	select ARM_ERRATA_775420
 	select ARM_GIC
 	select COMMON_CLK
 	select CPU_V7
@@ -843,6 +857,10 @@
 	select MFD_SYSCON
 	select PINCTRL
 	select PINCTRL_IMX6Q
+	select PL310_ERRATA_588369 if CACHE_PL310
+	select PL310_ERRATA_727915 if CACHE_PL310
+	select PL310_ERRATA_769419 if CACHE_PL310
+	select PM_OPP if PM
 
 	help
 	  This enables support for Freescale i.MX6 Quad processor.
diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
index fe47b71..0634b31 100644
--- a/arch/arm/mach-imx/Makefile
+++ b/arch/arm/mach-imx/Makefile
@@ -50,6 +50,7 @@
 obj-$(CONFIG_MACH_MX25_3DS) += mach-mx25_3ds.o
 obj-$(CONFIG_MACH_EUKREA_CPUIMX25SD) += mach-eukrea_cpuimx25.o
 obj-$(CONFIG_MACH_EUKREA_MBIMXSD25_BASEBOARD) += eukrea_mbimxsd25-baseboard.o
+obj-$(CONFIG_MACH_IMX25_DT) += imx25-dt.o
 
 # i.MX27 based machines
 obj-$(CONFIG_MACH_MX27ADS) += mach-mx27ads.o
diff --git a/arch/arm/mach-imx/clk-imx25.c b/arch/arm/mach-imx/clk-imx25.c
index bc88580..b197aa7 100644
--- a/arch/arm/mach-imx/clk-imx25.c
+++ b/arch/arm/mach-imx/clk-imx25.c
@@ -23,6 +23,9 @@
 #include <linux/io.h>
 #include <linux/clkdev.h>
 #include <linux/err.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
 
 #include "clk.h"
 #include "common.h"
@@ -55,6 +58,8 @@
 
 #define ccm(x)	(CRM_BASE + (x))
 
+static struct clk_onecell_data clk_data;
+
 static const char *cpu_sel_clks[] = { "mpll", "mpll_cpu_3_4", };
 static const char *per_sel_clks[] = { "ahb", "upll", };
 
@@ -64,24 +69,30 @@
 	per7_sel, per8_sel, per9_sel, per10_sel, per11_sel, per12_sel,
 	per13_sel, per14_sel, per15_sel, per0, per1, per2, per3, per4, per5,
 	per6, per7, per8, per9, per10, per11, per12, per13, per14, per15,
-	csi_ipg_per, esdhc1_ipg_per, esdhc2_ipg_per, gpt_ipg_per, i2c_ipg_per,
-	lcdc_ipg_per, nfc_ipg_per, ssi1_ipg_per, ssi2_ipg_per, uart_ipg_per,
-	csi_ahb, esdhc1_ahb, esdhc2_ahb, fec_ahb, lcdc_ahb, sdma_ahb,
-	usbotg_ahb, can1_ipg, can2_ipg, csi_ipg, cspi1_ipg, cspi2_ipg,
-	cspi3_ipg, dryice_ipg, esdhc1_ipg, esdhc2_ipg, fec_ipg, iim_ipg,
-	kpp_ipg, lcdc_ipg, pwm1_ipg, pwm2_ipg, pwm3_ipg, pwm4_ipg, sdma_ipg,
-	ssi1_ipg, ssi2_ipg, tsc_ipg, uart1_ipg, uart2_ipg, uart3_ipg,
-	uart4_ipg, uart5_ipg, wdt_ipg, clk_max
+	csi_ipg_per, epit_ipg_per, esai_ipg_per, esdhc1_ipg_per, esdhc2_ipg_per,
+	gpt_ipg_per, i2c_ipg_per, lcdc_ipg_per, nfc_ipg_per, owire_ipg_per,
+	pwm_ipg_per, sim1_ipg_per, sim2_ipg_per, ssi1_ipg_per, ssi2_ipg_per,
+	uart_ipg_per, ata_ahb, reserved1, csi_ahb, emi_ahb, esai_ahb, esdhc1_ahb,
+	esdhc2_ahb, fec_ahb, lcdc_ahb, rtic_ahb, sdma_ahb, slcdc_ahb, usbotg_ahb,
+	reserved2, reserved3, reserved4, reserved5, can1_ipg, can2_ipg,	csi_ipg,
+	cspi1_ipg, cspi2_ipg, cspi3_ipg, dryice_ipg, ect_ipg, epit1_ipg, epit2_ipg,
+	reserved6, esdhc1_ipg, esdhc2_ipg, fec_ipg, reserved7, reserved8, reserved9,
+	gpt1_ipg, gpt2_ipg, gpt3_ipg, gpt4_ipg, reserved10, reserved11, reserved12,
+	iim_ipg, reserved13, reserved14, kpp_ipg, lcdc_ipg, reserved15, pwm1_ipg,
+	pwm2_ipg, pwm3_ipg, pwm4_ipg, rngb_ipg, reserved16, scc_ipg, sdma_ipg,
+	sim1_ipg, sim2_ipg, slcdc_ipg, spba_ipg, ssi1_ipg, ssi2_ipg, tsc_ipg,
+	uart1_ipg, uart2_ipg, uart3_ipg, uart4_ipg, uart5_ipg, reserved17,
+	wdt_ipg, clk_max
 };
 
 static struct clk *clk[clk_max];
 
-int __init mx25_clocks_init(void)
+static int __init __mx25_clocks_init(unsigned long osc_rate)
 {
 	int i;
 
 	clk[dummy] = imx_clk_fixed("dummy", 0);
-	clk[osc] = imx_clk_fixed("osc", 24000000);
+	clk[osc] = imx_clk_fixed("osc", osc_rate);
 	clk[mpll] = imx_clk_pllv1("mpll", "osc", ccm(CCM_MPCTL));
 	clk[upll] = imx_clk_pllv1("upll", "osc", ccm(CCM_UPCTL));
 	clk[mpll_cpu_3_4] = imx_clk_fixed_factor("mpll_cpu_3_4", "mpll", 3, 4);
@@ -123,22 +134,36 @@
 	clk[per14] = imx_clk_divider("per14", "per14_sel", ccm(CCM_PCDR3), 16, 6);
 	clk[per15] = imx_clk_divider("per15", "per15_sel", ccm(CCM_PCDR3), 24, 6);
 	clk[csi_ipg_per] = imx_clk_gate("csi_ipg_per", "per0", ccm(CCM_CGCR0), 0);
+	clk[epit_ipg_per] = imx_clk_gate("epit_ipg_per", "per1", ccm(CCM_CGCR0),  1);
+	clk[esai_ipg_per] = imx_clk_gate("esai_ipg_per", "per2", ccm(CCM_CGCR0),  2);
 	clk[esdhc1_ipg_per] = imx_clk_gate("esdhc1_ipg_per", "per3", ccm(CCM_CGCR0),  3);
 	clk[esdhc2_ipg_per] = imx_clk_gate("esdhc2_ipg_per", "per4", ccm(CCM_CGCR0),  4);
 	clk[gpt_ipg_per] = imx_clk_gate("gpt_ipg_per", "per5", ccm(CCM_CGCR0),  5);
 	clk[i2c_ipg_per] = imx_clk_gate("i2c_ipg_per", "per6", ccm(CCM_CGCR0),  6);
 	clk[lcdc_ipg_per] = imx_clk_gate("lcdc_ipg_per", "per7", ccm(CCM_CGCR0),  7);
 	clk[nfc_ipg_per] = imx_clk_gate("nfc_ipg_per", "per8", ccm(CCM_CGCR0),  8);
+	clk[owire_ipg_per] = imx_clk_gate("owire_ipg_per", "per9", ccm(CCM_CGCR0),  9);
+	clk[pwm_ipg_per] = imx_clk_gate("pwm_ipg_per", "per10", ccm(CCM_CGCR0),  10);
+	clk[sim1_ipg_per] = imx_clk_gate("sim1_ipg_per", "per11", ccm(CCM_CGCR0),  11);
+	clk[sim2_ipg_per] = imx_clk_gate("sim2_ipg_per", "per12", ccm(CCM_CGCR0),  12);
 	clk[ssi1_ipg_per] = imx_clk_gate("ssi1_ipg_per", "per13", ccm(CCM_CGCR0), 13);
 	clk[ssi2_ipg_per] = imx_clk_gate("ssi2_ipg_per", "per14", ccm(CCM_CGCR0), 14);
 	clk[uart_ipg_per] = imx_clk_gate("uart_ipg_per", "per15", ccm(CCM_CGCR0), 15);
+	clk[ata_ahb] = imx_clk_gate("ata_ahb", "ahb", ccm(CCM_CGCR0), 16);
+	/* CCM_CGCR0(17): reserved */
 	clk[csi_ahb] = imx_clk_gate("csi_ahb", "ahb", ccm(CCM_CGCR0), 18);
+	clk[emi_ahb] = imx_clk_gate("emi_ahb", "ahb", ccm(CCM_CGCR0), 19);
+	clk[esai_ahb] = imx_clk_gate("esai_ahb", "ahb", ccm(CCM_CGCR0), 20);
 	clk[esdhc1_ahb] = imx_clk_gate("esdhc1_ahb", "ahb", ccm(CCM_CGCR0), 21);
 	clk[esdhc2_ahb] = imx_clk_gate("esdhc2_ahb", "ahb", ccm(CCM_CGCR0), 22);
 	clk[fec_ahb] = imx_clk_gate("fec_ahb", "ahb", ccm(CCM_CGCR0), 23);
 	clk[lcdc_ahb] = imx_clk_gate("lcdc_ahb", "ahb", ccm(CCM_CGCR0), 24);
+	clk[rtic_ahb] = imx_clk_gate("rtic_ahb", "ahb", ccm(CCM_CGCR0), 25);
 	clk[sdma_ahb] = imx_clk_gate("sdma_ahb", "ahb", ccm(CCM_CGCR0), 26);
+	clk[slcdc_ahb] = imx_clk_gate("slcdc_ahb", "ahb", ccm(CCM_CGCR0), 27);
 	clk[usbotg_ahb] = imx_clk_gate("usbotg_ahb", "ahb", ccm(CCM_CGCR0), 28);
+	/* CCM_CGCR0(29-31): reserved */
+	/* CCM_CGCR1(0): reserved in datasheet, used as audmux in FSL kernel */
 	clk[can1_ipg] = imx_clk_gate("can1_ipg", "ipg", ccm(CCM_CGCR1),  2);
 	clk[can2_ipg] = imx_clk_gate("can2_ipg", "ipg", ccm(CCM_CGCR1),  3);
 	clk[csi_ipg] = imx_clk_gate("csi_ipg", "ipg", ccm(CCM_CGCR1),  4);
@@ -146,17 +171,41 @@
 	clk[cspi2_ipg] = imx_clk_gate("cspi2_ipg", "ipg", ccm(CCM_CGCR1),  6);
 	clk[cspi3_ipg] = imx_clk_gate("cspi3_ipg", "ipg", ccm(CCM_CGCR1),  7);
 	clk[dryice_ipg] = imx_clk_gate("dryice_ipg", "ipg", ccm(CCM_CGCR1),  8);
+	clk[ect_ipg] = imx_clk_gate("ect_ipg", "ipg", ccm(CCM_CGCR1),  9);
+	clk[epit1_ipg] = imx_clk_gate("epit1_ipg", "ipg", ccm(CCM_CGCR1),  10);
+	clk[epit2_ipg] = imx_clk_gate("epit2_ipg", "ipg", ccm(CCM_CGCR1),  11);
+	/* CCM_CGCR1(12): reserved in datasheet, used as esai in FSL kernel */
 	clk[esdhc1_ipg] = imx_clk_gate("esdhc1_ipg", "ipg", ccm(CCM_CGCR1), 13);
 	clk[esdhc2_ipg] = imx_clk_gate("esdhc2_ipg", "ipg", ccm(CCM_CGCR1), 14);
 	clk[fec_ipg] = imx_clk_gate("fec_ipg", "ipg", ccm(CCM_CGCR1), 15);
+	/* CCM_CGCR1(16): reserved in datasheet, used as gpio1 in FSL kernel */
+	/* CCM_CGCR1(17): reserved in datasheet, used as gpio2 in FSL kernel */
+	/* CCM_CGCR1(18): reserved in datasheet, used as gpio3 in FSL kernel */
+	clk[gpt1_ipg] = imx_clk_gate("gpt1_ipg", "ipg", ccm(CCM_CGCR1), 19);
+	clk[gpt2_ipg] = imx_clk_gate("gpt2_ipg", "ipg", ccm(CCM_CGCR1), 20);
+	clk[gpt3_ipg] = imx_clk_gate("gpt3_ipg", "ipg", ccm(CCM_CGCR1), 21);
+	clk[gpt4_ipg] = imx_clk_gate("gpt4_ipg", "ipg", ccm(CCM_CGCR1), 22);
+	/* CCM_CGCR1(23): reserved in datasheet, used as i2c1 in FSL kernel */
+	/* CCM_CGCR1(24): reserved in datasheet, used as i2c2 in FSL kernel */
+	/* CCM_CGCR1(25): reserved in datasheet, used as i2c3 in FSL kernel */
 	clk[iim_ipg] = imx_clk_gate("iim_ipg", "ipg", ccm(CCM_CGCR1), 26);
+	/* CCM_CGCR1(27): reserved in datasheet, used as iomuxc in FSL kernel */
+	/* CCM_CGCR1(28): reserved in datasheet, used as kpp in FSL kernel */
 	clk[kpp_ipg] = imx_clk_gate("kpp_ipg", "ipg", ccm(CCM_CGCR1), 28);
 	clk[lcdc_ipg] = imx_clk_gate("lcdc_ipg", "ipg", ccm(CCM_CGCR1), 29);
+	/* CCM_CGCR1(30): reserved in datasheet, used as owire in FSL kernel */
 	clk[pwm1_ipg] = imx_clk_gate("pwm1_ipg", "ipg", ccm(CCM_CGCR1), 31);
 	clk[pwm2_ipg] = imx_clk_gate("pwm2_ipg", "ipg", ccm(CCM_CGCR2),  0);
 	clk[pwm3_ipg] = imx_clk_gate("pwm3_ipg", "ipg", ccm(CCM_CGCR2),  1);
 	clk[pwm4_ipg] = imx_clk_gate("pwm4_ipg", "ipg", ccm(CCM_CGCR2),  2);
+	clk[rngb_ipg] = imx_clk_gate("rngb_ipg", "ipg", ccm(CCM_CGCR2),  3);
+	/* CCM_CGCR2(4): reserved in datasheet, used as rtic in FSL kernel */
+	clk[scc_ipg] = imx_clk_gate("scc_ipg", "ipg", ccm(CCM_CGCR2),  5);
 	clk[sdma_ipg] = imx_clk_gate("sdma_ipg", "ipg", ccm(CCM_CGCR2),  6);
+	clk[sim1_ipg] = imx_clk_gate("sim1_ipg", "ipg", ccm(CCM_CGCR2),  7);
+	clk[sim2_ipg] = imx_clk_gate("sim2_ipg", "ipg", ccm(CCM_CGCR2),  8);
+	clk[slcdc_ipg] = imx_clk_gate("slcdc_ipg", "ipg", ccm(CCM_CGCR2),  9);
+	clk[spba_ipg] = imx_clk_gate("spba_ipg", "ipg", ccm(CCM_CGCR2),  10);
 	clk[ssi1_ipg] = imx_clk_gate("ssi1_ipg", "ipg", ccm(CCM_CGCR2), 11);
 	clk[ssi2_ipg] = imx_clk_gate("ssi2_ipg", "ipg", ccm(CCM_CGCR2), 12);
 	clk[tsc_ipg] = imx_clk_gate("tsc_ipg", "ipg", ccm(CCM_CGCR2), 13);
@@ -165,6 +214,7 @@
 	clk[uart3_ipg] = imx_clk_gate("uart3_ipg", "ipg", ccm(CCM_CGCR2), 16);
 	clk[uart4_ipg] = imx_clk_gate("uart4_ipg", "ipg", ccm(CCM_CGCR2), 17);
 	clk[uart5_ipg] = imx_clk_gate("uart5_ipg", "ipg", ccm(CCM_CGCR2), 18);
+	/* CCM_CGCR2(19): reserved in datasheet, but used as wdt in FSL kernel */
 	clk[wdt_ipg] = imx_clk_gate("wdt_ipg", "ipg", ccm(CCM_CGCR2), 19);
 
 	for (i = 0; i < ARRAY_SIZE(clk); i++)
@@ -172,6 +222,18 @@
 			pr_err("i.MX25 clk %d: register failed with %ld\n",
 				i, PTR_ERR(clk[i]));
 
+	clk_prepare_enable(clk[emi_ahb]);
+
+	clk_register_clkdev(clk[ipg], "ipg", "imx-gpt.0");
+	clk_register_clkdev(clk[gpt_ipg_per], "per", "imx-gpt.0");
+
+	return 0;
+}
+
+int __init mx25_clocks_init(void)
+{
+	__mx25_clocks_init(24000000);
+
 	/* i.mx25 has the i.mx21 type uart */
 	clk_register_clkdev(clk[uart1_ipg], "ipg", "imx21-uart.0");
 	clk_register_clkdev(clk[uart_ipg_per], "per", "imx21-uart.0");
@@ -183,8 +245,6 @@
 	clk_register_clkdev(clk[uart_ipg_per], "per", "imx21-uart.3");
 	clk_register_clkdev(clk[uart5_ipg], "ipg", "imx21-uart.4");
 	clk_register_clkdev(clk[uart_ipg_per], "per", "imx21-uart.4");
-	clk_register_clkdev(clk[ipg], "ipg", "imx-gpt.0");
-	clk_register_clkdev(clk[gpt_ipg_per], "per", "imx-gpt.0");
 	clk_register_clkdev(clk[ipg], "ipg", "mxc-ehci.0");
 	clk_register_clkdev(clk[usbotg_ahb], "ahb", "mxc-ehci.0");
 	clk_register_clkdev(clk[usb_div], "per", "mxc-ehci.0");
@@ -242,5 +302,40 @@
 	clk_register_clkdev(clk[iim_ipg], "iim", NULL);
 
 	mxc_timer_init(MX25_IO_ADDRESS(MX25_GPT1_BASE_ADDR), MX25_INT_GPT1);
+
+	return 0;
+}
+
+int __init mx25_clocks_init_dt(void)
+{
+	struct device_node *np;
+	void __iomem *base;
+	int irq;
+	unsigned long osc_rate = 24000000;
+
+	/* retrieve the freqency of fixed clocks from device tree */
+	for_each_compatible_node(np, NULL, "fixed-clock") {
+		u32 rate;
+		if (of_property_read_u32(np, "clock-frequency", &rate))
+			continue;
+
+		if (of_device_is_compatible(np, "fsl,imx-osc"))
+			osc_rate = rate;
+	}
+
+	np = of_find_compatible_node(NULL, NULL, "fsl,imx25-ccm");
+	clk_data.clks = clk;
+	clk_data.clk_num = ARRAY_SIZE(clk);
+	of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
+
+	__mx25_clocks_init(osc_rate);
+
+	np = of_find_compatible_node(NULL, NULL, "fsl,imx25-gpt");
+	base = of_iomap(np, 0);
+	WARN_ON(!base);
+	irq = irq_of_parse_and_map(np, 0);
+
+	mxc_timer_init(base, irq);
+
 	return 0;
 }
diff --git a/arch/arm/mach-imx/clk-imx6q.c b/arch/arm/mach-imx/clk-imx6q.c
index 4484769..7f2c10c 100644
--- a/arch/arm/mach-imx/clk-imx6q.c
+++ b/arch/arm/mach-imx/clk-imx6q.c
@@ -424,6 +424,7 @@
 	clk_register_clkdev(clk[cko1_sel], "cko1_sel", NULL);
 	clk_register_clkdev(clk[ahb], "ahb", NULL);
 	clk_register_clkdev(clk[cko1], "cko1", NULL);
+	clk_register_clkdev(clk[arm], NULL, "cpu0");
 
 	/*
 	 * The gpmi needs 100MHz frequency in the EDO/Sync mode,
diff --git a/arch/arm/mach-imx/common.h b/arch/arm/mach-imx/common.h
index ef8db6b..7191ab4 100644
--- a/arch/arm/mach-imx/common.h
+++ b/arch/arm/mach-imx/common.h
@@ -66,6 +66,7 @@
 			unsigned long ckih1, unsigned long ckih2);
 extern int mx53_clocks_init(unsigned long ckil, unsigned long osc,
 			unsigned long ckih1, unsigned long ckih2);
+extern int mx25_clocks_init_dt(void);
 extern int mx27_clocks_init_dt(void);
 extern int mx31_clocks_init_dt(void);
 extern int mx51_clocks_init_dt(void);
diff --git a/arch/arm/mach-imx/imx25-dt.c b/arch/arm/mach-imx/imx25-dt.c
new file mode 100644
index 0000000..e17dfbc
--- /dev/null
+++ b/arch/arm/mach-imx/imx25-dt.c
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2012 Sascha Hauer, Pengutronix
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/irq.h>
+#include <linux/of_irq.h>
+#include <linux/of_platform.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#include "common.h"
+#include "mx25.h"
+
+static void __init imx25_dt_init(void)
+{
+	of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
+}
+
+static void __init imx25_timer_init(void)
+{
+	mx25_clocks_init_dt();
+}
+
+static struct sys_timer imx25_timer = {
+	.init = imx25_timer_init,
+};
+
+static const char * const imx25_dt_board_compat[] __initconst = {
+	"fsl,imx25",
+	NULL
+};
+
+DT_MACHINE_START(IMX25_DT, "Freescale i.MX25 (Device Tree Support)")
+	.map_io		= mx25_map_io,
+	.init_early	= imx25_init_early,
+	.init_irq	= mx25_init_irq,
+	.handle_irq	= imx25_handle_irq,
+	.timer		= &imx25_timer,
+	.init_machine	= imx25_dt_init,
+	.dt_compat	= imx25_dt_board_compat,
+	.restart	= mxc_restart,
+MACHINE_END
diff --git a/arch/arm/mach-imx/lluart.c b/arch/arm/mach-imx/lluart.c
index 5f15103..2fdc9bf 100644
--- a/arch/arm/mach-imx/lluart.c
+++ b/arch/arm/mach-imx/lluart.c
@@ -17,17 +17,25 @@
 
 #include "hardware.h"
 
+#define IMX6Q_UART1_BASE_ADDR	0x02020000
+#define IMX6Q_UART2_BASE_ADDR	0x021e8000
+#define IMX6Q_UART3_BASE_ADDR	0x021ec000
+#define IMX6Q_UART4_BASE_ADDR	0x021f0000
+#define IMX6Q_UART5_BASE_ADDR	0x021f4000
+
+/*
+ * IMX6Q_UART_BASE_ADDR is put in the middle to force the expansion
+ * of IMX6Q_UART##n##_BASE_ADDR.
+ */
+#define IMX6Q_UART_BASE_ADDR(n)	IMX6Q_UART##n##_BASE_ADDR
+#define IMX6Q_UART_BASE(n)	IMX6Q_UART_BASE_ADDR(n)
+#define IMX6Q_DEBUG_UART_BASE	IMX6Q_UART_BASE(CONFIG_DEBUG_IMX6Q_UART_PORT)
+
 static struct map_desc imx_lluart_desc = {
-#ifdef CONFIG_DEBUG_IMX6Q_UART2
-	.virtual	= MX6Q_IO_P2V(MX6Q_UART2_BASE_ADDR),
-	.pfn		= __phys_to_pfn(MX6Q_UART2_BASE_ADDR),
-	.length		= MX6Q_UART2_SIZE,
-	.type		= MT_DEVICE,
-#endif
-#ifdef CONFIG_DEBUG_IMX6Q_UART4
-	.virtual	= MX6Q_IO_P2V(MX6Q_UART4_BASE_ADDR),
-	.pfn		= __phys_to_pfn(MX6Q_UART4_BASE_ADDR),
-	.length		= MX6Q_UART4_SIZE,
+#ifdef CONFIG_DEBUG_IMX6Q_UART
+	.virtual	= IMX_IO_P2V(IMX6Q_DEBUG_UART_BASE),
+	.pfn		= __phys_to_pfn(IMX6Q_DEBUG_UART_BASE),
+	.length		= 0x4000,
 	.type		= MT_DEVICE,
 #endif
 };
diff --git a/arch/arm/mach-imx/mach-imx6q.c b/arch/arm/mach-imx/mach-imx6q.c
index cce33e4..4eb1b3a 100644
--- a/arch/arm/mach-imx/mach-imx6q.c
+++ b/arch/arm/mach-imx/mach-imx6q.c
@@ -38,6 +38,40 @@
 #include "cpuidle.h"
 #include "hardware.h"
 
+#define IMX6Q_ANALOG_DIGPROG	0x260
+
+static int imx6q_revision(void)
+{
+	struct device_node *np;
+	void __iomem *base;
+	static u32 rev;
+
+	if (!rev) {
+		np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-anatop");
+		if (!np)
+			return IMX_CHIP_REVISION_UNKNOWN;
+		base = of_iomap(np, 0);
+		if (!base) {
+			of_node_put(np);
+			return IMX_CHIP_REVISION_UNKNOWN;
+		}
+		rev =  readl_relaxed(base + IMX6Q_ANALOG_DIGPROG);
+		iounmap(base);
+		of_node_put(np);
+	}
+
+	switch (rev & 0xff) {
+	case 0:
+		return IMX_CHIP_REVISION_1_0;
+	case 1:
+		return IMX_CHIP_REVISION_1_1;
+	case 2:
+		return IMX_CHIP_REVISION_1_2;
+	default:
+		return IMX_CHIP_REVISION_UNKNOWN;
+	}
+}
+
 void imx6q_restart(char mode, const char *cmd)
 {
 	struct device_node *np;
@@ -204,6 +238,7 @@
 {
 	mx6q_clocks_init();
 	twd_local_timer_of_register();
+	imx_print_silicon_rev("i.MX6Q", imx6q_revision());
 }
 
 static struct sys_timer imx6q_timer = {
diff --git a/arch/arm/mach-imx/mx6q.h b/arch/arm/mach-imx/mx6q.h
index f7e7dba..19d3f54 100644
--- a/arch/arm/mach-imx/mx6q.h
+++ b/arch/arm/mach-imx/mx6q.h
@@ -27,9 +27,5 @@
 #define MX6Q_CCM_SIZE			0x4000
 #define MX6Q_ANATOP_BASE_ADDR		0x020c8000
 #define MX6Q_ANATOP_SIZE		0x1000
-#define MX6Q_UART2_BASE_ADDR		0x021e8000
-#define MX6Q_UART2_SIZE			0x4000
-#define MX6Q_UART4_BASE_ADDR		0x021f0000
-#define MX6Q_UART4_SIZE			0x4000
 
 #endif	/* __MACH_MX6Q_H__ */
diff --git a/arch/arm/mach-kirkwood/Kconfig b/arch/arm/mach-kirkwood/Kconfig
index d018ad4..503d7dd 100644
--- a/arch/arm/mach-kirkwood/Kconfig
+++ b/arch/arm/mach-kirkwood/Kconfig
@@ -46,6 +46,11 @@
 
 config ARCH_KIRKWOOD_DT
 	bool "Marvell Kirkwood Flattened Device Tree"
+	select POWER_SUPPLY
+	select POWER_RESET
+	select POWER_RESET_GPIO
+	select REGULATOR
+	select REGULATOR_FIXED_VOLTAGE
 	select USE_OF
 	help
 	  Say 'Y' here if you want your kernel to support the
diff --git a/arch/arm/mach-kirkwood/board-dnskw.c b/arch/arm/mach-kirkwood/board-dnskw.c
index 43d16d6..a1aa87f 100644
--- a/arch/arm/mach-kirkwood/board-dnskw.c
+++ b/arch/arm/mach-kirkwood/board-dnskw.c
@@ -17,51 +17,11 @@
 #include <linux/mv643xx_eth.h>
 #include <linux/gpio.h>
 #include "common.h"
-#include "mpp.h"
 
 static struct mv643xx_eth_platform_data dnskw_ge00_data = {
 	.phy_addr	= MV643XX_ETH_PHY_ADDR(8),
 };
 
-static unsigned int dnskw_mpp_config[] __initdata = {
-	MPP13_UART1_TXD,	/* Custom ... */
-	MPP14_UART1_RXD,	/* ... Controller (DNS-320 only) */
-	MPP20_SATA1_ACTn,	/* LED: White Right HDD */
-	MPP21_SATA0_ACTn,	/* LED: White Left HDD */
-	MPP24_GPIO,
-	MPP25_GPIO,
-	MPP26_GPIO,	/* LED: Power */
-	MPP27_GPIO,	/* LED: Red Right HDD */
-	MPP28_GPIO,	/* LED: Red Left HDD */
-	MPP29_GPIO,	/* LED: Red USB (DNS-325 only) */
-	MPP30_GPIO,
-	MPP31_GPIO,
-	MPP32_GPIO,
-	MPP33_GPO,
-	MPP34_GPIO,	/* Button: Front power */
-	MPP35_GPIO,	/* LED: Red USB (DNS-320 only) */
-	MPP36_GPIO,	/* Power: Turn off board */
-	MPP37_GPIO,	/* Power: Turn back on after power failure */
-	MPP38_GPIO,
-	MPP39_GPIO,	/* Power: SATA0 */
-	MPP40_GPIO,	/* Power: SATA1 */
-	MPP41_GPIO,	/* SATA0 present */
-	MPP42_GPIO,	/* SATA1 present */
-	MPP43_GPIO,	/* LED: White USB */
-	MPP44_GPIO,	/* Fan: Tachometer Pin */
-	MPP45_GPIO,	/* Fan: high speed */
-	MPP46_GPIO,	/* Fan: low speed */
-	MPP47_GPIO,	/* Button: Back unmount */
-	MPP48_GPIO,	/* Button: Back reset */
-	MPP49_GPIO,	/* Temp Alarm (DNS-325) Pin of U5 (DNS-320) */
-	0
-};
-
-static void dnskw_power_off(void)
-{
-	gpio_set_value(36, 1);
-}
-
 /* Register any GPIO for output and set the value */
 static void __init dnskw_gpio_register(unsigned gpio, char *name, int def)
 {
@@ -76,22 +36,8 @@
 
 void __init dnskw_init(void)
 {
-	kirkwood_mpp_conf(dnskw_mpp_config);
-
-	kirkwood_ehci_init();
 	kirkwood_ge00_init(&dnskw_ge00_data);
 
-	/* Register power-off GPIO. */
-	if (gpio_request(36, "dnskw:power:off") == 0
-	    && gpio_direction_output(36, 0) == 0)
-		pm_power_off = dnskw_power_off;
-	else
-		pr_err("dnskw: failed to configure power-off GPIO\n");
-
-	/* Ensure power is supplied to both HDDs */
-	dnskw_gpio_register(39, "dnskw:power:sata0", 1);
-	dnskw_gpio_register(40, "dnskw:power:sata1", 1);
-
 	/* Set NAS to turn back on after a power failure */
 	dnskw_gpio_register(37, "dnskw:power:recover", 1);
 }
diff --git a/arch/arm/mach-kirkwood/board-dockstar.c b/arch/arm/mach-kirkwood/board-dockstar.c
index 6912882..d7196db 100644
--- a/arch/arm/mach-kirkwood/board-dockstar.c
+++ b/arch/arm/mach-kirkwood/board-dockstar.c
@@ -17,32 +17,16 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/mv643xx_eth.h>
-#include <linux/gpio.h>
 #include "common.h"
-#include "mpp.h"
 
 static struct mv643xx_eth_platform_data dockstar_ge00_data = {
 	.phy_addr	= MV643XX_ETH_PHY_ADDR(0),
 };
 
-static unsigned int dockstar_mpp_config[] __initdata = {
-	MPP29_GPIO,	/* USB Power Enable */
-	MPP46_GPIO,	/* LED green */
-	MPP47_GPIO,	/* LED orange */
-	0
-};
-
 void __init dockstar_dt_init(void)
 {
 	/*
 	 * Basic setup. Needs to be called early.
 	 */
-	kirkwood_mpp_conf(dockstar_mpp_config);
-
-	if (gpio_request(29, "USB Power Enable") != 0 ||
-	    gpio_direction_output(29, 1) != 0)
-		pr_err("can't setup GPIO 29 (USB Power Enable)\n");
-	kirkwood_ehci_init();
-
 	kirkwood_ge00_init(&dockstar_ge00_data);
 }
diff --git a/arch/arm/mach-kirkwood/board-dreamplug.c b/arch/arm/mach-kirkwood/board-dreamplug.c
index 8a8ebe0..08248e2 100644
--- a/arch/arm/mach-kirkwood/board-dreamplug.c
+++ b/arch/arm/mach-kirkwood/board-dreamplug.c
@@ -17,7 +17,6 @@
 #include <linux/gpio.h>
 #include <linux/platform_data/mmc-mvsdio.h>
 #include "common.h"
-#include "mpp.h"
 
 static struct mv643xx_eth_platform_data dreamplug_ge00_data = {
 	.phy_addr	= MV643XX_ETH_PHY_ADDR(0),
@@ -31,25 +30,11 @@
 	/* unfortunately the CD signal has not been connected */
 };
 
-static unsigned int dreamplug_mpp_config[] __initdata = {
-	MPP0_SPI_SCn,
-	MPP1_SPI_MOSI,
-	MPP2_SPI_SCK,
-	MPP3_SPI_MISO,
-	MPP47_GPIO,	/* Bluetooth LED */
-	MPP48_GPIO,	/* Wifi LED */
-	MPP49_GPIO,	/* Wifi AP LED */
-	0
-};
-
 void __init dreamplug_init(void)
 {
 	/*
 	 * Basic setup. Needs to be called early.
 	 */
-	kirkwood_mpp_conf(dreamplug_mpp_config);
-
-	kirkwood_ehci_init();
 	kirkwood_ge00_init(&dreamplug_ge00_data);
 	kirkwood_ge01_init(&dreamplug_ge01_data);
 	kirkwood_sdio_init(&dreamplug_mvsdio_data);
diff --git a/arch/arm/mach-kirkwood/board-goflexnet.c b/arch/arm/mach-kirkwood/board-goflexnet.c
index 5dcd0d6..9db979a 100644
--- a/arch/arm/mach-kirkwood/board-goflexnet.c
+++ b/arch/arm/mach-kirkwood/board-goflexnet.c
@@ -19,40 +19,16 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/mv643xx_eth.h>
-#include <linux/gpio.h>
 #include "common.h"
-#include "mpp.h"
 
 static struct mv643xx_eth_platform_data goflexnet_ge00_data = {
 	.phy_addr	= MV643XX_ETH_PHY_ADDR(0),
 };
 
-static unsigned int goflexnet_mpp_config[] __initdata = {
-	MPP29_GPIO,	/* USB Power Enable */
-	MPP47_GPIO,	/* LED Orange */
-	MPP46_GPIO,	/* LED Green */
-	MPP45_GPIO,	/* LED Left Capacity 3 */
-	MPP44_GPIO,	/* LED Left Capacity 2 */
-	MPP43_GPIO,	/* LED Left Capacity 1 */
-	MPP42_GPIO,	/* LED Left Capacity 0 */
-	MPP41_GPIO,	/* LED Right Capacity 3 */
-	MPP40_GPIO,	/* LED Right Capacity 2 */
-	MPP39_GPIO,	/* LED Right Capacity 1 */
-	MPP38_GPIO,	/* LED Right Capacity 0 */
-	0
-};
-
 void __init goflexnet_init(void)
 {
 	/*
 	 * Basic setup. Needs to be called early.
 	 */
-	kirkwood_mpp_conf(goflexnet_mpp_config);
-
-	if (gpio_request(29, "USB Power Enable") != 0 ||
-	    gpio_direction_output(29, 1) != 0)
-		pr_err("can't setup GPIO 29 (USB Power Enable)\n");
-	kirkwood_ehci_init();
-
 	kirkwood_ge00_init(&goflexnet_ge00_data);
 }
diff --git a/arch/arm/mach-kirkwood/board-ib62x0.c b/arch/arm/mach-kirkwood/board-ib62x0.c
index 6d3a564..9f6f496 100644
--- a/arch/arm/mach-kirkwood/board-ib62x0.c
+++ b/arch/arm/mach-kirkwood/board-ib62x0.c
@@ -14,52 +14,17 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/mv643xx_eth.h>
-#include <linux/gpio.h>
 #include <linux/input.h>
 #include "common.h"
-#include "mpp.h"
-
-#define IB62X0_GPIO_POWER_OFF	24
 
 static struct mv643xx_eth_platform_data ib62x0_ge00_data = {
 	.phy_addr	= MV643XX_ETH_PHY_ADDR(8),
 };
 
-static unsigned int ib62x0_mpp_config[] __initdata = {
-	MPP0_NF_IO2,
-	MPP1_NF_IO3,
-	MPP2_NF_IO4,
-	MPP3_NF_IO5,
-	MPP4_NF_IO6,
-	MPP5_NF_IO7,
-	MPP18_NF_IO0,
-	MPP19_NF_IO1,
-	MPP22_GPIO,	/* OS LED red */
-	MPP24_GPIO,	/* Power off device */
-	MPP25_GPIO,	/* OS LED green */
-	MPP27_GPIO,	/* USB transfer LED */
-	MPP28_GPIO,	/* Reset button */
-	MPP29_GPIO,	/* USB Copy button */
-	0
-};
-
-static void ib62x0_power_off(void)
-{
-	gpio_set_value(IB62X0_GPIO_POWER_OFF, 1);
-}
-
 void __init ib62x0_init(void)
 {
 	/*
 	 * Basic setup. Needs to be called early.
 	 */
-	kirkwood_mpp_conf(ib62x0_mpp_config);
-
-	kirkwood_ehci_init();
 	kirkwood_ge00_init(&ib62x0_ge00_data);
-	if (gpio_request(IB62X0_GPIO_POWER_OFF, "ib62x0:power:off") == 0 &&
-	    gpio_direction_output(IB62X0_GPIO_POWER_OFF, 0) == 0)
-		pm_power_off = ib62x0_power_off;
-	else
-		pr_err("board-ib62x0: failed to configure power-off GPIO\n");
 }
diff --git a/arch/arm/mach-kirkwood/board-iconnect.c b/arch/arm/mach-kirkwood/board-iconnect.c
index 24f5aa7..c8ebde4 100644
--- a/arch/arm/mach-kirkwood/board-iconnect.c
+++ b/arch/arm/mach-kirkwood/board-iconnect.c
@@ -13,31 +13,13 @@
 #include <linux/of.h>
 #include <linux/mv643xx_eth.h>
 #include "common.h"
-#include "mpp.h"
 
 static struct mv643xx_eth_platform_data iconnect_ge00_data = {
 	.phy_addr	= MV643XX_ETH_PHY_ADDR(11),
 };
 
-static unsigned int iconnect_mpp_config[] __initdata = {
-	MPP12_GPIO,
-	MPP35_GPIO,
-	MPP41_GPIO,
-	MPP42_GPIO,
-	MPP43_GPIO,
-	MPP44_GPIO,
-	MPP45_GPIO,
-	MPP46_GPIO,
-	MPP47_GPIO,
-	MPP48_GPIO,
-	0
-};
-
 void __init iconnect_init(void)
 {
-	kirkwood_mpp_conf(iconnect_mpp_config);
-
-	kirkwood_ehci_init();
 	kirkwood_ge00_init(&iconnect_ge00_data);
 }
 
diff --git a/arch/arm/mach-kirkwood/board-iomega_ix2_200.c b/arch/arm/mach-kirkwood/board-iomega_ix2_200.c
index e4ed62c..f655b26 100644
--- a/arch/arm/mach-kirkwood/board-iomega_ix2_200.c
+++ b/arch/arm/mach-kirkwood/board-iomega_ix2_200.c
@@ -13,7 +13,6 @@
 #include <linux/mv643xx_eth.h>
 #include <linux/ethtool.h>
 #include "common.h"
-#include "mpp.h"
 
 static struct mv643xx_eth_platform_data iomega_ix2_200_ge00_data = {
 	.phy_addr       = MV643XX_ETH_PHY_NONE,
@@ -21,35 +20,10 @@
 	.duplex         = DUPLEX_FULL,
 };
 
-static unsigned int iomega_ix2_200_mpp_config[] __initdata = {
-	MPP12_GPIO,			/* Reset Button */
-	MPP14_GPIO,			/* Power Button */
-	MPP15_GPIO,			/* Backup LED (blue) */
-	MPP16_GPIO,			/* Power LED (white) */
-	MPP35_GPIO,			/* OTB Button */
-	MPP36_GPIO,			/* Rebuild LED (white) */
-	MPP37_GPIO,			/* Health LED (red) */
-	MPP38_GPIO,			/* SATA LED brightness control 1 */
-	MPP39_GPIO,			/* SATA LED brightness control 2 */
-	MPP40_GPIO,			/* Backup LED brightness control 1 */
-	MPP41_GPIO,			/* Backup LED brightness control 2 */
-	MPP42_GPIO,			/* Power LED brightness control 1 */
-	MPP43_GPIO,			/* Power LED brightness control 2 */
-	MPP44_GPIO,			/* Health LED brightness control 1 */
-	MPP45_GPIO,			/* Health LED brightness control 2 */
-	MPP46_GPIO,			/* Rebuild LED brightness control 1 */
-	MPP47_GPIO,			/* Rebuild LED brightness control 2 */
-	0
-};
-
 void __init iomega_ix2_200_init(void)
 {
 	/*
 	 * Basic setup. Needs to be called early.
 	 */
-	kirkwood_mpp_conf(iomega_ix2_200_mpp_config);
-
-	kirkwood_ehci_init();
-
 	kirkwood_ge01_init(&iomega_ix2_200_ge00_data);
 }
diff --git a/arch/arm/mach-kirkwood/board-km_kirkwood.c b/arch/arm/mach-kirkwood/board-km_kirkwood.c
index f7d3283..44e4605 100644
--- a/arch/arm/mach-kirkwood/board-km_kirkwood.c
+++ b/arch/arm/mach-kirkwood/board-km_kirkwood.c
@@ -18,27 +18,15 @@
 #include <linux/clk.h>
 #include <linux/clk-private.h>
 #include "common.h"
-#include "mpp.h"
 
 static struct mv643xx_eth_platform_data km_kirkwood_ge00_data = {
 	.phy_addr	= MV643XX_ETH_PHY_ADDR(0),
 };
 
-static unsigned int km_kirkwood_mpp_config[] __initdata = {
-	MPP8_GPIO,	/* I2C SDA */
-	MPP9_GPIO,	/* I2C SCL */
-	0
-};
-
 void __init km_kirkwood_init(void)
 {
 	struct clk *sata_clk;
 	/*
-	 * Basic setup. Needs to be called early.
-	 */
-	kirkwood_mpp_conf(km_kirkwood_mpp_config);
-
-	/*
 	 * Our variant of kirkwood (integrated in the Bobcat) hangs on accessing
 	 * SATA bits (14-15) of the Clock Gating Control Register. Since these
 	 * devices are also not present in this variant, their clocks get
@@ -52,6 +40,5 @@
 	if (!IS_ERR(sata_clk))
 		sata_clk->flags |= CLK_IGNORE_UNUSED;
 
-	kirkwood_ehci_init();
 	kirkwood_ge00_init(&km_kirkwood_ge00_data);
 }
diff --git a/arch/arm/mach-kirkwood/board-lsxl.c b/arch/arm/mach-kirkwood/board-lsxl.c
index 7e18cad..4ec8b7a 100644
--- a/arch/arm/mach-kirkwood/board-lsxl.c
+++ b/arch/arm/mach-kirkwood/board-lsxl.c
@@ -15,9 +15,7 @@
 #include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/mv643xx_eth.h>
-#include <linux/gpio.h>
 #include "common.h"
-#include "mpp.h"
 
 static struct mv643xx_eth_platform_data lsxl_ge00_data = {
 	.phy_addr	= MV643XX_ETH_PHY_ADDR(0),
@@ -27,23 +25,6 @@
 	.phy_addr	= MV643XX_ETH_PHY_ADDR(8),
 };
 
-static unsigned int lsxl_mpp_config[] __initdata = {
-	MPP10_GPO,	/* HDD Power Enable */
-	MPP11_GPIO,	/* USB Vbus Enable */
-	MPP18_GPO,	/* FAN High Enable# */
-	MPP19_GPO,	/* FAN Low Enable# */
-	MPP36_GPIO,	/* Function Blue LED */
-	MPP37_GPIO,	/* Alarm LED */
-	MPP38_GPIO,	/* Info LED */
-	MPP39_GPIO,	/* Power LED */
-	MPP40_GPIO,	/* Fan Lock */
-	MPP41_GPIO,	/* Function Button */
-	MPP42_GPIO,	/* Power Switch */
-	MPP43_GPIO,	/* Power Auto Switch */
-	MPP48_GPIO,	/* Function Red LED */
-	0
-};
-
 /*
  * On the LS-XHL/LS-CHLv2, the shutdown process is following:
  * - Userland monitors key events until the power switch goes to off position
@@ -57,21 +38,12 @@
 	kirkwood_restart('h', NULL);
 }
 
-#define LSXL_GPIO_HDD_POWER 10
-#define LSXL_GPIO_USB_POWER 11
-
 void __init lsxl_init(void)
 {
 	/*
 	 * Basic setup. Needs to be called early.
 	 */
-	kirkwood_mpp_conf(lsxl_mpp_config);
 
-	/* usb and sata power on */
-	gpio_set_value(LSXL_GPIO_USB_POWER, 1);
-	gpio_set_value(LSXL_GPIO_HDD_POWER, 1);
-
-	kirkwood_ehci_init();
 	kirkwood_ge00_init(&lsxl_ge00_data);
 	kirkwood_ge01_init(&lsxl_ge01_data);
 
diff --git a/arch/arm/mach-kirkwood/board-mplcec4.c b/arch/arm/mach-kirkwood/board-mplcec4.c
index e78a227..56bfe5a 100644
--- a/arch/arm/mach-kirkwood/board-mplcec4.c
+++ b/arch/arm/mach-kirkwood/board-mplcec4.c
@@ -24,52 +24,16 @@
 	.phy_addr	= MV643XX_ETH_PHY_ADDR(2),
 };
 
-static unsigned int mplcec4_mpp_config[] __initdata = {
-	MPP0_NF_IO2,
-	MPP1_NF_IO3,
-	MPP2_NF_IO4,
-	MPP3_NF_IO5,
-	MPP4_NF_IO6,
-	MPP5_NF_IO7,
-	MPP6_SYSRST_OUTn,
-	MPP7_GPO,	/* Status LED Green High Active */
-	MPP10_UART0_TXD,
-	MPP11_UART0_RXD,
-	MPP12_SD_CLK,
-	MPP13_SD_CMD,	/* Alt UART1_TXD */
-	MPP14_SD_D0,	/* Alt UART1_RXD */
-	MPP15_SD_D1,
-	MPP16_SD_D2,
-	MPP17_SD_D3,
-	MPP18_NF_IO0,
-	MPP19_NF_IO1,
-	MPP28_GPIO,	/* Input SYS_POR_DET (active High) */
-	MPP29_GPIO,	/* Input SYS_RTC_INT (active High) */
-	MPP34_SATA1_ACTn,
-	MPP35_SATA0_ACTn,
-	MPP40_GPIO,	/* LED User1 orange */
-	MPP41_GPIO,	/* LED User1 green */
-	MPP44_GPIO,	/* LED User0 orange */
-	MPP45_GPIO,	/* LED User0 green */
-	MPP46_GPIO,	/* Status LED Yellow High Active */
-	MPP47_GPIO,	/* SD_CD# (in/IRQ)*/
-	0
-};
-
-
 static struct mvsdio_platform_data mplcec4_mvsdio_data = {
 	.gpio_card_detect = 47,	/* MPP47 used as SD card detect */
 };
 
 
-
 void __init mplcec4_init(void)
 {
 	/*
 	 * Basic setup. Needs to be called early.
 	 */
-	kirkwood_mpp_conf(mplcec4_mpp_config);
-	kirkwood_ehci_init();
 	kirkwood_ge00_init(&mplcec4_ge00_data);
 	kirkwood_ge01_init(&mplcec4_ge01_data);
 	kirkwood_sdio_init(&mplcec4_mvsdio_data);
diff --git a/arch/arm/mach-kirkwood/board-ns2.c b/arch/arm/mach-kirkwood/board-ns2.c
index 78596c4..8821720 100644
--- a/arch/arm/mach-kirkwood/board-ns2.c
+++ b/arch/arm/mach-kirkwood/board-ns2.c
@@ -73,7 +73,6 @@
 	 */
 	kirkwood_mpp_conf(ns2_mpp_config);
 
-	kirkwood_ehci_init();
 	if (of_machine_is_compatible("lacie,netspace_lite_v2") ||
 	    of_machine_is_compatible("lacie,netspace_mini_v2"))
 		ns2_ge00_data.phy_addr = MV643XX_ETH_PHY_ADDR(0);
diff --git a/arch/arm/mach-kirkwood/board-nsa310.c b/arch/arm/mach-kirkwood/board-nsa310.c
index 027ce83..f58d2e1 100644
--- a/arch/arm/mach-kirkwood/board-nsa310.c
+++ b/arch/arm/mach-kirkwood/board-nsa310.c
@@ -85,10 +85,6 @@
 
 	nsa310_gpio_init();
 
-	/* this can be removed once the mainline kirkwood.dtsi gets
-	 * the ehci configuration by default */
-	kirkwood_ehci_init();
-
 	kirkwood_pcie_id(&dev, &rev);
 
 	i2c_register_board_info(0, ARRAY_AND_SIZE(nsa310_i2c_info));
diff --git a/arch/arm/mach-kirkwood/board-openblocks_a6.c b/arch/arm/mach-kirkwood/board-openblocks_a6.c
index e807e8c..815fc64 100644
--- a/arch/arm/mach-kirkwood/board-openblocks_a6.c
+++ b/arch/arm/mach-kirkwood/board-openblocks_a6.c
@@ -55,8 +55,8 @@
 	MPP38_GPIO, /* INIT */
 	MPP39_GPIO, /* USB OC */
 	MPP41_GPIO, /* LED: Red */
-	MPP42_GPIO, /* LED: Yellow */
-	MPP43_GPIO, /* LED: Green */
+	MPP42_GPIO, /* LED: Green */
+	MPP43_GPIO, /* LED: Yellow */
 	0,
 };
 
@@ -66,6 +66,5 @@
 	 * Basic setup. Needs to be called early.
 	 */
 	kirkwood_mpp_conf(openblocks_a6_mpp_config);
-	kirkwood_ehci_init();
 	kirkwood_ge00_init(&openblocks_ge00_data);
 }
diff --git a/arch/arm/mach-kirkwood/board-ts219.c b/arch/arm/mach-kirkwood/board-ts219.c
index f3bfeda..acb0187 100644
--- a/arch/arm/mach-kirkwood/board-ts219.c
+++ b/arch/arm/mach-kirkwood/board-ts219.c
@@ -23,47 +23,21 @@
 #include <asm/mach/arch.h>
 #include <mach/kirkwood.h>
 #include "common.h"
-#include "mpp.h"
 #include "tsx1x-common.h"
 
 static struct mv643xx_eth_platform_data qnap_ts219_ge00_data = {
 	.phy_addr	= MV643XX_ETH_PHY_ADDR(8),
 };
 
-static unsigned int qnap_ts219_mpp_config[] __initdata = {
-	MPP0_SPI_SCn,
-	MPP1_SPI_MOSI,
-	MPP2_SPI_SCK,
-	MPP3_SPI_MISO,
-	MPP4_SATA1_ACTn,
-	MPP5_SATA0_ACTn,
-	MPP8_TW0_SDA,
-	MPP9_TW0_SCK,
-	MPP10_UART0_TXD,
-	MPP11_UART0_RXD,
-	MPP13_UART1_TXD,	/* PIC controller */
-	MPP14_UART1_RXD,	/* PIC controller */
-	MPP15_GPIO,		/* USB Copy button (on devices with 88F6281) */
-	MPP16_GPIO,		/* Reset button (on devices with 88F6281) */
-	MPP36_GPIO,		/* RAM: 0: 256 MB, 1: 512 MB */
-	MPP37_GPIO,		/* Reset button (on devices with 88F6282) */
-	MPP43_GPIO,		/* USB Copy button (on devices with 88F6282) */
-	MPP44_GPIO,		/* Board ID: 0: TS-11x, 1: TS-21x */
-	0
-};
-
 void __init qnap_dt_ts219_init(void)
 {
 	u32 dev, rev;
 
-	kirkwood_mpp_conf(qnap_ts219_mpp_config);
-
 	kirkwood_pcie_id(&dev, &rev);
 	if (dev == MV88F6282_DEV_ID)
 		qnap_ts219_ge00_data.phy_addr = MV643XX_ETH_PHY_ADDR(0);
 
 	kirkwood_ge00_init(&qnap_ts219_ge00_data);
-	kirkwood_ehci_init();
 
 	pm_power_off = qnap_tsx1x_power_off;
 }
diff --git a/arch/arm/mach-kirkwood/board-usi_topkick.c b/arch/arm/mach-kirkwood/board-usi_topkick.c
index e2ec9d8..15e69fc 100644
--- a/arch/arm/mach-kirkwood/board-usi_topkick.c
+++ b/arch/arm/mach-kirkwood/board-usi_topkick.c
@@ -76,7 +76,6 @@
 	/* SATA0 power enable */
 	gpio_set_value(TOPKICK_SATA0_PWR_ENABLE, 1);
 
-	kirkwood_ehci_init();
 	kirkwood_ge00_init(&topkick_ge00_data);
 	kirkwood_sdio_init(&topkick_mvsdio_data);
 }
diff --git a/arch/arm/mach-mxs/mach-mxs.c b/arch/arm/mach-mxs/mach-mxs.c
index 4748ec5..9807037 100644
--- a/arch/arm/mach-mxs/mach-mxs.c
+++ b/arch/arm/mach-mxs/mach-mxs.c
@@ -100,6 +100,25 @@
 	},
 };
 
+static struct fb_videomode apf28dev_video_modes[] = {
+	{
+		.name = "LW700",
+		.refresh = 60,
+		.xres = 800,
+		.yres = 480,
+		.pixclock = 30303, /* picosecond */
+		.left_margin = 96,
+		.right_margin = 96, /* at least 3 & 1 */
+		.upper_margin = 0x14,
+		.lower_margin = 0x15,
+		.hsync_len = 64,
+		.vsync_len = 4,
+		.sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT |
+				FB_SYNC_DATA_ENABLE_HIGH_ACT |
+				FB_SYNC_DOTCLK_FAILING_ACT,
+	},
+};
+
 static struct mxsfb_platform_data mxsfb_pdata __initdata;
 
 /*
@@ -160,6 +179,7 @@
 enum mac_oui {
 	OUI_FSL,
 	OUI_DENX,
+	OUI_CRYSTALFONTZ,
 };
 
 static void __init update_fec_mac_prop(enum mac_oui oui)
@@ -175,8 +195,12 @@
 		np = of_find_compatible_node(from, NULL, "fsl,imx28-fec");
 		if (!np)
 			return;
+
 		from = np;
 
+		if (of_get_property(np, "local-mac-address", NULL))
+			continue;
+
 		newmac = kzalloc(sizeof(*newmac) + 6, GFP_KERNEL);
 		if (!newmac)
 			return;
@@ -205,6 +229,11 @@
 			macaddr[1] = 0xe5;
 			macaddr[2] = 0x4e;
 			break;
+		case OUI_CRYSTALFONTZ:
+			macaddr[0] = 0x58;
+			macaddr[1] = 0xb9;
+			macaddr[2] = 0xe1;
+			break;
 		}
 		val = ocotp[i];
 		macaddr[3] = (val >> 16) & 0xff;
@@ -261,6 +290,11 @@
 	mxsfb_pdata.ld_intf_width = STMLCDIF_18BIT;
 }
 
+static void __init sc_sps1_init(void)
+{
+	enable_clk_enet_out();
+}
+
 static int apx4devkit_phy_fixup(struct phy_device *phy)
 {
 	phy->dev_flags |= MICREL_PHY_50MHZ_CLK;
@@ -355,6 +389,22 @@
 	pinctrl_put(pctl);
 }
 
+static void __init cfa10049_init(void)
+{
+	enable_clk_enet_out();
+	update_fec_mac_prop(OUI_CRYSTALFONTZ);
+}
+
+static void __init apf28_init(void)
+{
+	enable_clk_enet_out();
+
+	mxsfb_pdata.mode_list = apf28dev_video_modes;
+	mxsfb_pdata.mode_count = ARRAY_SIZE(apf28dev_video_modes);
+	mxsfb_pdata.default_bpp = 16;
+	mxsfb_pdata.ld_intf_width = STMLCDIF_16BIT;
+}
+
 static void __init mxs_machine_init(void)
 {
 	if (of_machine_is_compatible("fsl,imx28-evk"))
@@ -365,6 +415,12 @@
 		m28evk_init();
 	else if (of_machine_is_compatible("bluegiga,apx4devkit"))
 		apx4devkit_init();
+	else if (of_machine_is_compatible("crystalfontz,cfa10049"))
+		cfa10049_init();
+	else if (of_machine_is_compatible("armadeus,imx28-apf28"))
+		apf28_init();
+	else if (of_machine_is_compatible("schulercontrol,imx28-sps1"))
+		sc_sps1_init();
 
 	of_platform_populate(NULL, of_default_bus_match_table,
 			     mxs_auxdata_lookup, NULL);
diff --git a/arch/arm/mach-mxs/timer.c b/arch/arm/mach-mxs/timer.c
index 7c37926..856f4c7 100644
--- a/arch/arm/mach-mxs/timer.c
+++ b/arch/arm/mach-mxs/timer.c
@@ -29,6 +29,7 @@
 #include <linux/of_irq.h>
 
 #include <asm/mach/time.h>
+#include <asm/sched_clock.h>
 #include <mach/mxs.h>
 #include <mach/common.h>
 
@@ -233,15 +234,22 @@
 	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
 };
 
+static u32 notrace mxs_read_sched_clock_v2(void)
+{
+	return ~readl_relaxed(mxs_timrot_base + HW_TIMROT_RUNNING_COUNTn(1));
+}
+
 static int __init mxs_clocksource_init(struct clk *timer_clk)
 {
 	unsigned int c = clk_get_rate(timer_clk);
 
 	if (timrot_is_v1())
 		clocksource_register_hz(&clocksource_mxs, c);
-	else
+	else {
 		clocksource_mmio_init(mxs_timrot_base + HW_TIMROT_RUNNING_COUNTn(1),
 			"mxs_timer", c, 200, 32, clocksource_mmio_readl_down);
+		setup_sched_clock(mxs_read_sched_clock_v2, 32, c);
+	}
 
 	return 0;
 }
diff --git a/arch/arm/mach-netx/xc.c b/arch/arm/mach-netx/xc.c
index e4cfb7e..f1c972d 100644
--- a/arch/arm/mach-netx/xc.c
+++ b/arch/arm/mach-netx/xc.c
@@ -136,7 +136,7 @@
 	if (head->magic != 0x4e657458) {
 		if (head->magic == 0x5874654e) {
 			dev_err(x->dev,
-			    "firmware magic is 'XteN'. Endianess problems?\n");
+			    "firmware magic is 'XteN'. Endianness problems?\n");
 			ret = -ENODEV;
 			goto exit_release_firmware;
 		}
diff --git a/arch/arm/mach-nomadik/Kconfig b/arch/arm/mach-nomadik/Kconfig
index c744946..706dc57 100644
--- a/arch/arm/mach-nomadik/Kconfig
+++ b/arch/arm/mach-nomadik/Kconfig
@@ -4,7 +4,7 @@
 
 config MACH_NOMADIK_8815NHK
 	bool "ST 8815 Nomadik Hardware Kit (evaluation board)"
-	select HAS_MTU
+	select CLKSRC_NOMADIK_MTU
 	select NOMADIK_8815
 
 endmenu
diff --git a/arch/arm/mach-nomadik/board-nhk8815.c b/arch/arm/mach-nomadik/board-nhk8815.c
index 22ef8a1..5ccdf53 100644
--- a/arch/arm/mach-nomadik/board-nhk8815.c
+++ b/arch/arm/mach-nomadik/board-nhk8815.c
@@ -25,18 +25,16 @@
 #include <linux/io.h>
 #include <linux/pinctrl/machine.h>
 #include <linux/platform_data/pinctrl-nomadik.h>
+#include <linux/platform_data/clocksource-nomadik-mtu.h>
+#include <linux/platform_data/mtd-nomadik-nand.h>
 #include <asm/hardware/vic.h>
 #include <asm/sizes.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
-#include <asm/mach/irq.h>
 #include <asm/mach/flash.h>
 #include <asm/mach/time.h>
-
-#include <plat/mtu.h>
-
-#include <linux/platform_data/mtd-nomadik-nand.h>
 #include <mach/fsmc.h>
+#include <mach/irqs.h>
 
 #include "cpu-8815.h"
 
@@ -260,7 +258,7 @@
 	src_cr |= SRC_CR_INIT_VAL;
 	writel(src_cr, io_p2v(NOMADIK_SRC_BASE));
 
-	nmdk_timer_init(io_p2v(NOMADIK_MTU0_BASE));
+	nmdk_timer_init(io_p2v(NOMADIK_MTU0_BASE), IRQ_MTU0);
 }
 
 static struct sys_timer nomadik_timer = {
diff --git a/arch/arm/mach-nomadik/include/mach/irqs.h b/arch/arm/mach-nomadik/include/mach/irqs.h
index a118e615..b549d05 100644
--- a/arch/arm/mach-nomadik/include/mach/irqs.h
+++ b/arch/arm/mach-nomadik/include/mach/irqs.h
@@ -72,7 +72,7 @@
 #define NOMADIK_NR_GPIO			128 /* last 4 not wired to pins */
 #define NOMADIK_GPIO_TO_IRQ(gpio)	((gpio) + NOMADIK_GPIO_OFFSET)
 #define NOMADIK_IRQ_TO_GPIO(irq)	((irq) - NOMADIK_GPIO_OFFSET)
-#define NR_IRQS				NOMADIK_GPIO_TO_IRQ(NOMADIK_NR_GPIO)
+#define NOMADIK_NR_IRQS			NOMADIK_GPIO_TO_IRQ(NOMADIK_NR_GPIO)
 
 /* Following two are used by entry_macro.S, to access our dual-vic */
 #define VIC_REG_IRQSR0		0
diff --git a/arch/arm/mach-omap1/board-h2.c b/arch/arm/mach-omap1/board-h2.c
index 4953cf7..2274bd6 100644
--- a/arch/arm/mach-omap1/board-h2.c
+++ b/arch/arm/mach-omap1/board-h2.c
@@ -39,7 +39,7 @@
 #include <asm/mach/map.h>
 
 #include <mach/mux.h>
-#include <plat-omap/dma-omap.h>
+#include <linux/omap-dma.h>
 #include <mach/tc.h>
 #include <mach/irda.h>
 #include <linux/platform_data/keypad-omap.h>
diff --git a/arch/arm/mach-omap1/board-h3.c b/arch/arm/mach-omap1/board-h3.c
index 563ba16..1051935 100644
--- a/arch/arm/mach-omap1/board-h3.c
+++ b/arch/arm/mach-omap1/board-h3.c
@@ -43,7 +43,7 @@
 #include <mach/mux.h>
 #include <mach/tc.h>
 #include <linux/platform_data/keypad-omap.h>
-#include <plat-omap/dma-omap.h>
+#include <linux/omap-dma.h>
 #include <mach/flash.h>
 
 #include <mach/hardware.h>
diff --git a/arch/arm/mach-omap1/board-palmte.c b/arch/arm/mach-omap1/board-palmte.c
index 584b6fa..c33dceb 100644
--- a/arch/arm/mach-omap1/board-palmte.c
+++ b/arch/arm/mach-omap1/board-palmte.c
@@ -37,7 +37,7 @@
 #include <mach/flash.h>
 #include <mach/mux.h>
 #include <mach/tc.h>
-#include <plat-omap/dma-omap.h>
+#include <linux/omap-dma.h>
 #include <mach/irda.h>
 #include <linux/platform_data/keypad-omap.h>
 
diff --git a/arch/arm/mach-omap1/board-palmtt.c b/arch/arm/mach-omap1/board-palmtt.c
index fbc986b..2948b0e 100644
--- a/arch/arm/mach-omap1/board-palmtt.c
+++ b/arch/arm/mach-omap1/board-palmtt.c
@@ -36,7 +36,7 @@
 
 #include <mach/flash.h>
 #include <mach/mux.h>
-#include <plat-omap/dma-omap.h>
+#include <linux/omap-dma.h>
 #include <mach/tc.h>
 #include <mach/irda.h>
 #include <linux/platform_data/keypad-omap.h>
diff --git a/arch/arm/mach-omap1/board-palmz71.c b/arch/arm/mach-omap1/board-palmz71.c
index 60d917a..7a05895 100644
--- a/arch/arm/mach-omap1/board-palmz71.c
+++ b/arch/arm/mach-omap1/board-palmz71.c
@@ -38,7 +38,7 @@
 
 #include <mach/flash.h>
 #include <mach/mux.h>
-#include <plat-omap/dma-omap.h>
+#include <linux/omap-dma.h>
 #include <mach/tc.h>
 #include <mach/irda.h>
 #include <linux/platform_data/keypad-omap.h>
diff --git a/arch/arm/mach-omap1/board-sx1.c b/arch/arm/mach-omap1/board-sx1.c
index 1ebc7e0..20ed52a 100644
--- a/arch/arm/mach-omap1/board-sx1.c
+++ b/arch/arm/mach-omap1/board-sx1.c
@@ -36,7 +36,7 @@
 
 #include <mach/flash.h>
 #include <mach/mux.h>
-#include <plat-omap/dma-omap.h>
+#include <linux/omap-dma.h>
 #include <mach/irda.h>
 #include <mach/tc.h>
 #include <mach/board-sx1.h>
diff --git a/arch/arm/mach-omap1/dma.c b/arch/arm/mach-omap1/dma.c
index 978aed8..e190611 100644
--- a/arch/arm/mach-omap1/dma.c
+++ b/arch/arm/mach-omap1/dma.c
@@ -25,7 +25,7 @@
 #include <linux/device.h>
 #include <linux/io.h>
 
-#include <plat-omap/dma-omap.h>
+#include <linux/omap-dma.h>
 #include <mach/tc.h>
 
 #include <mach/irqs.h>
diff --git a/arch/arm/mach-omap1/io.c b/arch/arm/mach-omap1/io.c
index 5a3b806..499b8ac 100644
--- a/arch/arm/mach-omap1/io.c
+++ b/arch/arm/mach-omap1/io.c
@@ -18,7 +18,7 @@
 
 #include <mach/mux.h>
 #include <mach/tc.h>
-#include <plat-omap/dma-omap.h>
+#include <linux/omap-dma.h>
 
 #include "iomap.h"
 #include "common.h"
diff --git a/arch/arm/mach-omap1/lcd_dma.c b/arch/arm/mach-omap1/lcd_dma.c
index 7ed8c18..77924be 100644
--- a/arch/arm/mach-omap1/lcd_dma.c
+++ b/arch/arm/mach-omap1/lcd_dma.c
@@ -27,7 +27,7 @@
 #include <linux/interrupt.h>
 #include <linux/io.h>
 
-#include <plat-omap/dma-omap.h>
+#include <linux/omap-dma.h>
 
 #include <mach/hardware.h>
 #include <mach/lcdc.h>
diff --git a/arch/arm/mach-omap1/mcbsp.c b/arch/arm/mach-omap1/mcbsp.c
index c6d8fdf..b0d4723 100644
--- a/arch/arm/mach-omap1/mcbsp.c
+++ b/arch/arm/mach-omap1/mcbsp.c
@@ -19,7 +19,7 @@
 #include <linux/platform_device.h>
 #include <linux/slab.h>
 
-#include <plat-omap/dma-omap.h>
+#include <linux/omap-dma.h>
 #include <mach/mux.h>
 #include "soc.h"
 #include <linux/platform_data/asoc-ti-mcbsp.h>
diff --git a/arch/arm/mach-omap1/pm.c b/arch/arm/mach-omap1/pm.c
index 66d663a..7a7690a 100644
--- a/arch/arm/mach-omap1/pm.c
+++ b/arch/arm/mach-omap1/pm.c
@@ -52,7 +52,7 @@
 
 #include <mach/tc.h>
 #include <mach/mux.h>
-#include <plat-omap/dma-omap.h>
+#include <linux/omap-dma.h>
 #include <plat/dmtimer.h>
 
 #include <mach/irqs.h>
diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig
index 2265e58..be0f62b 100644
--- a/arch/arm/mach-omap2/Kconfig
+++ b/arch/arm/mach-omap2/Kconfig
@@ -34,6 +34,7 @@
 	select CPU_V6
 	select MULTI_IRQ_HANDLER
 	select SOC_HAS_OMAP2_SDRC
+	select COMMON_CLK
 
 config ARCH_OMAP3
 	bool "TI OMAP3"
@@ -47,6 +48,7 @@
 	select PM_OPP if PM
 	select PM_RUNTIME if CPU_IDLE
 	select SOC_HAS_OMAP2_SDRC
+	select COMMON_CLK
 	select USB_ARCH_HAS_EHCI if USB_SUPPORT
 
 config ARCH_OMAP4
@@ -68,6 +70,7 @@
 	select PM_OPP if PM
 	select PM_RUNTIME if CPU_IDLE
 	select USB_ARCH_HAS_EHCI if USB_SUPPORT
+	select COMMON_CLK
 
 config SOC_OMAP5
 	bool "TI OMAP5"
@@ -77,6 +80,7 @@
 	select CPU_V7
 	select HAVE_SMP
 	select SOC_HAS_REALTIME_COUNTER
+	select COMMON_CLK
 
 comment "OMAP Core Type"
 	depends on ARCH_OMAP2
@@ -111,6 +115,7 @@
 	select ARM_CPU_SUSPEND if PM
 	select CPU_V7
 	select MULTI_IRQ_HANDLER
+	select COMMON_CLK
 
 config OMAP_PACKAGE_ZAF
        bool
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
index b455ffc..a8004f3 100644
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -160,17 +160,17 @@
 obj-$(CONFIG_ARCH_OMAP2)		+= clkt2xxx_virt_prcm_set.o
 obj-$(CONFIG_ARCH_OMAP2)		+= clkt2xxx_apll.o clkt2xxx_osc.o
 obj-$(CONFIG_ARCH_OMAP2)		+= clkt2xxx_dpll.o clkt_iclk.o
-obj-$(CONFIG_SOC_OMAP2420)		+= clock2420_data.o
-obj-$(CONFIG_SOC_OMAP2430)		+= clock2430.o clock2430_data.o
+obj-$(CONFIG_SOC_OMAP2420)		+= cclock2420_data.o
+obj-$(CONFIG_SOC_OMAP2430)		+= clock2430.o cclock2430_data.o
 obj-$(CONFIG_ARCH_OMAP3)		+= $(clock-common) clock3xxx.o
 obj-$(CONFIG_ARCH_OMAP3)		+= clock34xx.o clkt34xx_dpll3m2.o
 obj-$(CONFIG_ARCH_OMAP3)		+= clock3517.o clock36xx.o
-obj-$(CONFIG_ARCH_OMAP3)		+= dpll3xxx.o clock3xxx_data.o
+obj-$(CONFIG_ARCH_OMAP3)		+= dpll3xxx.o cclock3xxx_data.o
 obj-$(CONFIG_ARCH_OMAP3)		+= clkt_iclk.o
-obj-$(CONFIG_ARCH_OMAP4)		+= $(clock-common) clock44xx_data.o
+obj-$(CONFIG_ARCH_OMAP4)		+= $(clock-common) cclock44xx_data.o
 obj-$(CONFIG_ARCH_OMAP4)		+= dpll3xxx.o dpll44xx.o
 obj-$(CONFIG_SOC_AM33XX)		+= $(clock-common) dpll3xxx.o
-obj-$(CONFIG_SOC_AM33XX)		+= clock33xx_data.o
+obj-$(CONFIG_SOC_AM33XX)		+= cclock33xx_data.o
 obj-$(CONFIG_SOC_OMAP5)			+= $(clock-common)
 obj-$(CONFIG_SOC_OMAP5)			+= dpll3xxx.o dpll44xx.o
 
diff --git a/arch/arm/mach-omap2/board-3430sdp.c b/arch/arm/mach-omap2/board-3430sdp.c
index 6601754..7b20154 100644
--- a/arch/arm/mach-omap2/board-3430sdp.c
+++ b/arch/arm/mach-omap2/board-3430sdp.c
@@ -31,7 +31,7 @@
 #include <asm/mach/map.h>
 
 #include "common.h"
-#include <plat-omap/dma-omap.h>
+#include <linux/omap-dma.h>
 #include <video/omapdss.h>
 #include <video/omap-panel-tfp410.h>
 
diff --git a/arch/arm/mach-omap2/board-h4.c b/arch/arm/mach-omap2/board-h4.c
index b626dbe..9a3878e 100644
--- a/arch/arm/mach-omap2/board-h4.c
+++ b/arch/arm/mach-omap2/board-h4.c
@@ -32,7 +32,7 @@
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 
-#include <plat-omap/dma-omap.h>
+#include <linux/omap-dma.h>
 #include <plat/debug-devices.h>
 
 #include <video/omapdss.h>
diff --git a/arch/arm/mach-omap2/board-rx51-peripherals.c b/arch/arm/mach-omap2/board-rx51-peripherals.c
index 07005fe..60529e0 100644
--- a/arch/arm/mach-omap2/board-rx51-peripherals.c
+++ b/arch/arm/mach-omap2/board-rx51-peripherals.c
@@ -31,7 +31,7 @@
 #include <asm/system_info.h>
 
 #include "common.h"
-#include <plat-omap/dma-omap.h>
+#include <linux/omap-dma.h>
 #include "gpmc-smc91x.h"
 
 #include "board-rx51.h"
diff --git a/arch/arm/mach-omap2/board-rx51.c b/arch/arm/mach-omap2/board-rx51.c
index b67fe11..f1d6efe 100644
--- a/arch/arm/mach-omap2/board-rx51.c
+++ b/arch/arm/mach-omap2/board-rx51.c
@@ -24,7 +24,7 @@
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 
-#include <plat-omap/dma-omap.h>
+#include <linux/omap-dma.h>
 
 #include "common.h"
 #include "mux.h"
diff --git a/arch/arm/mach-omap2/cclock2420_data.c b/arch/arm/mach-omap2/cclock2420_data.c
new file mode 100644
index 0000000..7e5febe
--- /dev/null
+++ b/arch/arm/mach-omap2/cclock2420_data.c
@@ -0,0 +1,1950 @@
+/*
+ * OMAP2420 clock data
+ *
+ * Copyright (C) 2005-2012 Texas Instruments, Inc.
+ * Copyright (C) 2004-2011 Nokia Corporation
+ *
+ * Contacts:
+ * Richard Woodruff <r-woodruff2@ti.com>
+ * Paul Walmsley
+ * Updated to COMMON clk format by Rajendra Nayak <rnayak@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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/clk-private.h>
+#include <linux/list.h>
+
+#include "soc.h"
+#include "iomap.h"
+#include "clock.h"
+#include "clock2xxx.h"
+#include "opp2xxx.h"
+#include "cm2xxx.h"
+#include "prm2xxx.h"
+#include "prm-regbits-24xx.h"
+#include "cm-regbits-24xx.h"
+#include "sdrc.h"
+#include "control.h"
+
+#define OMAP_CM_REGADDR                 OMAP2420_CM_REGADDR
+
+/*
+ * 2420 clock tree.
+ *
+ * NOTE:In many cases here we are assigning a 'default' parent. In
+ *	many cases the parent is selectable. The set parent calls will
+ *	also switch sources.
+ *
+ *	Several sources are given initial rates which may be wrong, this will
+ *	be fixed up in the init func.
+ *
+ *	Things are broadly separated below by clock domains. It is
+ *	noteworthy that most peripherals have dependencies on multiple clock
+ *	domains. Many get their interface clocks from the L4 domain, but get
+ *	functional clocks from fixed sources or other core domain derived
+ *	clocks.
+ */
+
+DEFINE_CLK_FIXED_RATE(alt_ck, CLK_IS_ROOT, 54000000, 0x0);
+
+DEFINE_CLK_FIXED_RATE(func_32k_ck, CLK_IS_ROOT, 32768, 0x0);
+
+DEFINE_CLK_FIXED_RATE(mcbsp_clks, CLK_IS_ROOT, 0x0, 0x0);
+
+static struct clk osc_ck;
+
+static const struct clk_ops osc_ck_ops = {
+	.recalc_rate	= &omap2_osc_clk_recalc,
+};
+
+static struct clk_hw_omap osc_ck_hw = {
+	.hw = {
+		.clk = &osc_ck,
+	},
+};
+
+static struct clk osc_ck = {
+	.name	= "osc_ck",
+	.ops	= &osc_ck_ops,
+	.hw	= &osc_ck_hw.hw,
+	.flags	= CLK_IS_ROOT,
+};
+
+DEFINE_CLK_FIXED_RATE(secure_32k_ck, CLK_IS_ROOT, 32768, 0x0);
+
+static struct clk sys_ck;
+
+static const char *sys_ck_parent_names[] = {
+	"osc_ck",
+};
+
+static const struct clk_ops sys_ck_ops = {
+	.init		= &omap2_init_clk_clkdm,
+	.recalc_rate	= &omap2xxx_sys_clk_recalc,
+};
+
+DEFINE_STRUCT_CLK_HW_OMAP(sys_ck, "wkup_clkdm");
+DEFINE_STRUCT_CLK(sys_ck, sys_ck_parent_names, sys_ck_ops);
+
+static struct dpll_data dpll_dd = {
+	.mult_div1_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1),
+	.mult_mask	= OMAP24XX_DPLL_MULT_MASK,
+	.div1_mask	= OMAP24XX_DPLL_DIV_MASK,
+	.clk_bypass	= &sys_ck,
+	.clk_ref	= &sys_ck,
+	.control_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
+	.enable_mask	= OMAP24XX_EN_DPLL_MASK,
+	.max_multiplier	= 1023,
+	.min_divider	= 1,
+	.max_divider	= 16,
+};
+
+static struct clk dpll_ck;
+
+static const char *dpll_ck_parent_names[] = {
+	"sys_ck",
+};
+
+static const struct clk_ops dpll_ck_ops = {
+	.init		= &omap2_init_clk_clkdm,
+	.get_parent	= &omap2_init_dpll_parent,
+	.recalc_rate	= &omap2_dpllcore_recalc,
+	.round_rate	= &omap2_dpll_round_rate,
+	.set_rate	= &omap2_reprogram_dpllcore,
+};
+
+static struct clk_hw_omap dpll_ck_hw = {
+	.hw = {
+		.clk = &dpll_ck,
+	},
+	.ops		= &clkhwops_omap2xxx_dpll,
+	.dpll_data	= &dpll_dd,
+	.clkdm_name	= "wkup_clkdm",
+};
+
+DEFINE_STRUCT_CLK(dpll_ck, dpll_ck_parent_names, dpll_ck_ops);
+
+static struct clk core_ck;
+
+static const char *core_ck_parent_names[] = {
+	"dpll_ck",
+};
+
+static const struct clk_ops core_ck_ops = {
+	.init		= &omap2_init_clk_clkdm,
+};
+
+DEFINE_STRUCT_CLK_HW_OMAP(core_ck, "wkup_clkdm");
+DEFINE_STRUCT_CLK(core_ck, core_ck_parent_names, core_ck_ops);
+
+DEFINE_CLK_DIVIDER(core_l3_ck, "core_ck", &core_ck, 0x0,
+		   OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1),
+		   OMAP24XX_CLKSEL_L3_SHIFT, OMAP24XX_CLKSEL_L3_WIDTH,
+		   CLK_DIVIDER_ONE_BASED, NULL);
+
+DEFINE_CLK_DIVIDER(l4_ck, "core_l3_ck", &core_l3_ck, 0x0,
+		   OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1),
+		   OMAP24XX_CLKSEL_L4_SHIFT, OMAP24XX_CLKSEL_L4_WIDTH,
+		   CLK_DIVIDER_ONE_BASED, NULL);
+
+static struct clk aes_ick;
+
+static const char *aes_ick_parent_names[] = {
+	"l4_ck",
+};
+
+static const struct clk_ops aes_ick_ops = {
+	.init		= &omap2_init_clk_clkdm,
+	.enable		= &omap2_dflt_clk_enable,
+	.disable	= &omap2_dflt_clk_disable,
+	.is_enabled	= &omap2_dflt_clk_is_enabled,
+};
+
+static struct clk_hw_omap aes_ick_hw = {
+	.hw = {
+		.clk = &aes_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_ICLKEN4),
+	.enable_bit	= OMAP24XX_EN_AES_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(aes_ick, aes_ick_parent_names, aes_ick_ops);
+
+static struct clk apll54_ck;
+
+static const struct clk_ops apll54_ck_ops = {
+	.init		= &omap2_init_clk_clkdm,
+	.enable		= &omap2_clk_apll54_enable,
+	.disable	= &omap2_clk_apll54_disable,
+	.recalc_rate	= &omap2_clk_apll54_recalc,
+};
+
+static struct clk_hw_omap apll54_ck_hw = {
+	.hw = {
+		.clk = &apll54_ck,
+	},
+	.ops		= &clkhwops_apll54,
+	.enable_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
+	.enable_bit	= OMAP24XX_EN_54M_PLL_SHIFT,
+	.flags		= ENABLE_ON_INIT,
+	.clkdm_name	= "wkup_clkdm",
+};
+
+DEFINE_STRUCT_CLK(apll54_ck, dpll_ck_parent_names, apll54_ck_ops);
+
+static struct clk apll96_ck;
+
+static const struct clk_ops apll96_ck_ops = {
+	.init		= &omap2_init_clk_clkdm,
+	.enable		= &omap2_clk_apll96_enable,
+	.disable	= &omap2_clk_apll96_disable,
+	.recalc_rate	= &omap2_clk_apll96_recalc,
+};
+
+static struct clk_hw_omap apll96_ck_hw = {
+	.hw = {
+		.clk = &apll96_ck,
+	},
+	.ops		= &clkhwops_apll96,
+	.enable_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
+	.enable_bit	= OMAP24XX_EN_96M_PLL_SHIFT,
+	.flags		= ENABLE_ON_INIT,
+	.clkdm_name	= "wkup_clkdm",
+};
+
+DEFINE_STRUCT_CLK(apll96_ck, dpll_ck_parent_names, apll96_ck_ops);
+
+static struct clk func_96m_ck;
+
+static const char *func_96m_ck_parent_names[] = {
+	"apll96_ck",
+};
+
+DEFINE_STRUCT_CLK_HW_OMAP(func_96m_ck, "wkup_clkdm");
+DEFINE_STRUCT_CLK(func_96m_ck, func_96m_ck_parent_names, core_ck_ops);
+
+static struct clk cam_fck;
+
+static const char *cam_fck_parent_names[] = {
+	"func_96m_ck",
+};
+
+static struct clk_hw_omap cam_fck_hw = {
+	.hw = {
+		.clk = &cam_fck,
+	},
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP24XX_EN_CAM_SHIFT,
+	.clkdm_name	= "core_l3_clkdm",
+};
+
+DEFINE_STRUCT_CLK(cam_fck, cam_fck_parent_names, aes_ick_ops);
+
+static struct clk cam_ick;
+
+static struct clk_hw_omap cam_ick_hw = {
+	.hw = {
+		.clk = &cam_ick,
+	},
+	.ops		= &clkhwops_iclk,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_CAM_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(cam_ick, aes_ick_parent_names, aes_ick_ops);
+
+static struct clk des_ick;
+
+static struct clk_hw_omap des_ick_hw = {
+	.hw = {
+		.clk = &des_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_ICLKEN4),
+	.enable_bit	= OMAP24XX_EN_DES_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(des_ick, aes_ick_parent_names, aes_ick_ops);
+
+static const struct clksel_rate dsp_fck_core_rates[] = {
+	{ .div = 1, .val = 1, .flags = RATE_IN_24XX },
+	{ .div = 2, .val = 2, .flags = RATE_IN_24XX },
+	{ .div = 3, .val = 3, .flags = RATE_IN_24XX },
+	{ .div = 4, .val = 4, .flags = RATE_IN_24XX },
+	{ .div = 6, .val = 6, .flags = RATE_IN_242X },
+	{ .div = 8, .val = 8, .flags = RATE_IN_242X },
+	{ .div = 12, .val = 12, .flags = RATE_IN_242X },
+	{ .div = 0 }
+};
+
+static const struct clksel dsp_fck_clksel[] = {
+	{ .parent = &core_ck, .rates = dsp_fck_core_rates },
+	{ .parent = NULL },
+};
+
+static const char *dsp_fck_parent_names[] = {
+	"core_ck",
+};
+
+static const struct clk_ops dsp_fck_ops = {
+	.init		= &omap2_init_clk_clkdm,
+	.enable		= &omap2_dflt_clk_enable,
+	.disable	= &omap2_dflt_clk_disable,
+	.is_enabled	= &omap2_dflt_clk_is_enabled,
+	.recalc_rate	= &omap2_clksel_recalc,
+	.set_rate	= &omap2_clksel_set_rate,
+	.round_rate	= &omap2_clksel_round_rate,
+};
+
+DEFINE_CLK_OMAP_MUX_GATE(dsp_fck, "dsp_clkdm", dsp_fck_clksel,
+			 OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_CLKSEL),
+			 OMAP24XX_CLKSEL_DSP_MASK,
+			 OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_FCLKEN),
+			 OMAP24XX_CM_FCLKEN_DSP_EN_DSP_SHIFT, &clkhwops_wait,
+			 dsp_fck_parent_names, dsp_fck_ops);
+
+static const struct clksel dsp_ick_clksel[] = {
+	{ .parent = &dsp_fck, .rates = dsp_ick_rates },
+	{ .parent = NULL },
+};
+
+static const char *dsp_ick_parent_names[] = {
+	"dsp_fck",
+};
+
+DEFINE_CLK_OMAP_MUX_GATE(dsp_ick, "dsp_clkdm", dsp_ick_clksel,
+			 OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_CLKSEL),
+			 OMAP24XX_CLKSEL_DSP_IF_MASK,
+			 OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_ICLKEN),
+			 OMAP2420_EN_DSP_IPI_SHIFT, &clkhwops_iclk_wait,
+			 dsp_ick_parent_names, dsp_fck_ops);
+
+static const struct clksel_rate dss1_fck_sys_rates[] = {
+	{ .div = 1, .val = 0, .flags = RATE_IN_24XX },
+	{ .div = 0 }
+};
+
+static const struct clksel_rate dss1_fck_core_rates[] = {
+	{ .div = 1, .val = 1, .flags = RATE_IN_24XX },
+	{ .div = 2, .val = 2, .flags = RATE_IN_24XX },
+	{ .div = 3, .val = 3, .flags = RATE_IN_24XX },
+	{ .div = 4, .val = 4, .flags = RATE_IN_24XX },
+	{ .div = 5, .val = 5, .flags = RATE_IN_24XX },
+	{ .div = 6, .val = 6, .flags = RATE_IN_24XX },
+	{ .div = 8, .val = 8, .flags = RATE_IN_24XX },
+	{ .div = 9, .val = 9, .flags = RATE_IN_24XX },
+	{ .div = 12, .val = 12, .flags = RATE_IN_24XX },
+	{ .div = 16, .val = 16, .flags = RATE_IN_24XX },
+	{ .div = 0 }
+};
+
+static const struct clksel dss1_fck_clksel[] = {
+	{ .parent = &sys_ck, .rates = dss1_fck_sys_rates },
+	{ .parent = &core_ck, .rates = dss1_fck_core_rates },
+	{ .parent = NULL },
+};
+
+static const char *dss1_fck_parent_names[] = {
+	"sys_ck", "core_ck",
+};
+
+static struct clk dss1_fck;
+
+static const struct clk_ops dss1_fck_ops = {
+	.init		= &omap2_init_clk_clkdm,
+	.enable		= &omap2_dflt_clk_enable,
+	.disable	= &omap2_dflt_clk_disable,
+	.is_enabled	= &omap2_dflt_clk_is_enabled,
+	.recalc_rate	= &omap2_clksel_recalc,
+	.get_parent	= &omap2_clksel_find_parent_index,
+	.set_parent	= &omap2_clksel_set_parent,
+};
+
+DEFINE_CLK_OMAP_MUX_GATE(dss1_fck, "dss_clkdm", dss1_fck_clksel,
+			 OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1),
+			 OMAP24XX_CLKSEL_DSS1_MASK,
+			 OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+			 OMAP24XX_EN_DSS1_SHIFT, NULL,
+			 dss1_fck_parent_names, dss1_fck_ops);
+
+static const struct clksel_rate dss2_fck_sys_rates[] = {
+	{ .div = 1, .val = 0, .flags = RATE_IN_24XX },
+	{ .div = 0 }
+};
+
+static const struct clksel_rate dss2_fck_48m_rates[] = {
+	{ .div = 1, .val = 1, .flags = RATE_IN_24XX },
+	{ .div = 0 }
+};
+
+static const struct clksel_rate func_48m_apll96_rates[] = {
+	{ .div = 2, .val = 0, .flags = RATE_IN_24XX },
+	{ .div = 0 }
+};
+
+static const struct clksel_rate func_48m_alt_rates[] = {
+	{ .div = 1, .val = 1, .flags = RATE_IN_24XX },
+	{ .div = 0 }
+};
+
+static const struct clksel func_48m_clksel[] = {
+	{ .parent = &apll96_ck, .rates = func_48m_apll96_rates },
+	{ .parent = &alt_ck, .rates = func_48m_alt_rates },
+	{ .parent = NULL },
+};
+
+static const char *func_48m_ck_parent_names[] = {
+	"apll96_ck", "alt_ck",
+};
+
+static struct clk func_48m_ck;
+
+static const struct clk_ops func_48m_ck_ops = {
+	.init		= &omap2_init_clk_clkdm,
+	.recalc_rate	= &omap2_clksel_recalc,
+	.set_rate	= &omap2_clksel_set_rate,
+	.round_rate	= &omap2_clksel_round_rate,
+	.get_parent	= &omap2_clksel_find_parent_index,
+	.set_parent	= &omap2_clksel_set_parent,
+};
+
+static struct clk_hw_omap func_48m_ck_hw = {
+	.hw = {
+		.clk = &func_48m_ck,
+	},
+	.clksel		= func_48m_clksel,
+	.clksel_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1),
+	.clksel_mask	= OMAP24XX_48M_SOURCE_MASK,
+	.clkdm_name	= "wkup_clkdm",
+};
+
+DEFINE_STRUCT_CLK(func_48m_ck, func_48m_ck_parent_names, func_48m_ck_ops);
+
+static const struct clksel dss2_fck_clksel[] = {
+	{ .parent = &sys_ck, .rates = dss2_fck_sys_rates },
+	{ .parent = &func_48m_ck, .rates = dss2_fck_48m_rates },
+	{ .parent = NULL },
+};
+
+static const char *dss2_fck_parent_names[] = {
+	"sys_ck", "func_48m_ck",
+};
+
+DEFINE_CLK_OMAP_MUX_GATE(dss2_fck, "dss_clkdm", dss2_fck_clksel,
+			 OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1),
+			 OMAP24XX_CLKSEL_DSS2_MASK,
+			 OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+			 OMAP24XX_EN_DSS2_SHIFT, NULL,
+			 dss2_fck_parent_names, dss1_fck_ops);
+
+static const char *func_54m_ck_parent_names[] = {
+	"apll54_ck", "alt_ck",
+};
+
+DEFINE_CLK_MUX(func_54m_ck, func_54m_ck_parent_names, NULL, 0x0,
+	       OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1),
+	       OMAP24XX_54M_SOURCE_SHIFT, OMAP24XX_54M_SOURCE_WIDTH,
+	       0x0, NULL);
+
+static struct clk dss_54m_fck;
+
+static const char *dss_54m_fck_parent_names[] = {
+	"func_54m_ck",
+};
+
+static struct clk_hw_omap dss_54m_fck_hw = {
+	.hw = {
+		.clk = &dss_54m_fck,
+	},
+	.ops		= &clkhwops_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP24XX_EN_TV_SHIFT,
+	.clkdm_name	= "dss_clkdm",
+};
+
+DEFINE_STRUCT_CLK(dss_54m_fck, dss_54m_fck_parent_names, aes_ick_ops);
+
+static struct clk dss_ick;
+
+static struct clk_hw_omap dss_ick_hw = {
+	.hw = {
+		.clk = &dss_ick,
+	},
+	.ops		= &clkhwops_iclk,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_DSS1_SHIFT,
+	.clkdm_name	= "dss_clkdm",
+};
+
+DEFINE_STRUCT_CLK(dss_ick, aes_ick_parent_names, aes_ick_ops);
+
+static struct clk eac_fck;
+
+static struct clk_hw_omap eac_fck_hw = {
+	.hw = {
+		.clk = &eac_fck,
+	},
+	.ops		= &clkhwops_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP2420_EN_EAC_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(eac_fck, cam_fck_parent_names, aes_ick_ops);
+
+static struct clk eac_ick;
+
+static struct clk_hw_omap eac_ick_hw = {
+	.hw = {
+		.clk = &eac_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP2420_EN_EAC_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(eac_ick, aes_ick_parent_names, aes_ick_ops);
+
+static struct clk emul_ck;
+
+static struct clk_hw_omap emul_ck_hw = {
+	.hw = {
+		.clk = &emul_ck,
+	},
+	.enable_reg	= OMAP2420_PRCM_CLKEMUL_CTRL,
+	.enable_bit	= OMAP24XX_EMULATION_EN_SHIFT,
+	.clkdm_name	= "wkup_clkdm",
+};
+
+DEFINE_STRUCT_CLK(emul_ck, dss_54m_fck_parent_names, aes_ick_ops);
+
+DEFINE_CLK_FIXED_FACTOR(func_12m_ck, "func_48m_ck", &func_48m_ck, 0x0, 1, 4);
+
+static struct clk fac_fck;
+
+static const char *fac_fck_parent_names[] = {
+	"func_12m_ck",
+};
+
+static struct clk_hw_omap fac_fck_hw = {
+	.hw = {
+		.clk = &fac_fck,
+	},
+	.ops		= &clkhwops_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP24XX_EN_FAC_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(fac_fck, fac_fck_parent_names, aes_ick_ops);
+
+static struct clk fac_ick;
+
+static struct clk_hw_omap fac_ick_hw = {
+	.hw = {
+		.clk = &fac_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_FAC_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(fac_ick, aes_ick_parent_names, aes_ick_ops);
+
+static const struct clksel gfx_fck_clksel[] = {
+	{ .parent = &core_l3_ck, .rates = gfx_l3_rates },
+	{ .parent = NULL },
+};
+
+static const char *gfx_2d_fck_parent_names[] = {
+	"core_l3_ck",
+};
+
+DEFINE_CLK_OMAP_MUX_GATE(gfx_2d_fck, "gfx_clkdm", gfx_fck_clksel,
+			 OMAP_CM_REGADDR(GFX_MOD, CM_CLKSEL),
+			 OMAP_CLKSEL_GFX_MASK,
+			 OMAP_CM_REGADDR(GFX_MOD, CM_FCLKEN),
+			 OMAP24XX_EN_2D_SHIFT, &clkhwops_wait,
+			 gfx_2d_fck_parent_names, dsp_fck_ops);
+
+DEFINE_CLK_OMAP_MUX_GATE(gfx_3d_fck, "gfx_clkdm", gfx_fck_clksel,
+			 OMAP_CM_REGADDR(GFX_MOD, CM_CLKSEL),
+			 OMAP_CLKSEL_GFX_MASK,
+			 OMAP_CM_REGADDR(GFX_MOD, CM_FCLKEN),
+			 OMAP24XX_EN_3D_SHIFT, &clkhwops_wait,
+			 gfx_2d_fck_parent_names, dsp_fck_ops);
+
+static struct clk gfx_ick;
+
+static const char *gfx_ick_parent_names[] = {
+	"core_l3_ck",
+};
+
+static struct clk_hw_omap gfx_ick_hw = {
+	.hw = {
+		.clk = &gfx_ick,
+	},
+	.ops		= &clkhwops_wait,
+	.enable_reg	= OMAP_CM_REGADDR(GFX_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP_EN_GFX_SHIFT,
+	.clkdm_name	= "gfx_clkdm",
+};
+
+DEFINE_STRUCT_CLK(gfx_ick, gfx_ick_parent_names, aes_ick_ops);
+
+static struct clk gpios_fck;
+
+static const char *gpios_fck_parent_names[] = {
+	"func_32k_ck",
+};
+
+static struct clk_hw_omap gpios_fck_hw = {
+	.hw = {
+		.clk = &gpios_fck,
+	},
+	.ops		= &clkhwops_wait,
+	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP24XX_EN_GPIOS_SHIFT,
+	.clkdm_name	= "wkup_clkdm",
+};
+
+DEFINE_STRUCT_CLK(gpios_fck, gpios_fck_parent_names, aes_ick_ops);
+
+static struct clk wu_l4_ick;
+
+DEFINE_STRUCT_CLK_HW_OMAP(wu_l4_ick, "wkup_clkdm");
+DEFINE_STRUCT_CLK(wu_l4_ick, dpll_ck_parent_names, core_ck_ops);
+
+static struct clk gpios_ick;
+
+static const char *gpios_ick_parent_names[] = {
+	"wu_l4_ick",
+};
+
+static struct clk_hw_omap gpios_ick_hw = {
+	.hw = {
+		.clk = &gpios_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP24XX_EN_GPIOS_SHIFT,
+	.clkdm_name	= "wkup_clkdm",
+};
+
+DEFINE_STRUCT_CLK(gpios_ick, gpios_ick_parent_names, aes_ick_ops);
+
+static struct clk gpmc_fck;
+
+static struct clk_hw_omap gpmc_fck_hw = {
+	.hw = {
+		.clk = &gpmc_fck,
+	},
+	.ops		= &clkhwops_iclk,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN3),
+	.enable_bit	= OMAP24XX_AUTO_GPMC_SHIFT,
+	.flags		= ENABLE_ON_INIT,
+	.clkdm_name	= "core_l3_clkdm",
+};
+
+DEFINE_STRUCT_CLK(gpmc_fck, gfx_ick_parent_names, core_ck_ops);
+
+static const struct clksel_rate gpt_alt_rates[] = {
+	{ .div = 1, .val = 2, .flags = RATE_IN_24XX },
+	{ .div = 0 }
+};
+
+static const struct clksel omap24xx_gpt_clksel[] = {
+	{ .parent = &func_32k_ck, .rates = gpt_32k_rates },
+	{ .parent = &sys_ck, .rates = gpt_sys_rates },
+	{ .parent = &alt_ck, .rates = gpt_alt_rates },
+	{ .parent = NULL },
+};
+
+static const char *gpt10_fck_parent_names[] = {
+	"func_32k_ck", "sys_ck", "alt_ck",
+};
+
+DEFINE_CLK_OMAP_MUX_GATE(gpt10_fck, "core_l4_clkdm", omap24xx_gpt_clksel,
+			 OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
+			 OMAP24XX_CLKSEL_GPT10_MASK,
+			 OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+			 OMAP24XX_EN_GPT10_SHIFT, &clkhwops_wait,
+			 gpt10_fck_parent_names, dss1_fck_ops);
+
+static struct clk gpt10_ick;
+
+static struct clk_hw_omap gpt10_ick_hw = {
+	.hw = {
+		.clk = &gpt10_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_GPT10_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(gpt10_ick, aes_ick_parent_names, aes_ick_ops);
+
+DEFINE_CLK_OMAP_MUX_GATE(gpt11_fck, "core_l4_clkdm", omap24xx_gpt_clksel,
+			 OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
+			 OMAP24XX_CLKSEL_GPT11_MASK,
+			 OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+			 OMAP24XX_EN_GPT11_SHIFT, &clkhwops_wait,
+			 gpt10_fck_parent_names, dss1_fck_ops);
+
+static struct clk gpt11_ick;
+
+static struct clk_hw_omap gpt11_ick_hw = {
+	.hw = {
+		.clk = &gpt11_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_GPT11_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(gpt11_ick, aes_ick_parent_names, aes_ick_ops);
+
+DEFINE_CLK_OMAP_MUX_GATE(gpt12_fck, "core_l4_clkdm", omap24xx_gpt_clksel,
+			 OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
+			 OMAP24XX_CLKSEL_GPT12_MASK,
+			 OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+			 OMAP24XX_EN_GPT12_SHIFT, &clkhwops_wait,
+			 gpt10_fck_parent_names, dss1_fck_ops);
+
+static struct clk gpt12_ick;
+
+static struct clk_hw_omap gpt12_ick_hw = {
+	.hw = {
+		.clk = &gpt12_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_GPT12_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(gpt12_ick, aes_ick_parent_names, aes_ick_ops);
+
+static const struct clk_ops gpt1_fck_ops = {
+	.init		= &omap2_init_clk_clkdm,
+	.enable		= &omap2_dflt_clk_enable,
+	.disable	= &omap2_dflt_clk_disable,
+	.is_enabled	= &omap2_dflt_clk_is_enabled,
+	.recalc_rate	= &omap2_clksel_recalc,
+	.set_rate	= &omap2_clksel_set_rate,
+	.round_rate	= &omap2_clksel_round_rate,
+	.get_parent	= &omap2_clksel_find_parent_index,
+	.set_parent	= &omap2_clksel_set_parent,
+};
+
+DEFINE_CLK_OMAP_MUX_GATE(gpt1_fck, "core_l4_clkdm", omap24xx_gpt_clksel,
+			 OMAP_CM_REGADDR(WKUP_MOD, CM_CLKSEL1),
+			 OMAP24XX_CLKSEL_GPT1_MASK,
+			 OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN),
+			 OMAP24XX_EN_GPT1_SHIFT, &clkhwops_wait,
+			 gpt10_fck_parent_names, gpt1_fck_ops);
+
+static struct clk gpt1_ick;
+
+static struct clk_hw_omap gpt1_ick_hw = {
+	.hw = {
+		.clk = &gpt1_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP24XX_EN_GPT1_SHIFT,
+	.clkdm_name	= "wkup_clkdm",
+};
+
+DEFINE_STRUCT_CLK(gpt1_ick, gpios_ick_parent_names, aes_ick_ops);
+
+DEFINE_CLK_OMAP_MUX_GATE(gpt2_fck, "core_l4_clkdm", omap24xx_gpt_clksel,
+			 OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
+			 OMAP24XX_CLKSEL_GPT2_MASK,
+			 OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+			 OMAP24XX_EN_GPT2_SHIFT, &clkhwops_wait,
+			 gpt10_fck_parent_names, dss1_fck_ops);
+
+static struct clk gpt2_ick;
+
+static struct clk_hw_omap gpt2_ick_hw = {
+	.hw = {
+		.clk = &gpt2_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_GPT2_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(gpt2_ick, aes_ick_parent_names, aes_ick_ops);
+
+DEFINE_CLK_OMAP_MUX_GATE(gpt3_fck, "core_l4_clkdm", omap24xx_gpt_clksel,
+			 OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
+			 OMAP24XX_CLKSEL_GPT3_MASK,
+			 OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+			 OMAP24XX_EN_GPT3_SHIFT, &clkhwops_wait,
+			 gpt10_fck_parent_names, dss1_fck_ops);
+
+static struct clk gpt3_ick;
+
+static struct clk_hw_omap gpt3_ick_hw = {
+	.hw = {
+		.clk = &gpt3_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_GPT3_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(gpt3_ick, aes_ick_parent_names, aes_ick_ops);
+
+DEFINE_CLK_OMAP_MUX_GATE(gpt4_fck, "core_l4_clkdm", omap24xx_gpt_clksel,
+			 OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
+			 OMAP24XX_CLKSEL_GPT4_MASK,
+			 OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+			 OMAP24XX_EN_GPT4_SHIFT, &clkhwops_wait,
+			 gpt10_fck_parent_names, dss1_fck_ops);
+
+static struct clk gpt4_ick;
+
+static struct clk_hw_omap gpt4_ick_hw = {
+	.hw = {
+		.clk = &gpt4_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_GPT4_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(gpt4_ick, aes_ick_parent_names, aes_ick_ops);
+
+DEFINE_CLK_OMAP_MUX_GATE(gpt5_fck, "core_l4_clkdm", omap24xx_gpt_clksel,
+			 OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
+			 OMAP24XX_CLKSEL_GPT5_MASK,
+			 OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+			 OMAP24XX_EN_GPT5_SHIFT, &clkhwops_wait,
+			 gpt10_fck_parent_names, dss1_fck_ops);
+
+static struct clk gpt5_ick;
+
+static struct clk_hw_omap gpt5_ick_hw = {
+	.hw = {
+		.clk = &gpt5_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_GPT5_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(gpt5_ick, aes_ick_parent_names, aes_ick_ops);
+
+DEFINE_CLK_OMAP_MUX_GATE(gpt6_fck, "core_l4_clkdm", omap24xx_gpt_clksel,
+			 OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
+			 OMAP24XX_CLKSEL_GPT6_MASK,
+			 OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+			 OMAP24XX_EN_GPT6_SHIFT, &clkhwops_wait,
+			 gpt10_fck_parent_names, dss1_fck_ops);
+
+static struct clk gpt6_ick;
+
+static struct clk_hw_omap gpt6_ick_hw = {
+	.hw = {
+		.clk = &gpt6_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_GPT6_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(gpt6_ick, aes_ick_parent_names, aes_ick_ops);
+
+DEFINE_CLK_OMAP_MUX_GATE(gpt7_fck, "core_l4_clkdm", omap24xx_gpt_clksel,
+			 OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
+			 OMAP24XX_CLKSEL_GPT7_MASK,
+			 OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+			 OMAP24XX_EN_GPT7_SHIFT, &clkhwops_wait,
+			 gpt10_fck_parent_names, dss1_fck_ops);
+
+static struct clk gpt7_ick;
+
+static struct clk_hw_omap gpt7_ick_hw = {
+	.hw = {
+		.clk = &gpt7_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_GPT7_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(gpt7_ick, aes_ick_parent_names, aes_ick_ops);
+
+DEFINE_CLK_OMAP_MUX_GATE(gpt8_fck, "core_l4_clkdm", omap24xx_gpt_clksel,
+			 OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
+			 OMAP24XX_CLKSEL_GPT8_MASK,
+			 OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+			 OMAP24XX_EN_GPT8_SHIFT, &clkhwops_wait,
+			 gpt10_fck_parent_names, dss1_fck_ops);
+
+static struct clk gpt8_ick;
+
+static struct clk_hw_omap gpt8_ick_hw = {
+	.hw = {
+		.clk = &gpt8_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_GPT8_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(gpt8_ick, aes_ick_parent_names, aes_ick_ops);
+
+DEFINE_CLK_OMAP_MUX_GATE(gpt9_fck, "core_l4_clkdm", omap24xx_gpt_clksel,
+			 OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
+			 OMAP24XX_CLKSEL_GPT9_MASK,
+			 OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+			 OMAP24XX_EN_GPT9_SHIFT, &clkhwops_wait,
+			 gpt10_fck_parent_names, dss1_fck_ops);
+
+static struct clk gpt9_ick;
+
+static struct clk_hw_omap gpt9_ick_hw = {
+	.hw = {
+		.clk = &gpt9_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_GPT9_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(gpt9_ick, aes_ick_parent_names, aes_ick_ops);
+
+static struct clk hdq_fck;
+
+static struct clk_hw_omap hdq_fck_hw = {
+	.hw = {
+		.clk = &hdq_fck,
+	},
+	.ops		= &clkhwops_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP24XX_EN_HDQ_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(hdq_fck, fac_fck_parent_names, aes_ick_ops);
+
+static struct clk hdq_ick;
+
+static struct clk_hw_omap hdq_ick_hw = {
+	.hw = {
+		.clk = &hdq_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_HDQ_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(hdq_ick, aes_ick_parent_names, aes_ick_ops);
+
+static struct clk i2c1_fck;
+
+static struct clk_hw_omap i2c1_fck_hw = {
+	.hw = {
+		.clk = &i2c1_fck,
+	},
+	.ops		= &clkhwops_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP2420_EN_I2C1_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(i2c1_fck, fac_fck_parent_names, aes_ick_ops);
+
+static struct clk i2c1_ick;
+
+static struct clk_hw_omap i2c1_ick_hw = {
+	.hw = {
+		.clk = &i2c1_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP2420_EN_I2C1_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(i2c1_ick, aes_ick_parent_names, aes_ick_ops);
+
+static struct clk i2c2_fck;
+
+static struct clk_hw_omap i2c2_fck_hw = {
+	.hw = {
+		.clk = &i2c2_fck,
+	},
+	.ops		= &clkhwops_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP2420_EN_I2C2_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(i2c2_fck, fac_fck_parent_names, aes_ick_ops);
+
+static struct clk i2c2_ick;
+
+static struct clk_hw_omap i2c2_ick_hw = {
+	.hw = {
+		.clk = &i2c2_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP2420_EN_I2C2_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(i2c2_ick, aes_ick_parent_names, aes_ick_ops);
+
+DEFINE_CLK_OMAP_MUX_GATE(iva1_ifck, "iva1_clkdm", dsp_fck_clksel,
+			 OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_CLKSEL),
+			 OMAP2420_CLKSEL_IVA_MASK,
+			 OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_FCLKEN),
+			 OMAP2420_EN_IVA_COP_SHIFT, &clkhwops_wait,
+			 dsp_fck_parent_names, dsp_fck_ops);
+
+static struct clk iva1_mpu_int_ifck;
+
+static const char *iva1_mpu_int_ifck_parent_names[] = {
+	"iva1_ifck",
+};
+
+static const struct clk_ops iva1_mpu_int_ifck_ops = {
+	.init		= &omap2_init_clk_clkdm,
+	.enable		= &omap2_dflt_clk_enable,
+	.disable	= &omap2_dflt_clk_disable,
+	.is_enabled	= &omap2_dflt_clk_is_enabled,
+	.recalc_rate	= &omap_fixed_divisor_recalc,
+};
+
+static struct clk_hw_omap iva1_mpu_int_ifck_hw = {
+	.hw = {
+		.clk = &iva1_mpu_int_ifck,
+	},
+	.ops		= &clkhwops_wait,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP2420_EN_IVA_MPU_SHIFT,
+	.clkdm_name	= "iva1_clkdm",
+	.fixed_div	= 2,
+};
+
+DEFINE_STRUCT_CLK(iva1_mpu_int_ifck, iva1_mpu_int_ifck_parent_names,
+		  iva1_mpu_int_ifck_ops);
+
+static struct clk mailboxes_ick;
+
+static struct clk_hw_omap mailboxes_ick_hw = {
+	.hw = {
+		.clk = &mailboxes_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_MAILBOXES_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(mailboxes_ick, aes_ick_parent_names, aes_ick_ops);
+
+static const struct clksel_rate common_mcbsp_96m_rates[] = {
+	{ .div = 1, .val = 0, .flags = RATE_IN_24XX },
+	{ .div = 0 }
+};
+
+static const struct clksel_rate common_mcbsp_mcbsp_rates[] = {
+	{ .div = 1, .val = 1, .flags = RATE_IN_24XX },
+	{ .div = 0 }
+};
+
+static const struct clksel mcbsp_fck_clksel[] = {
+	{ .parent = &func_96m_ck, .rates = common_mcbsp_96m_rates },
+	{ .parent = &mcbsp_clks, .rates = common_mcbsp_mcbsp_rates },
+	{ .parent = NULL },
+};
+
+static const char *mcbsp1_fck_parent_names[] = {
+	"func_96m_ck", "mcbsp_clks",
+};
+
+DEFINE_CLK_OMAP_MUX_GATE(mcbsp1_fck, "core_l4_clkdm", mcbsp_fck_clksel,
+			 OMAP242X_CTRL_REGADDR(OMAP2_CONTROL_DEVCONF0),
+			 OMAP2_MCBSP1_CLKS_MASK,
+			 OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+			 OMAP24XX_EN_MCBSP1_SHIFT, &clkhwops_wait,
+			 mcbsp1_fck_parent_names, dss1_fck_ops);
+
+static struct clk mcbsp1_ick;
+
+static struct clk_hw_omap mcbsp1_ick_hw = {
+	.hw = {
+		.clk = &mcbsp1_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_MCBSP1_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(mcbsp1_ick, aes_ick_parent_names, aes_ick_ops);
+
+DEFINE_CLK_OMAP_MUX_GATE(mcbsp2_fck, "core_l4_clkdm", mcbsp_fck_clksel,
+			 OMAP242X_CTRL_REGADDR(OMAP2_CONTROL_DEVCONF0),
+			 OMAP2_MCBSP2_CLKS_MASK,
+			 OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+			 OMAP24XX_EN_MCBSP2_SHIFT, &clkhwops_wait,
+			 mcbsp1_fck_parent_names, dss1_fck_ops);
+
+static struct clk mcbsp2_ick;
+
+static struct clk_hw_omap mcbsp2_ick_hw = {
+	.hw = {
+		.clk = &mcbsp2_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_MCBSP2_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(mcbsp2_ick, aes_ick_parent_names, aes_ick_ops);
+
+static struct clk mcspi1_fck;
+
+static const char *mcspi1_fck_parent_names[] = {
+	"func_48m_ck",
+};
+
+static struct clk_hw_omap mcspi1_fck_hw = {
+	.hw = {
+		.clk = &mcspi1_fck,
+	},
+	.ops		= &clkhwops_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP24XX_EN_MCSPI1_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(mcspi1_fck, mcspi1_fck_parent_names, aes_ick_ops);
+
+static struct clk mcspi1_ick;
+
+static struct clk_hw_omap mcspi1_ick_hw = {
+	.hw = {
+		.clk = &mcspi1_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_MCSPI1_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(mcspi1_ick, aes_ick_parent_names, aes_ick_ops);
+
+static struct clk mcspi2_fck;
+
+static struct clk_hw_omap mcspi2_fck_hw = {
+	.hw = {
+		.clk = &mcspi2_fck,
+	},
+	.ops		= &clkhwops_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP24XX_EN_MCSPI2_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(mcspi2_fck, mcspi1_fck_parent_names, aes_ick_ops);
+
+static struct clk mcspi2_ick;
+
+static struct clk_hw_omap mcspi2_ick_hw = {
+	.hw = {
+		.clk = &mcspi2_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_MCSPI2_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(mcspi2_ick, aes_ick_parent_names, aes_ick_ops);
+
+static struct clk mmc_fck;
+
+static struct clk_hw_omap mmc_fck_hw = {
+	.hw = {
+		.clk = &mmc_fck,
+	},
+	.ops		= &clkhwops_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP2420_EN_MMC_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(mmc_fck, cam_fck_parent_names, aes_ick_ops);
+
+static struct clk mmc_ick;
+
+static struct clk_hw_omap mmc_ick_hw = {
+	.hw = {
+		.clk = &mmc_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP2420_EN_MMC_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(mmc_ick, aes_ick_parent_names, aes_ick_ops);
+
+DEFINE_CLK_DIVIDER(mpu_ck, "core_ck", &core_ck, 0x0,
+		   OMAP_CM_REGADDR(MPU_MOD, CM_CLKSEL),
+		   OMAP24XX_CLKSEL_MPU_SHIFT, OMAP24XX_CLKSEL_MPU_WIDTH,
+		   CLK_DIVIDER_ONE_BASED, NULL);
+
+static struct clk mpu_wdt_fck;
+
+static struct clk_hw_omap mpu_wdt_fck_hw = {
+	.hw = {
+		.clk = &mpu_wdt_fck,
+	},
+	.ops		= &clkhwops_wait,
+	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP24XX_EN_MPU_WDT_SHIFT,
+	.clkdm_name	= "wkup_clkdm",
+};
+
+DEFINE_STRUCT_CLK(mpu_wdt_fck, gpios_fck_parent_names, aes_ick_ops);
+
+static struct clk mpu_wdt_ick;
+
+static struct clk_hw_omap mpu_wdt_ick_hw = {
+	.hw = {
+		.clk = &mpu_wdt_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP24XX_EN_MPU_WDT_SHIFT,
+	.clkdm_name	= "wkup_clkdm",
+};
+
+DEFINE_STRUCT_CLK(mpu_wdt_ick, gpios_ick_parent_names, aes_ick_ops);
+
+static struct clk mspro_fck;
+
+static struct clk_hw_omap mspro_fck_hw = {
+	.hw = {
+		.clk = &mspro_fck,
+	},
+	.ops		= &clkhwops_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP24XX_EN_MSPRO_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(mspro_fck, cam_fck_parent_names, aes_ick_ops);
+
+static struct clk mspro_ick;
+
+static struct clk_hw_omap mspro_ick_hw = {
+	.hw = {
+		.clk = &mspro_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_MSPRO_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(mspro_ick, aes_ick_parent_names, aes_ick_ops);
+
+static struct clk omapctrl_ick;
+
+static struct clk_hw_omap omapctrl_ick_hw = {
+	.hw = {
+		.clk = &omapctrl_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP24XX_EN_OMAPCTRL_SHIFT,
+	.flags		= ENABLE_ON_INIT,
+	.clkdm_name	= "wkup_clkdm",
+};
+
+DEFINE_STRUCT_CLK(omapctrl_ick, gpios_ick_parent_names, aes_ick_ops);
+
+static struct clk pka_ick;
+
+static struct clk_hw_omap pka_ick_hw = {
+	.hw = {
+		.clk = &pka_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_ICLKEN4),
+	.enable_bit	= OMAP24XX_EN_PKA_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(pka_ick, aes_ick_parent_names, aes_ick_ops);
+
+static struct clk rng_ick;
+
+static struct clk_hw_omap rng_ick_hw = {
+	.hw = {
+		.clk = &rng_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_ICLKEN4),
+	.enable_bit	= OMAP24XX_EN_RNG_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(rng_ick, aes_ick_parent_names, aes_ick_ops);
+
+static struct clk sdma_fck;
+
+DEFINE_STRUCT_CLK_HW_OMAP(sdma_fck, "core_l3_clkdm");
+DEFINE_STRUCT_CLK(sdma_fck, gfx_ick_parent_names, core_ck_ops);
+
+static struct clk sdma_ick;
+
+static struct clk_hw_omap sdma_ick_hw = {
+	.hw = {
+		.clk = &sdma_ick,
+	},
+	.ops		= &clkhwops_iclk,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN3),
+	.enable_bit	= OMAP24XX_AUTO_SDMA_SHIFT,
+	.clkdm_name	= "core_l3_clkdm",
+};
+
+DEFINE_STRUCT_CLK(sdma_ick, gfx_ick_parent_names, core_ck_ops);
+
+static struct clk sdrc_ick;
+
+static struct clk_hw_omap sdrc_ick_hw = {
+	.hw = {
+		.clk = &sdrc_ick,
+	},
+	.ops		= &clkhwops_iclk,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN3),
+	.enable_bit	= OMAP24XX_AUTO_SDRC_SHIFT,
+	.flags		= ENABLE_ON_INIT,
+	.clkdm_name	= "core_l3_clkdm",
+};
+
+DEFINE_STRUCT_CLK(sdrc_ick, gfx_ick_parent_names, core_ck_ops);
+
+static struct clk sha_ick;
+
+static struct clk_hw_omap sha_ick_hw = {
+	.hw = {
+		.clk = &sha_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_ICLKEN4),
+	.enable_bit	= OMAP24XX_EN_SHA_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(sha_ick, aes_ick_parent_names, aes_ick_ops);
+
+static struct clk ssi_l4_ick;
+
+static struct clk_hw_omap ssi_l4_ick_hw = {
+	.hw = {
+		.clk = &ssi_l4_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
+	.enable_bit	= OMAP24XX_EN_SSI_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(ssi_l4_ick, aes_ick_parent_names, aes_ick_ops);
+
+static const struct clksel_rate ssi_ssr_sst_fck_core_rates[] = {
+	{ .div = 1, .val = 1, .flags = RATE_IN_24XX },
+	{ .div = 2, .val = 2, .flags = RATE_IN_24XX },
+	{ .div = 3, .val = 3, .flags = RATE_IN_24XX },
+	{ .div = 4, .val = 4, .flags = RATE_IN_24XX },
+	{ .div = 6, .val = 6, .flags = RATE_IN_242X },
+	{ .div = 8, .val = 8, .flags = RATE_IN_242X },
+	{ .div = 0 }
+};
+
+static const struct clksel ssi_ssr_sst_fck_clksel[] = {
+	{ .parent = &core_ck, .rates = ssi_ssr_sst_fck_core_rates },
+	{ .parent = NULL },
+};
+
+static const char *ssi_ssr_sst_fck_parent_names[] = {
+	"core_ck",
+};
+
+DEFINE_CLK_OMAP_MUX_GATE(ssi_ssr_sst_fck, "core_l3_clkdm",
+			 ssi_ssr_sst_fck_clksel,
+			 OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1),
+			 OMAP24XX_CLKSEL_SSI_MASK,
+			 OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
+			 OMAP24XX_EN_SSI_SHIFT, &clkhwops_wait,
+			 ssi_ssr_sst_fck_parent_names, dsp_fck_ops);
+
+static struct clk sync_32k_ick;
+
+static struct clk_hw_omap sync_32k_ick_hw = {
+	.hw = {
+		.clk = &sync_32k_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP24XX_EN_32KSYNC_SHIFT,
+	.flags		= ENABLE_ON_INIT,
+	.clkdm_name	= "wkup_clkdm",
+};
+
+DEFINE_STRUCT_CLK(sync_32k_ick, gpios_ick_parent_names, aes_ick_ops);
+
+static const struct clksel_rate common_clkout_src_core_rates[] = {
+	{ .div = 1, .val = 0, .flags = RATE_IN_24XX },
+	{ .div = 0 }
+};
+
+static const struct clksel_rate common_clkout_src_sys_rates[] = {
+	{ .div = 1, .val = 1, .flags = RATE_IN_24XX },
+	{ .div = 0 }
+};
+
+static const struct clksel_rate common_clkout_src_96m_rates[] = {
+	{ .div = 1, .val = 2, .flags = RATE_IN_24XX },
+	{ .div = 0 }
+};
+
+static const struct clksel_rate common_clkout_src_54m_rates[] = {
+	{ .div = 1, .val = 3, .flags = RATE_IN_24XX },
+	{ .div = 0 }
+};
+
+static const struct clksel common_clkout_src_clksel[] = {
+	{ .parent = &core_ck, .rates = common_clkout_src_core_rates },
+	{ .parent = &sys_ck, .rates = common_clkout_src_sys_rates },
+	{ .parent = &func_96m_ck, .rates = common_clkout_src_96m_rates },
+	{ .parent = &func_54m_ck, .rates = common_clkout_src_54m_rates },
+	{ .parent = NULL },
+};
+
+static const char *sys_clkout_src_parent_names[] = {
+	"core_ck", "sys_ck", "func_96m_ck", "func_54m_ck",
+};
+
+DEFINE_CLK_OMAP_MUX_GATE(sys_clkout_src, "wkup_clkdm", common_clkout_src_clksel,
+			 OMAP2420_PRCM_CLKOUT_CTRL, OMAP24XX_CLKOUT_SOURCE_MASK,
+			 OMAP2420_PRCM_CLKOUT_CTRL, OMAP24XX_CLKOUT_EN_SHIFT,
+			 NULL, sys_clkout_src_parent_names, gpt1_fck_ops);
+
+DEFINE_CLK_DIVIDER(sys_clkout, "sys_clkout_src", &sys_clkout_src, 0x0,
+		   OMAP2420_PRCM_CLKOUT_CTRL, OMAP24XX_CLKOUT_DIV_SHIFT,
+		   OMAP24XX_CLKOUT_DIV_WIDTH, CLK_DIVIDER_POWER_OF_TWO, NULL);
+
+DEFINE_CLK_OMAP_MUX_GATE(sys_clkout2_src, "wkup_clkdm",
+			 common_clkout_src_clksel, OMAP2420_PRCM_CLKOUT_CTRL,
+			 OMAP2420_CLKOUT2_SOURCE_MASK,
+			 OMAP2420_PRCM_CLKOUT_CTRL, OMAP2420_CLKOUT2_EN_SHIFT,
+			 NULL, sys_clkout_src_parent_names, gpt1_fck_ops);
+
+DEFINE_CLK_DIVIDER(sys_clkout2, "sys_clkout2_src", &sys_clkout2_src, 0x0,
+		   OMAP2420_PRCM_CLKOUT_CTRL, OMAP2420_CLKOUT2_DIV_SHIFT,
+		   OMAP2420_CLKOUT2_DIV_WIDTH, CLK_DIVIDER_POWER_OF_TWO, NULL);
+
+static struct clk uart1_fck;
+
+static struct clk_hw_omap uart1_fck_hw = {
+	.hw = {
+		.clk = &uart1_fck,
+	},
+	.ops		= &clkhwops_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP24XX_EN_UART1_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(uart1_fck, mcspi1_fck_parent_names, aes_ick_ops);
+
+static struct clk uart1_ick;
+
+static struct clk_hw_omap uart1_ick_hw = {
+	.hw = {
+		.clk = &uart1_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_UART1_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(uart1_ick, aes_ick_parent_names, aes_ick_ops);
+
+static struct clk uart2_fck;
+
+static struct clk_hw_omap uart2_fck_hw = {
+	.hw = {
+		.clk = &uart2_fck,
+	},
+	.ops		= &clkhwops_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP24XX_EN_UART2_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(uart2_fck, mcspi1_fck_parent_names, aes_ick_ops);
+
+static struct clk uart2_ick;
+
+static struct clk_hw_omap uart2_ick_hw = {
+	.hw = {
+		.clk = &uart2_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_UART2_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(uart2_ick, aes_ick_parent_names, aes_ick_ops);
+
+static struct clk uart3_fck;
+
+static struct clk_hw_omap uart3_fck_hw = {
+	.hw = {
+		.clk = &uart3_fck,
+	},
+	.ops		= &clkhwops_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
+	.enable_bit	= OMAP24XX_EN_UART3_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(uart3_fck, mcspi1_fck_parent_names, aes_ick_ops);
+
+static struct clk uart3_ick;
+
+static struct clk_hw_omap uart3_ick_hw = {
+	.hw = {
+		.clk = &uart3_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
+	.enable_bit	= OMAP24XX_EN_UART3_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(uart3_ick, aes_ick_parent_names, aes_ick_ops);
+
+static struct clk usb_fck;
+
+static struct clk_hw_omap usb_fck_hw = {
+	.hw = {
+		.clk = &usb_fck,
+	},
+	.ops		= &clkhwops_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
+	.enable_bit	= OMAP24XX_EN_USB_SHIFT,
+	.clkdm_name	= "core_l3_clkdm",
+};
+
+DEFINE_STRUCT_CLK(usb_fck, mcspi1_fck_parent_names, aes_ick_ops);
+
+static const struct clksel_rate usb_l4_ick_core_l3_rates[] = {
+	{ .div = 1, .val = 1, .flags = RATE_IN_24XX },
+	{ .div = 2, .val = 2, .flags = RATE_IN_24XX },
+	{ .div = 4, .val = 4, .flags = RATE_IN_24XX },
+	{ .div = 0 }
+};
+
+static const struct clksel usb_l4_ick_clksel[] = {
+	{ .parent = &core_l3_ck, .rates = usb_l4_ick_core_l3_rates },
+	{ .parent = NULL },
+};
+
+static const char *usb_l4_ick_parent_names[] = {
+	"core_l3_ck",
+};
+
+DEFINE_CLK_OMAP_MUX_GATE(usb_l4_ick, "core_l4_clkdm", usb_l4_ick_clksel,
+			 OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1),
+			 OMAP24XX_CLKSEL_USB_MASK,
+			 OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
+			 OMAP24XX_EN_USB_SHIFT, &clkhwops_iclk_wait,
+			 usb_l4_ick_parent_names, dsp_fck_ops);
+
+static struct clk virt_prcm_set;
+
+static const char *virt_prcm_set_parent_names[] = {
+	"mpu_ck",
+};
+
+static const struct clk_ops virt_prcm_set_ops = {
+	.recalc_rate	= &omap2_table_mpu_recalc,
+	.set_rate	= &omap2_select_table_rate,
+	.round_rate	= &omap2_round_to_table_rate,
+};
+
+DEFINE_STRUCT_CLK_HW_OMAP(virt_prcm_set, NULL);
+DEFINE_STRUCT_CLK(virt_prcm_set, virt_prcm_set_parent_names, virt_prcm_set_ops);
+
+static const struct clksel_rate vlynq_fck_96m_rates[] = {
+	{ .div = 1, .val = 0, .flags = RATE_IN_242X },
+	{ .div = 0 }
+};
+
+static const struct clksel_rate vlynq_fck_core_rates[] = {
+	{ .div = 1, .val = 1, .flags = RATE_IN_242X },
+	{ .div = 2, .val = 2, .flags = RATE_IN_242X },
+	{ .div = 3, .val = 3, .flags = RATE_IN_242X },
+	{ .div = 4, .val = 4, .flags = RATE_IN_242X },
+	{ .div = 6, .val = 6, .flags = RATE_IN_242X },
+	{ .div = 8, .val = 8, .flags = RATE_IN_242X },
+	{ .div = 9, .val = 9, .flags = RATE_IN_242X },
+	{ .div = 12, .val = 12, .flags = RATE_IN_242X },
+	{ .div = 16, .val = 16, .flags = RATE_IN_242X },
+	{ .div = 18, .val = 18, .flags = RATE_IN_242X },
+	{ .div = 0 }
+};
+
+static const struct clksel vlynq_fck_clksel[] = {
+	{ .parent = &func_96m_ck, .rates = vlynq_fck_96m_rates },
+	{ .parent = &core_ck, .rates = vlynq_fck_core_rates },
+	{ .parent = NULL },
+};
+
+static const char *vlynq_fck_parent_names[] = {
+	"func_96m_ck", "core_ck",
+};
+
+DEFINE_CLK_OMAP_MUX_GATE(vlynq_fck, "core_l3_clkdm", vlynq_fck_clksel,
+			 OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1),
+			 OMAP2420_CLKSEL_VLYNQ_MASK,
+			 OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+			 OMAP2420_EN_VLYNQ_SHIFT, &clkhwops_wait,
+			 vlynq_fck_parent_names, dss1_fck_ops);
+
+static struct clk vlynq_ick;
+
+static struct clk_hw_omap vlynq_ick_hw = {
+	.hw = {
+		.clk = &vlynq_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP2420_EN_VLYNQ_SHIFT,
+	.clkdm_name	= "core_l3_clkdm",
+};
+
+DEFINE_STRUCT_CLK(vlynq_ick, gfx_ick_parent_names, aes_ick_ops);
+
+static struct clk wdt1_ick;
+
+static struct clk_hw_omap wdt1_ick_hw = {
+	.hw = {
+		.clk = &wdt1_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP24XX_EN_WDT1_SHIFT,
+	.clkdm_name	= "wkup_clkdm",
+};
+
+DEFINE_STRUCT_CLK(wdt1_ick, gpios_ick_parent_names, aes_ick_ops);
+
+static struct clk wdt1_osc_ck;
+
+static const struct clk_ops wdt1_osc_ck_ops = {};
+
+DEFINE_STRUCT_CLK_HW_OMAP(wdt1_osc_ck, NULL);
+DEFINE_STRUCT_CLK(wdt1_osc_ck, sys_ck_parent_names, wdt1_osc_ck_ops);
+
+static struct clk wdt3_fck;
+
+static struct clk_hw_omap wdt3_fck_hw = {
+	.hw = {
+		.clk = &wdt3_fck,
+	},
+	.ops		= &clkhwops_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP2420_EN_WDT3_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(wdt3_fck, gpios_fck_parent_names, aes_ick_ops);
+
+static struct clk wdt3_ick;
+
+static struct clk_hw_omap wdt3_ick_hw = {
+	.hw = {
+		.clk = &wdt3_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP2420_EN_WDT3_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(wdt3_ick, aes_ick_parent_names, aes_ick_ops);
+
+static struct clk wdt4_fck;
+
+static struct clk_hw_omap wdt4_fck_hw = {
+	.hw = {
+		.clk = &wdt4_fck,
+	},
+	.ops		= &clkhwops_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP24XX_EN_WDT4_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(wdt4_fck, gpios_fck_parent_names, aes_ick_ops);
+
+static struct clk wdt4_ick;
+
+static struct clk_hw_omap wdt4_ick_hw = {
+	.hw = {
+		.clk = &wdt4_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_WDT4_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(wdt4_ick, aes_ick_parent_names, aes_ick_ops);
+
+/*
+ * clkdev integration
+ */
+
+static struct omap_clk omap2420_clks[] = {
+	/* external root sources */
+	CLK(NULL,	"func_32k_ck",	&func_32k_ck,	CK_242X),
+	CLK(NULL,	"secure_32k_ck", &secure_32k_ck, CK_242X),
+	CLK(NULL,	"osc_ck",	&osc_ck,	CK_242X),
+	CLK(NULL,	"sys_ck",	&sys_ck,	CK_242X),
+	CLK(NULL,	"alt_ck",	&alt_ck,	CK_242X),
+	CLK(NULL,	"mcbsp_clks",	&mcbsp_clks,	CK_242X),
+	/* internal analog sources */
+	CLK(NULL,	"dpll_ck",	&dpll_ck,	CK_242X),
+	CLK(NULL,	"apll96_ck",	&apll96_ck,	CK_242X),
+	CLK(NULL,	"apll54_ck",	&apll54_ck,	CK_242X),
+	/* internal prcm root sources */
+	CLK(NULL,	"func_54m_ck",	&func_54m_ck,	CK_242X),
+	CLK(NULL,	"core_ck",	&core_ck,	CK_242X),
+	CLK(NULL,	"func_96m_ck",	&func_96m_ck,	CK_242X),
+	CLK(NULL,	"func_48m_ck",	&func_48m_ck,	CK_242X),
+	CLK(NULL,	"func_12m_ck",	&func_12m_ck,	CK_242X),
+	CLK(NULL,	"ck_wdt1_osc",	&wdt1_osc_ck,	CK_242X),
+	CLK(NULL,	"sys_clkout_src", &sys_clkout_src, CK_242X),
+	CLK(NULL,	"sys_clkout",	&sys_clkout,	CK_242X),
+	CLK(NULL,	"sys_clkout2_src", &sys_clkout2_src, CK_242X),
+	CLK(NULL,	"sys_clkout2",	&sys_clkout2,	CK_242X),
+	CLK(NULL,	"emul_ck",	&emul_ck,	CK_242X),
+	/* mpu domain clocks */
+	CLK(NULL,	"mpu_ck",	&mpu_ck,	CK_242X),
+	/* dsp domain clocks */
+	CLK(NULL,	"dsp_fck",	&dsp_fck,	CK_242X),
+	CLK(NULL,	"dsp_ick",	&dsp_ick,	CK_242X),
+	CLK(NULL,	"iva1_ifck",	&iva1_ifck,	CK_242X),
+	CLK(NULL,	"iva1_mpu_int_ifck", &iva1_mpu_int_ifck, CK_242X),
+	/* GFX domain clocks */
+	CLK(NULL,	"gfx_3d_fck",	&gfx_3d_fck,	CK_242X),
+	CLK(NULL,	"gfx_2d_fck",	&gfx_2d_fck,	CK_242X),
+	CLK(NULL,	"gfx_ick",	&gfx_ick,	CK_242X),
+	/* DSS domain clocks */
+	CLK("omapdss_dss",	"ick",		&dss_ick,	CK_242X),
+	CLK(NULL,	"dss_ick",		&dss_ick,	CK_242X),
+	CLK(NULL,	"dss1_fck",		&dss1_fck,	CK_242X),
+	CLK(NULL,	"dss2_fck",	&dss2_fck,	CK_242X),
+	CLK(NULL,	"dss_54m_fck",	&dss_54m_fck,	CK_242X),
+	/* L3 domain clocks */
+	CLK(NULL,	"core_l3_ck",	&core_l3_ck,	CK_242X),
+	CLK(NULL,	"ssi_fck",	&ssi_ssr_sst_fck, CK_242X),
+	CLK(NULL,	"usb_l4_ick",	&usb_l4_ick,	CK_242X),
+	/* L4 domain clocks */
+	CLK(NULL,	"l4_ck",	&l4_ck,		CK_242X),
+	CLK(NULL,	"ssi_l4_ick",	&ssi_l4_ick,	CK_242X),
+	CLK(NULL,	"wu_l4_ick",	&wu_l4_ick,	CK_242X),
+	/* virtual meta-group clock */
+	CLK(NULL,	"virt_prcm_set", &virt_prcm_set, CK_242X),
+	/* general l4 interface ck, multi-parent functional clk */
+	CLK(NULL,	"gpt1_ick",	&gpt1_ick,	CK_242X),
+	CLK(NULL,	"gpt1_fck",	&gpt1_fck,	CK_242X),
+	CLK(NULL,	"gpt2_ick",	&gpt2_ick,	CK_242X),
+	CLK(NULL,	"gpt2_fck",	&gpt2_fck,	CK_242X),
+	CLK(NULL,	"gpt3_ick",	&gpt3_ick,	CK_242X),
+	CLK(NULL,	"gpt3_fck",	&gpt3_fck,	CK_242X),
+	CLK(NULL,	"gpt4_ick",	&gpt4_ick,	CK_242X),
+	CLK(NULL,	"gpt4_fck",	&gpt4_fck,	CK_242X),
+	CLK(NULL,	"gpt5_ick",	&gpt5_ick,	CK_242X),
+	CLK(NULL,	"gpt5_fck",	&gpt5_fck,	CK_242X),
+	CLK(NULL,	"gpt6_ick",	&gpt6_ick,	CK_242X),
+	CLK(NULL,	"gpt6_fck",	&gpt6_fck,	CK_242X),
+	CLK(NULL,	"gpt7_ick",	&gpt7_ick,	CK_242X),
+	CLK(NULL,	"gpt7_fck",	&gpt7_fck,	CK_242X),
+	CLK(NULL,	"gpt8_ick",	&gpt8_ick,	CK_242X),
+	CLK(NULL,	"gpt8_fck",	&gpt8_fck,	CK_242X),
+	CLK(NULL,	"gpt9_ick",	&gpt9_ick,	CK_242X),
+	CLK(NULL,	"gpt9_fck",	&gpt9_fck,	CK_242X),
+	CLK(NULL,	"gpt10_ick",	&gpt10_ick,	CK_242X),
+	CLK(NULL,	"gpt10_fck",	&gpt10_fck,	CK_242X),
+	CLK(NULL,	"gpt11_ick",	&gpt11_ick,	CK_242X),
+	CLK(NULL,	"gpt11_fck",	&gpt11_fck,	CK_242X),
+	CLK(NULL,	"gpt12_ick",	&gpt12_ick,	CK_242X),
+	CLK(NULL,	"gpt12_fck",	&gpt12_fck,	CK_242X),
+	CLK("omap-mcbsp.1", "ick",	&mcbsp1_ick,	CK_242X),
+	CLK(NULL,	"mcbsp1_ick",	&mcbsp1_ick,	CK_242X),
+	CLK(NULL,	"mcbsp1_fck",	&mcbsp1_fck,	CK_242X),
+	CLK("omap-mcbsp.2", "ick",	&mcbsp2_ick,	CK_242X),
+	CLK(NULL,	"mcbsp2_ick",	&mcbsp2_ick,	CK_242X),
+	CLK(NULL,	"mcbsp2_fck",	&mcbsp2_fck,	CK_242X),
+	CLK("omap2_mcspi.1", "ick",	&mcspi1_ick,	CK_242X),
+	CLK(NULL,	"mcspi1_ick",	&mcspi1_ick,	CK_242X),
+	CLK(NULL,	"mcspi1_fck",	&mcspi1_fck,	CK_242X),
+	CLK("omap2_mcspi.2", "ick",	&mcspi2_ick,	CK_242X),
+	CLK(NULL,	"mcspi2_ick",	&mcspi2_ick,	CK_242X),
+	CLK(NULL,	"mcspi2_fck",	&mcspi2_fck,	CK_242X),
+	CLK(NULL,	"uart1_ick",	&uart1_ick,	CK_242X),
+	CLK(NULL,	"uart1_fck",	&uart1_fck,	CK_242X),
+	CLK(NULL,	"uart2_ick",	&uart2_ick,	CK_242X),
+	CLK(NULL,	"uart2_fck",	&uart2_fck,	CK_242X),
+	CLK(NULL,	"uart3_ick",	&uart3_ick,	CK_242X),
+	CLK(NULL,	"uart3_fck",	&uart3_fck,	CK_242X),
+	CLK(NULL,	"gpios_ick",	&gpios_ick,	CK_242X),
+	CLK(NULL,	"gpios_fck",	&gpios_fck,	CK_242X),
+	CLK("omap_wdt",	"ick",		&mpu_wdt_ick,	CK_242X),
+	CLK(NULL,	"mpu_wdt_ick",		&mpu_wdt_ick,	CK_242X),
+	CLK(NULL,	"mpu_wdt_fck",	&mpu_wdt_fck,	CK_242X),
+	CLK(NULL,	"sync_32k_ick",	&sync_32k_ick,	CK_242X),
+	CLK(NULL,	"wdt1_ick",	&wdt1_ick,	CK_242X),
+	CLK(NULL,	"omapctrl_ick",	&omapctrl_ick,	CK_242X),
+	CLK("omap24xxcam", "fck",	&cam_fck,	CK_242X),
+	CLK(NULL,	"cam_fck",	&cam_fck,	CK_242X),
+	CLK("omap24xxcam", "ick",	&cam_ick,	CK_242X),
+	CLK(NULL,	"cam_ick",	&cam_ick,	CK_242X),
+	CLK(NULL,	"mailboxes_ick", &mailboxes_ick,	CK_242X),
+	CLK(NULL,	"wdt4_ick",	&wdt4_ick,	CK_242X),
+	CLK(NULL,	"wdt4_fck",	&wdt4_fck,	CK_242X),
+	CLK(NULL,	"wdt3_ick",	&wdt3_ick,	CK_242X),
+	CLK(NULL,	"wdt3_fck",	&wdt3_fck,	CK_242X),
+	CLK(NULL,	"mspro_ick",	&mspro_ick,	CK_242X),
+	CLK(NULL,	"mspro_fck",	&mspro_fck,	CK_242X),
+	CLK("mmci-omap.0", "ick",	&mmc_ick,	CK_242X),
+	CLK(NULL,	"mmc_ick",	&mmc_ick,	CK_242X),
+	CLK("mmci-omap.0", "fck",	&mmc_fck,	CK_242X),
+	CLK(NULL,	"mmc_fck",	&mmc_fck,	CK_242X),
+	CLK(NULL,	"fac_ick",	&fac_ick,	CK_242X),
+	CLK(NULL,	"fac_fck",	&fac_fck,	CK_242X),
+	CLK(NULL,	"eac_ick",	&eac_ick,	CK_242X),
+	CLK(NULL,	"eac_fck",	&eac_fck,	CK_242X),
+	CLK("omap_hdq.0", "ick",	&hdq_ick,	CK_242X),
+	CLK(NULL,	"hdq_ick",	&hdq_ick,	CK_242X),
+	CLK("omap_hdq.0", "fck",	&hdq_fck,	CK_242X),
+	CLK(NULL,	"hdq_fck",	&hdq_fck,	CK_242X),
+	CLK("omap_i2c.1", "ick",	&i2c1_ick,	CK_242X),
+	CLK(NULL,	"i2c1_ick",	&i2c1_ick,	CK_242X),
+	CLK(NULL,	"i2c1_fck",	&i2c1_fck,	CK_242X),
+	CLK("omap_i2c.2", "ick",	&i2c2_ick,	CK_242X),
+	CLK(NULL,	"i2c2_ick",	&i2c2_ick,	CK_242X),
+	CLK(NULL,	"i2c2_fck",	&i2c2_fck,	CK_242X),
+	CLK(NULL,	"gpmc_fck",	&gpmc_fck,	CK_242X),
+	CLK(NULL,	"sdma_fck",	&sdma_fck,	CK_242X),
+	CLK(NULL,	"sdma_ick",	&sdma_ick,	CK_242X),
+	CLK(NULL,	"sdrc_ick",	&sdrc_ick,	CK_242X),
+	CLK(NULL,	"vlynq_ick",	&vlynq_ick,	CK_242X),
+	CLK(NULL,	"vlynq_fck",	&vlynq_fck,	CK_242X),
+	CLK(NULL,	"des_ick",	&des_ick,	CK_242X),
+	CLK("omap-sham",	"ick",	&sha_ick,	CK_242X),
+	CLK(NULL,	"sha_ick",	&sha_ick,	CK_242X),
+	CLK("omap_rng",	"ick",		&rng_ick,	CK_242X),
+	CLK(NULL,	"rng_ick",		&rng_ick,	CK_242X),
+	CLK("omap-aes",	"ick",	&aes_ick,	CK_242X),
+	CLK(NULL,	"aes_ick",	&aes_ick,	CK_242X),
+	CLK(NULL,	"pka_ick",	&pka_ick,	CK_242X),
+	CLK(NULL,	"usb_fck",	&usb_fck,	CK_242X),
+	CLK("musb-hdrc",	"fck",	&osc_ck,	CK_242X),
+	CLK(NULL,	"timer_32k_ck",	&func_32k_ck,	CK_242X),
+	CLK(NULL,	"timer_sys_ck",	&sys_ck,	CK_242X),
+	CLK(NULL,	"timer_ext_ck",	&alt_ck,	CK_242X),
+	CLK(NULL,	"cpufreq_ck",	&virt_prcm_set,	CK_242X),
+};
+
+
+static const char *enable_init_clks[] = {
+	"apll96_ck",
+	"apll54_ck",
+	"sync_32k_ick",
+	"omapctrl_ick",
+	"gpmc_fck",
+	"sdrc_ick",
+};
+
+/*
+ * init code
+ */
+
+int __init omap2420_clk_init(void)
+{
+	struct omap_clk *c;
+
+	prcm_clksrc_ctrl = OMAP2420_PRCM_CLKSRC_CTRL;
+	cpu_mask = RATE_IN_242X;
+	rate_table = omap2420_rate_table;
+
+	omap2xxx_clkt_dpllcore_init(&dpll_ck_hw.hw);
+
+	omap2xxx_clkt_vps_check_bootloader_rates();
+
+	for (c = omap2420_clks; c < omap2420_clks + ARRAY_SIZE(omap2420_clks);
+	     c++) {
+		clkdev_add(&c->lk);
+		if (!__clk_init(NULL, c->lk.clk))
+			omap2_init_clk_hw_omap_clocks(c->lk.clk);
+	}
+
+	omap2_clk_disable_autoidle_all();
+
+	omap2_clk_enable_init_clocks(enable_init_clks,
+				     ARRAY_SIZE(enable_init_clks));
+
+	pr_info("Clocking rate (Crystal/DPLL/MPU): %ld.%01ld/%ld/%ld MHz\n",
+		(clk_get_rate(&sys_ck) / 1000000),
+		(clk_get_rate(&sys_ck) / 100000) % 10,
+		(clk_get_rate(&dpll_ck) / 1000000),
+		(clk_get_rate(&mpu_ck) / 1000000));
+
+	return 0;
+}
diff --git a/arch/arm/mach-omap2/cclock2430_data.c b/arch/arm/mach-omap2/cclock2430_data.c
new file mode 100644
index 0000000..eda079b
--- /dev/null
+++ b/arch/arm/mach-omap2/cclock2430_data.c
@@ -0,0 +1,2065 @@
+/*
+ * OMAP2430 clock data
+ *
+ * Copyright (C) 2005-2009, 2012 Texas Instruments, Inc.
+ * Copyright (C) 2004-2011 Nokia Corporation
+ *
+ * Contacts:
+ * Richard Woodruff <r-woodruff2@ti.com>
+ * Paul Walmsley
+ *
+ * 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/clk.h>
+#include <linux/clk-private.h>
+#include <linux/list.h>
+
+#include "soc.h"
+#include "iomap.h"
+#include "clock.h"
+#include "clock2xxx.h"
+#include "opp2xxx.h"
+#include "cm2xxx.h"
+#include "prm2xxx.h"
+#include "prm-regbits-24xx.h"
+#include "cm-regbits-24xx.h"
+#include "sdrc.h"
+#include "control.h"
+
+#define OMAP_CM_REGADDR			OMAP2430_CM_REGADDR
+
+/*
+ * 2430 clock tree.
+ *
+ * NOTE:In many cases here we are assigning a 'default' parent. In
+ *	many cases the parent is selectable. The set parent calls will
+ *	also switch sources.
+ *
+ *	Several sources are given initial rates which may be wrong, this will
+ *	be fixed up in the init func.
+ *
+ *	Things are broadly separated below by clock domains. It is
+ *	noteworthy that most peripherals have dependencies on multiple clock
+ *	domains. Many get their interface clocks from the L4 domain, but get
+ *	functional clocks from fixed sources or other core domain derived
+ *	clocks.
+ */
+
+DEFINE_CLK_FIXED_RATE(alt_ck, CLK_IS_ROOT, 54000000, 0x0);
+
+DEFINE_CLK_FIXED_RATE(func_32k_ck, CLK_IS_ROOT, 32768, 0x0);
+
+DEFINE_CLK_FIXED_RATE(mcbsp_clks, CLK_IS_ROOT, 0x0, 0x0);
+
+static struct clk osc_ck;
+
+static const struct clk_ops osc_ck_ops = {
+	.enable		= &omap2_enable_osc_ck,
+	.disable	= omap2_disable_osc_ck,
+	.recalc_rate	= &omap2_osc_clk_recalc,
+};
+
+static struct clk_hw_omap osc_ck_hw = {
+	.hw = {
+		.clk = &osc_ck,
+	},
+};
+
+static struct clk osc_ck = {
+	.name	= "osc_ck",
+	.ops	= &osc_ck_ops,
+	.hw	= &osc_ck_hw.hw,
+	.flags	= CLK_IS_ROOT,
+};
+
+DEFINE_CLK_FIXED_RATE(secure_32k_ck, CLK_IS_ROOT, 32768, 0x0);
+
+static struct clk sys_ck;
+
+static const char *sys_ck_parent_names[] = {
+	"osc_ck",
+};
+
+static const struct clk_ops sys_ck_ops = {
+	.init		= &omap2_init_clk_clkdm,
+	.recalc_rate	= &omap2xxx_sys_clk_recalc,
+};
+
+DEFINE_STRUCT_CLK_HW_OMAP(sys_ck, "wkup_clkdm");
+DEFINE_STRUCT_CLK(sys_ck, sys_ck_parent_names, sys_ck_ops);
+
+static struct dpll_data dpll_dd = {
+	.mult_div1_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1),
+	.mult_mask	= OMAP24XX_DPLL_MULT_MASK,
+	.div1_mask	= OMAP24XX_DPLL_DIV_MASK,
+	.clk_bypass	= &sys_ck,
+	.clk_ref	= &sys_ck,
+	.control_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
+	.enable_mask	= OMAP24XX_EN_DPLL_MASK,
+	.max_multiplier	= 1023,
+	.min_divider	= 1,
+	.max_divider	= 16,
+};
+
+static struct clk dpll_ck;
+
+static const char *dpll_ck_parent_names[] = {
+	"sys_ck",
+};
+
+static const struct clk_ops dpll_ck_ops = {
+	.init		= &omap2_init_clk_clkdm,
+	.get_parent	= &omap2_init_dpll_parent,
+	.recalc_rate	= &omap2_dpllcore_recalc,
+	.round_rate	= &omap2_dpll_round_rate,
+	.set_rate	= &omap2_reprogram_dpllcore,
+};
+
+static struct clk_hw_omap dpll_ck_hw = {
+	.hw = {
+		.clk = &dpll_ck,
+	},
+	.ops		= &clkhwops_omap2xxx_dpll,
+	.dpll_data	= &dpll_dd,
+	.clkdm_name	= "wkup_clkdm",
+};
+
+DEFINE_STRUCT_CLK(dpll_ck, dpll_ck_parent_names, dpll_ck_ops);
+
+static struct clk core_ck;
+
+static const char *core_ck_parent_names[] = {
+	"dpll_ck",
+};
+
+static const struct clk_ops core_ck_ops = {
+	.init		= &omap2_init_clk_clkdm,
+};
+
+DEFINE_STRUCT_CLK_HW_OMAP(core_ck, "wkup_clkdm");
+DEFINE_STRUCT_CLK(core_ck, core_ck_parent_names, core_ck_ops);
+
+DEFINE_CLK_DIVIDER(core_l3_ck, "core_ck", &core_ck, 0x0,
+		   OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1),
+		   OMAP24XX_CLKSEL_L3_SHIFT, OMAP24XX_CLKSEL_L3_WIDTH,
+		   CLK_DIVIDER_ONE_BASED, NULL);
+
+DEFINE_CLK_DIVIDER(l4_ck, "core_l3_ck", &core_l3_ck, 0x0,
+		   OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1),
+		   OMAP24XX_CLKSEL_L4_SHIFT, OMAP24XX_CLKSEL_L4_WIDTH,
+		   CLK_DIVIDER_ONE_BASED, NULL);
+
+static struct clk aes_ick;
+
+static const char *aes_ick_parent_names[] = {
+	"l4_ck",
+};
+
+static const struct clk_ops aes_ick_ops = {
+	.init		= &omap2_init_clk_clkdm,
+	.enable		= &omap2_dflt_clk_enable,
+	.disable	= &omap2_dflt_clk_disable,
+	.is_enabled	= &omap2_dflt_clk_is_enabled,
+};
+
+static struct clk_hw_omap aes_ick_hw = {
+	.hw = {
+		.clk = &aes_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_ICLKEN4),
+	.enable_bit	= OMAP24XX_EN_AES_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(aes_ick, aes_ick_parent_names, aes_ick_ops);
+
+static struct clk apll54_ck;
+
+static const struct clk_ops apll54_ck_ops = {
+	.init		= &omap2_init_clk_clkdm,
+	.enable		= &omap2_clk_apll54_enable,
+	.disable	= &omap2_clk_apll54_disable,
+	.recalc_rate	= &omap2_clk_apll54_recalc,
+};
+
+static struct clk_hw_omap apll54_ck_hw = {
+	.hw = {
+		.clk = &apll54_ck,
+	},
+	.ops		= &clkhwops_apll54,
+	.enable_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
+	.enable_bit	= OMAP24XX_EN_54M_PLL_SHIFT,
+	.flags		= ENABLE_ON_INIT,
+	.clkdm_name	= "wkup_clkdm",
+};
+
+DEFINE_STRUCT_CLK(apll54_ck, dpll_ck_parent_names, apll54_ck_ops);
+
+static struct clk apll96_ck;
+
+static const struct clk_ops apll96_ck_ops = {
+	.init		= &omap2_init_clk_clkdm,
+	.enable		= &omap2_clk_apll96_enable,
+	.disable	= &omap2_clk_apll96_disable,
+	.recalc_rate	= &omap2_clk_apll96_recalc,
+};
+
+static struct clk_hw_omap apll96_ck_hw = {
+	.hw = {
+		.clk = &apll96_ck,
+	},
+	.ops		= &clkhwops_apll96,
+	.enable_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
+	.enable_bit	= OMAP24XX_EN_96M_PLL_SHIFT,
+	.flags		= ENABLE_ON_INIT,
+	.clkdm_name	= "wkup_clkdm",
+};
+
+DEFINE_STRUCT_CLK(apll96_ck, dpll_ck_parent_names, apll96_ck_ops);
+
+static const char *func_96m_ck_parent_names[] = {
+	"apll96_ck", "alt_ck",
+};
+
+DEFINE_CLK_MUX(func_96m_ck, func_96m_ck_parent_names, NULL, 0x0,
+	       OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1), OMAP2430_96M_SOURCE_SHIFT,
+	       OMAP2430_96M_SOURCE_WIDTH, 0x0, NULL);
+
+static struct clk cam_fck;
+
+static const char *cam_fck_parent_names[] = {
+	"func_96m_ck",
+};
+
+static struct clk_hw_omap cam_fck_hw = {
+	.hw = {
+		.clk = &cam_fck,
+	},
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP24XX_EN_CAM_SHIFT,
+	.clkdm_name	= "core_l3_clkdm",
+};
+
+DEFINE_STRUCT_CLK(cam_fck, cam_fck_parent_names, aes_ick_ops);
+
+static struct clk cam_ick;
+
+static struct clk_hw_omap cam_ick_hw = {
+	.hw = {
+		.clk = &cam_ick,
+	},
+	.ops		= &clkhwops_iclk,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_CAM_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(cam_ick, aes_ick_parent_names, aes_ick_ops);
+
+static struct clk des_ick;
+
+static struct clk_hw_omap des_ick_hw = {
+	.hw = {
+		.clk = &des_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_ICLKEN4),
+	.enable_bit	= OMAP24XX_EN_DES_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(des_ick, aes_ick_parent_names, aes_ick_ops);
+
+static const struct clksel_rate dsp_fck_core_rates[] = {
+	{ .div = 1, .val = 1, .flags = RATE_IN_24XX },
+	{ .div = 2, .val = 2, .flags = RATE_IN_24XX },
+	{ .div = 3, .val = 3, .flags = RATE_IN_24XX },
+	{ .div = 4, .val = 4, .flags = RATE_IN_24XX },
+	{ .div = 0 }
+};
+
+static const struct clksel dsp_fck_clksel[] = {
+	{ .parent = &core_ck, .rates = dsp_fck_core_rates },
+	{ .parent = NULL },
+};
+
+static const char *dsp_fck_parent_names[] = {
+	"core_ck",
+};
+
+static struct clk dsp_fck;
+
+static const struct clk_ops dsp_fck_ops = {
+	.init		= &omap2_init_clk_clkdm,
+	.enable		= &omap2_dflt_clk_enable,
+	.disable	= &omap2_dflt_clk_disable,
+	.is_enabled	= &omap2_dflt_clk_is_enabled,
+	.recalc_rate	= &omap2_clksel_recalc,
+	.set_rate	= &omap2_clksel_set_rate,
+	.round_rate	= &omap2_clksel_round_rate,
+};
+
+DEFINE_CLK_OMAP_MUX_GATE(dsp_fck, "dsp_clkdm", dsp_fck_clksel,
+			 OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_CLKSEL),
+			 OMAP24XX_CLKSEL_DSP_MASK,
+			 OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_FCLKEN),
+			 OMAP24XX_CM_FCLKEN_DSP_EN_DSP_SHIFT, &clkhwops_wait,
+			 dsp_fck_parent_names, dsp_fck_ops);
+
+static const struct clksel_rate dss1_fck_sys_rates[] = {
+	{ .div = 1, .val = 0, .flags = RATE_IN_24XX },
+	{ .div = 0 }
+};
+
+static const struct clksel_rate dss1_fck_core_rates[] = {
+	{ .div = 1, .val = 1, .flags = RATE_IN_24XX },
+	{ .div = 2, .val = 2, .flags = RATE_IN_24XX },
+	{ .div = 3, .val = 3, .flags = RATE_IN_24XX },
+	{ .div = 4, .val = 4, .flags = RATE_IN_24XX },
+	{ .div = 5, .val = 5, .flags = RATE_IN_24XX },
+	{ .div = 6, .val = 6, .flags = RATE_IN_24XX },
+	{ .div = 8, .val = 8, .flags = RATE_IN_24XX },
+	{ .div = 9, .val = 9, .flags = RATE_IN_24XX },
+	{ .div = 12, .val = 12, .flags = RATE_IN_24XX },
+	{ .div = 16, .val = 16, .flags = RATE_IN_24XX },
+	{ .div = 0 }
+};
+
+static const struct clksel dss1_fck_clksel[] = {
+	{ .parent = &sys_ck, .rates = dss1_fck_sys_rates },
+	{ .parent = &core_ck, .rates = dss1_fck_core_rates },
+	{ .parent = NULL },
+};
+
+static const char *dss1_fck_parent_names[] = {
+	"sys_ck", "core_ck",
+};
+
+static const struct clk_ops dss1_fck_ops = {
+	.init		= &omap2_init_clk_clkdm,
+	.enable		= &omap2_dflt_clk_enable,
+	.disable	= &omap2_dflt_clk_disable,
+	.is_enabled	= &omap2_dflt_clk_is_enabled,
+	.recalc_rate	= &omap2_clksel_recalc,
+	.get_parent	= &omap2_clksel_find_parent_index,
+	.set_parent	= &omap2_clksel_set_parent,
+};
+
+DEFINE_CLK_OMAP_MUX_GATE(dss1_fck, "dss_clkdm", dss1_fck_clksel,
+			 OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1),
+			 OMAP24XX_CLKSEL_DSS1_MASK,
+			 OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+			 OMAP24XX_EN_DSS1_SHIFT, NULL,
+			 dss1_fck_parent_names, dss1_fck_ops);
+
+static const struct clksel_rate dss2_fck_sys_rates[] = {
+	{ .div = 1, .val = 0, .flags = RATE_IN_24XX },
+	{ .div = 0 }
+};
+
+static const struct clksel_rate dss2_fck_48m_rates[] = {
+	{ .div = 1, .val = 1, .flags = RATE_IN_24XX },
+	{ .div = 0 }
+};
+
+static const struct clksel_rate func_48m_apll96_rates[] = {
+	{ .div = 2, .val = 0, .flags = RATE_IN_24XX },
+	{ .div = 0 }
+};
+
+static const struct clksel_rate func_48m_alt_rates[] = {
+	{ .div = 1, .val = 1, .flags = RATE_IN_24XX },
+	{ .div = 0 }
+};
+
+static const struct clksel func_48m_clksel[] = {
+	{ .parent = &apll96_ck, .rates = func_48m_apll96_rates },
+	{ .parent = &alt_ck, .rates = func_48m_alt_rates },
+	{ .parent = NULL },
+};
+
+static const char *func_48m_ck_parent_names[] = {
+	"apll96_ck", "alt_ck",
+};
+
+static struct clk func_48m_ck;
+
+static const struct clk_ops func_48m_ck_ops = {
+	.init		= &omap2_init_clk_clkdm,
+	.recalc_rate	= &omap2_clksel_recalc,
+	.set_rate	= &omap2_clksel_set_rate,
+	.round_rate	= &omap2_clksel_round_rate,
+	.get_parent	= &omap2_clksel_find_parent_index,
+	.set_parent	= &omap2_clksel_set_parent,
+};
+
+static struct clk_hw_omap func_48m_ck_hw = {
+	.hw = {
+		.clk = &func_48m_ck,
+	},
+	.clksel		= func_48m_clksel,
+	.clksel_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1),
+	.clksel_mask	= OMAP24XX_48M_SOURCE_MASK,
+	.clkdm_name	= "wkup_clkdm",
+};
+
+DEFINE_STRUCT_CLK(func_48m_ck, func_48m_ck_parent_names, func_48m_ck_ops);
+
+static const struct clksel dss2_fck_clksel[] = {
+	{ .parent = &sys_ck, .rates = dss2_fck_sys_rates },
+	{ .parent = &func_48m_ck, .rates = dss2_fck_48m_rates },
+	{ .parent = NULL },
+};
+
+static const char *dss2_fck_parent_names[] = {
+	"sys_ck", "func_48m_ck",
+};
+
+DEFINE_CLK_OMAP_MUX_GATE(dss2_fck, "dss_clkdm", dss2_fck_clksel,
+			 OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1),
+			 OMAP24XX_CLKSEL_DSS2_MASK,
+			 OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+			 OMAP24XX_EN_DSS2_SHIFT, NULL,
+			 dss2_fck_parent_names, dss1_fck_ops);
+
+static const char *func_54m_ck_parent_names[] = {
+	"apll54_ck", "alt_ck",
+};
+
+DEFINE_CLK_MUX(func_54m_ck, func_54m_ck_parent_names, NULL, 0x0,
+	       OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1),
+	       OMAP24XX_54M_SOURCE_SHIFT, OMAP24XX_54M_SOURCE_WIDTH, 0x0, NULL);
+
+static struct clk dss_54m_fck;
+
+static const char *dss_54m_fck_parent_names[] = {
+	"func_54m_ck",
+};
+
+static struct clk_hw_omap dss_54m_fck_hw = {
+	.hw = {
+		.clk = &dss_54m_fck,
+	},
+	.ops		= &clkhwops_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP24XX_EN_TV_SHIFT,
+	.clkdm_name	= "dss_clkdm",
+};
+
+DEFINE_STRUCT_CLK(dss_54m_fck, dss_54m_fck_parent_names, aes_ick_ops);
+
+static struct clk dss_ick;
+
+static struct clk_hw_omap dss_ick_hw = {
+	.hw = {
+		.clk = &dss_ick,
+	},
+	.ops		= &clkhwops_iclk,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_DSS1_SHIFT,
+	.clkdm_name	= "dss_clkdm",
+};
+
+DEFINE_STRUCT_CLK(dss_ick, aes_ick_parent_names, aes_ick_ops);
+
+static struct clk emul_ck;
+
+static struct clk_hw_omap emul_ck_hw = {
+	.hw = {
+		.clk = &emul_ck,
+	},
+	.enable_reg	= OMAP2430_PRCM_CLKEMUL_CTRL,
+	.enable_bit	= OMAP24XX_EMULATION_EN_SHIFT,
+	.clkdm_name	= "wkup_clkdm",
+};
+
+DEFINE_STRUCT_CLK(emul_ck, dss_54m_fck_parent_names, aes_ick_ops);
+
+DEFINE_CLK_FIXED_FACTOR(func_12m_ck, "func_48m_ck", &func_48m_ck, 0x0, 1, 4);
+
+static struct clk fac_fck;
+
+static const char *fac_fck_parent_names[] = {
+	"func_12m_ck",
+};
+
+static struct clk_hw_omap fac_fck_hw = {
+	.hw = {
+		.clk = &fac_fck,
+	},
+	.ops		= &clkhwops_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP24XX_EN_FAC_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(fac_fck, fac_fck_parent_names, aes_ick_ops);
+
+static struct clk fac_ick;
+
+static struct clk_hw_omap fac_ick_hw = {
+	.hw = {
+		.clk = &fac_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_FAC_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(fac_ick, aes_ick_parent_names, aes_ick_ops);
+
+static const struct clksel gfx_fck_clksel[] = {
+	{ .parent = &core_l3_ck, .rates = gfx_l3_rates },
+	{ .parent = NULL },
+};
+
+static const char *gfx_2d_fck_parent_names[] = {
+	"core_l3_ck",
+};
+
+DEFINE_CLK_OMAP_MUX_GATE(gfx_2d_fck, "gfx_clkdm", gfx_fck_clksel,
+			 OMAP_CM_REGADDR(GFX_MOD, CM_CLKSEL),
+			 OMAP_CLKSEL_GFX_MASK,
+			 OMAP_CM_REGADDR(GFX_MOD, CM_FCLKEN),
+			 OMAP24XX_EN_2D_SHIFT, &clkhwops_wait,
+			 gfx_2d_fck_parent_names, dsp_fck_ops);
+
+DEFINE_CLK_OMAP_MUX_GATE(gfx_3d_fck, "gfx_clkdm", gfx_fck_clksel,
+			 OMAP_CM_REGADDR(GFX_MOD, CM_CLKSEL),
+			 OMAP_CLKSEL_GFX_MASK,
+			 OMAP_CM_REGADDR(GFX_MOD, CM_FCLKEN),
+			 OMAP24XX_EN_3D_SHIFT, &clkhwops_wait,
+			 gfx_2d_fck_parent_names, dsp_fck_ops);
+
+static struct clk gfx_ick;
+
+static const char *gfx_ick_parent_names[] = {
+	"core_l3_ck",
+};
+
+static struct clk_hw_omap gfx_ick_hw = {
+	.hw = {
+		.clk = &gfx_ick,
+	},
+	.ops		= &clkhwops_wait,
+	.enable_reg	= OMAP_CM_REGADDR(GFX_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP_EN_GFX_SHIFT,
+	.clkdm_name	= "gfx_clkdm",
+};
+
+DEFINE_STRUCT_CLK(gfx_ick, gfx_ick_parent_names, aes_ick_ops);
+
+static struct clk gpio5_fck;
+
+static const char *gpio5_fck_parent_names[] = {
+	"func_32k_ck",
+};
+
+static struct clk_hw_omap gpio5_fck_hw = {
+	.hw = {
+		.clk = &gpio5_fck,
+	},
+	.ops		= &clkhwops_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
+	.enable_bit	= OMAP2430_EN_GPIO5_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(gpio5_fck, gpio5_fck_parent_names, aes_ick_ops);
+
+static struct clk gpio5_ick;
+
+static struct clk_hw_omap gpio5_ick_hw = {
+	.hw = {
+		.clk = &gpio5_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
+	.enable_bit	= OMAP2430_EN_GPIO5_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(gpio5_ick, aes_ick_parent_names, aes_ick_ops);
+
+static struct clk gpios_fck;
+
+static struct clk_hw_omap gpios_fck_hw = {
+	.hw = {
+		.clk = &gpios_fck,
+	},
+	.ops		= &clkhwops_wait,
+	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP24XX_EN_GPIOS_SHIFT,
+	.clkdm_name	= "wkup_clkdm",
+};
+
+DEFINE_STRUCT_CLK(gpios_fck, gpio5_fck_parent_names, aes_ick_ops);
+
+static struct clk wu_l4_ick;
+
+DEFINE_STRUCT_CLK_HW_OMAP(wu_l4_ick, "wkup_clkdm");
+DEFINE_STRUCT_CLK(wu_l4_ick, dpll_ck_parent_names, core_ck_ops);
+
+static struct clk gpios_ick;
+
+static const char *gpios_ick_parent_names[] = {
+	"wu_l4_ick",
+};
+
+static struct clk_hw_omap gpios_ick_hw = {
+	.hw = {
+		.clk = &gpios_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP24XX_EN_GPIOS_SHIFT,
+	.clkdm_name	= "wkup_clkdm",
+};
+
+DEFINE_STRUCT_CLK(gpios_ick, gpios_ick_parent_names, aes_ick_ops);
+
+static struct clk gpmc_fck;
+
+static struct clk_hw_omap gpmc_fck_hw = {
+	.hw = {
+		.clk = &gpmc_fck,
+	},
+	.ops		= &clkhwops_iclk,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN3),
+	.enable_bit	= OMAP24XX_AUTO_GPMC_SHIFT,
+	.flags		= ENABLE_ON_INIT,
+	.clkdm_name	= "core_l3_clkdm",
+};
+
+DEFINE_STRUCT_CLK(gpmc_fck, gfx_ick_parent_names, core_ck_ops);
+
+static const struct clksel_rate gpt_alt_rates[] = {
+	{ .div = 1, .val = 2, .flags = RATE_IN_24XX },
+	{ .div = 0 }
+};
+
+static const struct clksel omap24xx_gpt_clksel[] = {
+	{ .parent = &func_32k_ck, .rates = gpt_32k_rates },
+	{ .parent = &sys_ck, .rates = gpt_sys_rates },
+	{ .parent = &alt_ck, .rates = gpt_alt_rates },
+	{ .parent = NULL },
+};
+
+static const char *gpt10_fck_parent_names[] = {
+	"func_32k_ck", "sys_ck", "alt_ck",
+};
+
+DEFINE_CLK_OMAP_MUX_GATE(gpt10_fck, "core_l4_clkdm", omap24xx_gpt_clksel,
+			 OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
+			 OMAP24XX_CLKSEL_GPT10_MASK,
+			 OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+			 OMAP24XX_EN_GPT10_SHIFT, &clkhwops_wait,
+			 gpt10_fck_parent_names, dss1_fck_ops);
+
+static struct clk gpt10_ick;
+
+static struct clk_hw_omap gpt10_ick_hw = {
+	.hw = {
+		.clk = &gpt10_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_GPT10_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(gpt10_ick, aes_ick_parent_names, aes_ick_ops);
+
+DEFINE_CLK_OMAP_MUX_GATE(gpt11_fck, "core_l4_clkdm", omap24xx_gpt_clksel,
+			 OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
+			 OMAP24XX_CLKSEL_GPT11_MASK,
+			 OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+			 OMAP24XX_EN_GPT11_SHIFT, &clkhwops_wait,
+			 gpt10_fck_parent_names, dss1_fck_ops);
+
+static struct clk gpt11_ick;
+
+static struct clk_hw_omap gpt11_ick_hw = {
+	.hw = {
+		.clk = &gpt11_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_GPT11_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(gpt11_ick, aes_ick_parent_names, aes_ick_ops);
+
+DEFINE_CLK_OMAP_MUX_GATE(gpt12_fck, "core_l4_clkdm", omap24xx_gpt_clksel,
+			 OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
+			 OMAP24XX_CLKSEL_GPT12_MASK,
+			 OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+			 OMAP24XX_EN_GPT12_SHIFT, &clkhwops_wait,
+			 gpt10_fck_parent_names, dss1_fck_ops);
+
+static struct clk gpt12_ick;
+
+static struct clk_hw_omap gpt12_ick_hw = {
+	.hw = {
+		.clk = &gpt12_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_GPT12_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(gpt12_ick, aes_ick_parent_names, aes_ick_ops);
+
+static const struct clk_ops gpt1_fck_ops = {
+	.init		= &omap2_init_clk_clkdm,
+	.enable		= &omap2_dflt_clk_enable,
+	.disable	= &omap2_dflt_clk_disable,
+	.is_enabled	= &omap2_dflt_clk_is_enabled,
+	.recalc_rate	= &omap2_clksel_recalc,
+	.set_rate	= &omap2_clksel_set_rate,
+	.round_rate	= &omap2_clksel_round_rate,
+	.get_parent	= &omap2_clksel_find_parent_index,
+	.set_parent	= &omap2_clksel_set_parent,
+};
+
+DEFINE_CLK_OMAP_MUX_GATE(gpt1_fck, "core_l4_clkdm", omap24xx_gpt_clksel,
+			 OMAP_CM_REGADDR(WKUP_MOD, CM_CLKSEL1),
+			 OMAP24XX_CLKSEL_GPT1_MASK,
+			 OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN),
+			 OMAP24XX_EN_GPT1_SHIFT, &clkhwops_wait,
+			 gpt10_fck_parent_names, gpt1_fck_ops);
+
+static struct clk gpt1_ick;
+
+static struct clk_hw_omap gpt1_ick_hw = {
+	.hw = {
+		.clk = &gpt1_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP24XX_EN_GPT1_SHIFT,
+	.clkdm_name	= "wkup_clkdm",
+};
+
+DEFINE_STRUCT_CLK(gpt1_ick, gpios_ick_parent_names, aes_ick_ops);
+
+DEFINE_CLK_OMAP_MUX_GATE(gpt2_fck, "core_l4_clkdm", omap24xx_gpt_clksel,
+			 OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
+			 OMAP24XX_CLKSEL_GPT2_MASK,
+			 OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+			 OMAP24XX_EN_GPT2_SHIFT, &clkhwops_wait,
+			 gpt10_fck_parent_names, dss1_fck_ops);
+
+static struct clk gpt2_ick;
+
+static struct clk_hw_omap gpt2_ick_hw = {
+	.hw = {
+		.clk = &gpt2_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_GPT2_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(gpt2_ick, aes_ick_parent_names, aes_ick_ops);
+
+DEFINE_CLK_OMAP_MUX_GATE(gpt3_fck, "core_l4_clkdm", omap24xx_gpt_clksel,
+			 OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
+			 OMAP24XX_CLKSEL_GPT3_MASK,
+			 OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+			 OMAP24XX_EN_GPT3_SHIFT, &clkhwops_wait,
+			 gpt10_fck_parent_names, dss1_fck_ops);
+
+static struct clk gpt3_ick;
+
+static struct clk_hw_omap gpt3_ick_hw = {
+	.hw = {
+		.clk = &gpt3_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_GPT3_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(gpt3_ick, aes_ick_parent_names, aes_ick_ops);
+
+DEFINE_CLK_OMAP_MUX_GATE(gpt4_fck, "core_l4_clkdm", omap24xx_gpt_clksel,
+			 OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
+			 OMAP24XX_CLKSEL_GPT4_MASK,
+			 OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+			 OMAP24XX_EN_GPT4_SHIFT, &clkhwops_wait,
+			 gpt10_fck_parent_names, dss1_fck_ops);
+
+static struct clk gpt4_ick;
+
+static struct clk_hw_omap gpt4_ick_hw = {
+	.hw = {
+		.clk = &gpt4_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_GPT4_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(gpt4_ick, aes_ick_parent_names, aes_ick_ops);
+
+DEFINE_CLK_OMAP_MUX_GATE(gpt5_fck, "core_l4_clkdm", omap24xx_gpt_clksel,
+			 OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
+			 OMAP24XX_CLKSEL_GPT5_MASK,
+			 OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+			 OMAP24XX_EN_GPT5_SHIFT, &clkhwops_wait,
+			 gpt10_fck_parent_names, dss1_fck_ops);
+
+static struct clk gpt5_ick;
+
+static struct clk_hw_omap gpt5_ick_hw = {
+	.hw = {
+		.clk = &gpt5_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_GPT5_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(gpt5_ick, aes_ick_parent_names, aes_ick_ops);
+
+DEFINE_CLK_OMAP_MUX_GATE(gpt6_fck, "core_l4_clkdm", omap24xx_gpt_clksel,
+			 OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
+			 OMAP24XX_CLKSEL_GPT6_MASK,
+			 OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+			 OMAP24XX_EN_GPT6_SHIFT, &clkhwops_wait,
+			 gpt10_fck_parent_names, dss1_fck_ops);
+
+static struct clk gpt6_ick;
+
+static struct clk_hw_omap gpt6_ick_hw = {
+	.hw = {
+		.clk = &gpt6_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_GPT6_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(gpt6_ick, aes_ick_parent_names, aes_ick_ops);
+
+DEFINE_CLK_OMAP_MUX_GATE(gpt7_fck, "core_l4_clkdm", omap24xx_gpt_clksel,
+			 OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
+			 OMAP24XX_CLKSEL_GPT7_MASK,
+			 OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+			 OMAP24XX_EN_GPT7_SHIFT, &clkhwops_wait,
+			 gpt10_fck_parent_names, dss1_fck_ops);
+
+static struct clk gpt7_ick;
+
+static struct clk_hw_omap gpt7_ick_hw = {
+	.hw = {
+		.clk = &gpt7_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_GPT7_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(gpt7_ick, aes_ick_parent_names, aes_ick_ops);
+
+static struct clk gpt8_fck;
+
+DEFINE_CLK_OMAP_MUX_GATE(gpt8_fck, "core_l4_clkdm", omap24xx_gpt_clksel,
+			 OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
+			 OMAP24XX_CLKSEL_GPT8_MASK,
+			 OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+			 OMAP24XX_EN_GPT8_SHIFT, &clkhwops_wait,
+			 gpt10_fck_parent_names, dss1_fck_ops);
+
+static struct clk gpt8_ick;
+
+static struct clk_hw_omap gpt8_ick_hw = {
+	.hw = {
+		.clk = &gpt8_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_GPT8_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(gpt8_ick, aes_ick_parent_names, aes_ick_ops);
+
+DEFINE_CLK_OMAP_MUX_GATE(gpt9_fck, "core_l4_clkdm", omap24xx_gpt_clksel,
+			 OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
+			 OMAP24XX_CLKSEL_GPT9_MASK,
+			 OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+			 OMAP24XX_EN_GPT9_SHIFT, &clkhwops_wait,
+			 gpt10_fck_parent_names, dss1_fck_ops);
+
+static struct clk gpt9_ick;
+
+static struct clk_hw_omap gpt9_ick_hw = {
+	.hw = {
+		.clk = &gpt9_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_GPT9_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(gpt9_ick, aes_ick_parent_names, aes_ick_ops);
+
+static struct clk hdq_fck;
+
+static struct clk_hw_omap hdq_fck_hw = {
+	.hw = {
+		.clk = &hdq_fck,
+	},
+	.ops		= &clkhwops_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP24XX_EN_HDQ_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(hdq_fck, fac_fck_parent_names, aes_ick_ops);
+
+static struct clk hdq_ick;
+
+static struct clk_hw_omap hdq_ick_hw = {
+	.hw = {
+		.clk = &hdq_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_HDQ_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(hdq_ick, aes_ick_parent_names, aes_ick_ops);
+
+static struct clk i2c1_ick;
+
+static struct clk_hw_omap i2c1_ick_hw = {
+	.hw = {
+		.clk = &i2c1_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP2420_EN_I2C1_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(i2c1_ick, aes_ick_parent_names, aes_ick_ops);
+
+static struct clk i2c2_ick;
+
+static struct clk_hw_omap i2c2_ick_hw = {
+	.hw = {
+		.clk = &i2c2_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP2420_EN_I2C2_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(i2c2_ick, aes_ick_parent_names, aes_ick_ops);
+
+static struct clk i2chs1_fck;
+
+static struct clk_hw_omap i2chs1_fck_hw = {
+	.hw = {
+		.clk = &i2chs1_fck,
+	},
+	.ops		= &clkhwops_omap2430_i2chs_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
+	.enable_bit	= OMAP2430_EN_I2CHS1_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(i2chs1_fck, cam_fck_parent_names, aes_ick_ops);
+
+static struct clk i2chs2_fck;
+
+static struct clk_hw_omap i2chs2_fck_hw = {
+	.hw = {
+		.clk = &i2chs2_fck,
+	},
+	.ops		= &clkhwops_omap2430_i2chs_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
+	.enable_bit	= OMAP2430_EN_I2CHS2_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(i2chs2_fck, cam_fck_parent_names, aes_ick_ops);
+
+static struct clk icr_ick;
+
+static struct clk_hw_omap icr_ick_hw = {
+	.hw = {
+		.clk = &icr_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP2430_EN_ICR_SHIFT,
+	.clkdm_name	= "wkup_clkdm",
+};
+
+DEFINE_STRUCT_CLK(icr_ick, gpios_ick_parent_names, aes_ick_ops);
+
+static const struct clksel dsp_ick_clksel[] = {
+	{ .parent = &dsp_fck, .rates = dsp_ick_rates },
+	{ .parent = NULL },
+};
+
+static const char *iva2_1_ick_parent_names[] = {
+	"dsp_fck",
+};
+
+DEFINE_CLK_OMAP_MUX_GATE(iva2_1_ick, "dsp_clkdm", dsp_ick_clksel,
+			 OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_CLKSEL),
+			 OMAP24XX_CLKSEL_DSP_IF_MASK,
+			 OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_FCLKEN),
+			 OMAP24XX_CM_FCLKEN_DSP_EN_DSP_SHIFT, &clkhwops_wait,
+			 iva2_1_ick_parent_names, dsp_fck_ops);
+
+static struct clk mailboxes_ick;
+
+static struct clk_hw_omap mailboxes_ick_hw = {
+	.hw = {
+		.clk = &mailboxes_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_MAILBOXES_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(mailboxes_ick, aes_ick_parent_names, aes_ick_ops);
+
+static const struct clksel_rate common_mcbsp_96m_rates[] = {
+	{ .div = 1, .val = 0, .flags = RATE_IN_24XX },
+	{ .div = 0 }
+};
+
+static const struct clksel_rate common_mcbsp_mcbsp_rates[] = {
+	{ .div = 1, .val = 1, .flags = RATE_IN_24XX },
+	{ .div = 0 }
+};
+
+static const struct clksel mcbsp_fck_clksel[] = {
+	{ .parent = &func_96m_ck, .rates = common_mcbsp_96m_rates },
+	{ .parent = &mcbsp_clks, .rates = common_mcbsp_mcbsp_rates },
+	{ .parent = NULL },
+};
+
+static const char *mcbsp1_fck_parent_names[] = {
+	"func_96m_ck", "mcbsp_clks",
+};
+
+DEFINE_CLK_OMAP_MUX_GATE(mcbsp1_fck, "core_l4_clkdm", mcbsp_fck_clksel,
+			 OMAP243X_CTRL_REGADDR(OMAP2_CONTROL_DEVCONF0),
+			 OMAP2_MCBSP1_CLKS_MASK,
+			 OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+			 OMAP24XX_EN_MCBSP1_SHIFT, &clkhwops_wait,
+			 mcbsp1_fck_parent_names, dss1_fck_ops);
+
+static struct clk mcbsp1_ick;
+
+static struct clk_hw_omap mcbsp1_ick_hw = {
+	.hw = {
+		.clk = &mcbsp1_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_MCBSP1_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(mcbsp1_ick, aes_ick_parent_names, aes_ick_ops);
+
+DEFINE_CLK_OMAP_MUX_GATE(mcbsp2_fck, "core_l4_clkdm", mcbsp_fck_clksel,
+			 OMAP243X_CTRL_REGADDR(OMAP2_CONTROL_DEVCONF0),
+			 OMAP2_MCBSP2_CLKS_MASK,
+			 OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+			 OMAP24XX_EN_MCBSP2_SHIFT, &clkhwops_wait,
+			 mcbsp1_fck_parent_names, dss1_fck_ops);
+
+static struct clk mcbsp2_ick;
+
+static struct clk_hw_omap mcbsp2_ick_hw = {
+	.hw = {
+		.clk = &mcbsp2_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_MCBSP2_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(mcbsp2_ick, aes_ick_parent_names, aes_ick_ops);
+
+DEFINE_CLK_OMAP_MUX_GATE(mcbsp3_fck, "core_l4_clkdm", mcbsp_fck_clksel,
+			 OMAP243X_CTRL_REGADDR(OMAP243X_CONTROL_DEVCONF1),
+			 OMAP2_MCBSP3_CLKS_MASK,
+			 OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
+			 OMAP2430_EN_MCBSP3_SHIFT, &clkhwops_wait,
+			 mcbsp1_fck_parent_names, dss1_fck_ops);
+
+static struct clk mcbsp3_ick;
+
+static struct clk_hw_omap mcbsp3_ick_hw = {
+	.hw = {
+		.clk = &mcbsp3_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
+	.enable_bit	= OMAP2430_EN_MCBSP3_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(mcbsp3_ick, aes_ick_parent_names, aes_ick_ops);
+
+DEFINE_CLK_OMAP_MUX_GATE(mcbsp4_fck, "core_l4_clkdm", mcbsp_fck_clksel,
+			 OMAP243X_CTRL_REGADDR(OMAP243X_CONTROL_DEVCONF1),
+			 OMAP2_MCBSP4_CLKS_MASK,
+			 OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
+			 OMAP2430_EN_MCBSP4_SHIFT, &clkhwops_wait,
+			 mcbsp1_fck_parent_names, dss1_fck_ops);
+
+static struct clk mcbsp4_ick;
+
+static struct clk_hw_omap mcbsp4_ick_hw = {
+	.hw = {
+		.clk = &mcbsp4_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
+	.enable_bit	= OMAP2430_EN_MCBSP4_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(mcbsp4_ick, aes_ick_parent_names, aes_ick_ops);
+
+DEFINE_CLK_OMAP_MUX_GATE(mcbsp5_fck, "core_l4_clkdm", mcbsp_fck_clksel,
+			 OMAP243X_CTRL_REGADDR(OMAP243X_CONTROL_DEVCONF1),
+			 OMAP2_MCBSP5_CLKS_MASK,
+			 OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
+			 OMAP2430_EN_MCBSP5_SHIFT, &clkhwops_wait,
+			 mcbsp1_fck_parent_names, dss1_fck_ops);
+
+static struct clk mcbsp5_ick;
+
+static struct clk_hw_omap mcbsp5_ick_hw = {
+	.hw = {
+		.clk = &mcbsp5_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
+	.enable_bit	= OMAP2430_EN_MCBSP5_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(mcbsp5_ick, aes_ick_parent_names, aes_ick_ops);
+
+static struct clk mcspi1_fck;
+
+static const char *mcspi1_fck_parent_names[] = {
+	"func_48m_ck",
+};
+
+static struct clk_hw_omap mcspi1_fck_hw = {
+	.hw = {
+		.clk = &mcspi1_fck,
+	},
+	.ops		= &clkhwops_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP24XX_EN_MCSPI1_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(mcspi1_fck, mcspi1_fck_parent_names, aes_ick_ops);
+
+static struct clk mcspi1_ick;
+
+static struct clk_hw_omap mcspi1_ick_hw = {
+	.hw = {
+		.clk = &mcspi1_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_MCSPI1_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(mcspi1_ick, aes_ick_parent_names, aes_ick_ops);
+
+static struct clk mcspi2_fck;
+
+static struct clk_hw_omap mcspi2_fck_hw = {
+	.hw = {
+		.clk = &mcspi2_fck,
+	},
+	.ops		= &clkhwops_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP24XX_EN_MCSPI2_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(mcspi2_fck, mcspi1_fck_parent_names, aes_ick_ops);
+
+static struct clk mcspi2_ick;
+
+static struct clk_hw_omap mcspi2_ick_hw = {
+	.hw = {
+		.clk = &mcspi2_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_MCSPI2_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(mcspi2_ick, aes_ick_parent_names, aes_ick_ops);
+
+static struct clk mcspi3_fck;
+
+static struct clk_hw_omap mcspi3_fck_hw = {
+	.hw = {
+		.clk = &mcspi3_fck,
+	},
+	.ops		= &clkhwops_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
+	.enable_bit	= OMAP2430_EN_MCSPI3_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(mcspi3_fck, mcspi1_fck_parent_names, aes_ick_ops);
+
+static struct clk mcspi3_ick;
+
+static struct clk_hw_omap mcspi3_ick_hw = {
+	.hw = {
+		.clk = &mcspi3_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
+	.enable_bit	= OMAP2430_EN_MCSPI3_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(mcspi3_ick, aes_ick_parent_names, aes_ick_ops);
+
+static const struct clksel_rate mdm_ick_core_rates[] = {
+	{ .div = 1, .val = 1, .flags = RATE_IN_243X },
+	{ .div = 4, .val = 4, .flags = RATE_IN_243X },
+	{ .div = 6, .val = 6, .flags = RATE_IN_243X },
+	{ .div = 9, .val = 9, .flags = RATE_IN_243X },
+	{ .div = 0 }
+};
+
+static const struct clksel mdm_ick_clksel[] = {
+	{ .parent = &core_ck, .rates = mdm_ick_core_rates },
+	{ .parent = NULL },
+};
+
+static const char *mdm_ick_parent_names[] = {
+	"core_ck",
+};
+
+DEFINE_CLK_OMAP_MUX_GATE(mdm_ick, "mdm_clkdm", mdm_ick_clksel,
+			 OMAP_CM_REGADDR(OMAP2430_MDM_MOD, CM_CLKSEL),
+			 OMAP2430_CLKSEL_MDM_MASK,
+			 OMAP_CM_REGADDR(OMAP2430_MDM_MOD, CM_ICLKEN),
+			 OMAP2430_CM_ICLKEN_MDM_EN_MDM_SHIFT,
+			 &clkhwops_iclk_wait, mdm_ick_parent_names,
+			 dsp_fck_ops);
+
+static struct clk mdm_intc_ick;
+
+static struct clk_hw_omap mdm_intc_ick_hw = {
+	.hw = {
+		.clk = &mdm_intc_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
+	.enable_bit	= OMAP2430_EN_MDM_INTC_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(mdm_intc_ick, aes_ick_parent_names, aes_ick_ops);
+
+static struct clk mdm_osc_ck;
+
+static struct clk_hw_omap mdm_osc_ck_hw = {
+	.hw = {
+		.clk = &mdm_osc_ck,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP2430_MDM_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP2430_EN_OSC_SHIFT,
+	.clkdm_name	= "mdm_clkdm",
+};
+
+DEFINE_STRUCT_CLK(mdm_osc_ck, sys_ck_parent_names, aes_ick_ops);
+
+static struct clk mmchs1_fck;
+
+static struct clk_hw_omap mmchs1_fck_hw = {
+	.hw = {
+		.clk = &mmchs1_fck,
+	},
+	.ops		= &clkhwops_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
+	.enable_bit	= OMAP2430_EN_MMCHS1_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(mmchs1_fck, cam_fck_parent_names, aes_ick_ops);
+
+static struct clk mmchs1_ick;
+
+static struct clk_hw_omap mmchs1_ick_hw = {
+	.hw = {
+		.clk = &mmchs1_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
+	.enable_bit	= OMAP2430_EN_MMCHS1_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(mmchs1_ick, aes_ick_parent_names, aes_ick_ops);
+
+static struct clk mmchs2_fck;
+
+static struct clk_hw_omap mmchs2_fck_hw = {
+	.hw = {
+		.clk = &mmchs2_fck,
+	},
+	.ops		= &clkhwops_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
+	.enable_bit	= OMAP2430_EN_MMCHS2_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(mmchs2_fck, cam_fck_parent_names, aes_ick_ops);
+
+static struct clk mmchs2_ick;
+
+static struct clk_hw_omap mmchs2_ick_hw = {
+	.hw = {
+		.clk = &mmchs2_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
+	.enable_bit	= OMAP2430_EN_MMCHS2_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(mmchs2_ick, aes_ick_parent_names, aes_ick_ops);
+
+static struct clk mmchsdb1_fck;
+
+static struct clk_hw_omap mmchsdb1_fck_hw = {
+	.hw = {
+		.clk = &mmchsdb1_fck,
+	},
+	.ops		= &clkhwops_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
+	.enable_bit	= OMAP2430_EN_MMCHSDB1_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(mmchsdb1_fck, gpio5_fck_parent_names, aes_ick_ops);
+
+static struct clk mmchsdb2_fck;
+
+static struct clk_hw_omap mmchsdb2_fck_hw = {
+	.hw = {
+		.clk = &mmchsdb2_fck,
+	},
+	.ops		= &clkhwops_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
+	.enable_bit	= OMAP2430_EN_MMCHSDB2_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(mmchsdb2_fck, gpio5_fck_parent_names, aes_ick_ops);
+
+DEFINE_CLK_DIVIDER(mpu_ck, "core_ck", &core_ck, 0x0,
+		   OMAP_CM_REGADDR(MPU_MOD, CM_CLKSEL),
+		   OMAP24XX_CLKSEL_MPU_SHIFT, OMAP24XX_CLKSEL_MPU_WIDTH,
+		   CLK_DIVIDER_ONE_BASED, NULL);
+
+static struct clk mpu_wdt_fck;
+
+static struct clk_hw_omap mpu_wdt_fck_hw = {
+	.hw = {
+		.clk = &mpu_wdt_fck,
+	},
+	.ops		= &clkhwops_wait,
+	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP24XX_EN_MPU_WDT_SHIFT,
+	.clkdm_name	= "wkup_clkdm",
+};
+
+DEFINE_STRUCT_CLK(mpu_wdt_fck, gpio5_fck_parent_names, aes_ick_ops);
+
+static struct clk mpu_wdt_ick;
+
+static struct clk_hw_omap mpu_wdt_ick_hw = {
+	.hw = {
+		.clk = &mpu_wdt_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP24XX_EN_MPU_WDT_SHIFT,
+	.clkdm_name	= "wkup_clkdm",
+};
+
+DEFINE_STRUCT_CLK(mpu_wdt_ick, gpios_ick_parent_names, aes_ick_ops);
+
+static struct clk mspro_fck;
+
+static struct clk_hw_omap mspro_fck_hw = {
+	.hw = {
+		.clk = &mspro_fck,
+	},
+	.ops		= &clkhwops_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP24XX_EN_MSPRO_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(mspro_fck, cam_fck_parent_names, aes_ick_ops);
+
+static struct clk mspro_ick;
+
+static struct clk_hw_omap mspro_ick_hw = {
+	.hw = {
+		.clk = &mspro_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_MSPRO_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(mspro_ick, aes_ick_parent_names, aes_ick_ops);
+
+static struct clk omapctrl_ick;
+
+static struct clk_hw_omap omapctrl_ick_hw = {
+	.hw = {
+		.clk = &omapctrl_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP24XX_EN_OMAPCTRL_SHIFT,
+	.flags		= ENABLE_ON_INIT,
+	.clkdm_name	= "wkup_clkdm",
+};
+
+DEFINE_STRUCT_CLK(omapctrl_ick, gpios_ick_parent_names, aes_ick_ops);
+
+static struct clk pka_ick;
+
+static struct clk_hw_omap pka_ick_hw = {
+	.hw = {
+		.clk = &pka_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_ICLKEN4),
+	.enable_bit	= OMAP24XX_EN_PKA_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(pka_ick, aes_ick_parent_names, aes_ick_ops);
+
+static struct clk rng_ick;
+
+static struct clk_hw_omap rng_ick_hw = {
+	.hw = {
+		.clk = &rng_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_ICLKEN4),
+	.enable_bit	= OMAP24XX_EN_RNG_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(rng_ick, aes_ick_parent_names, aes_ick_ops);
+
+static struct clk sdma_fck;
+
+DEFINE_STRUCT_CLK_HW_OMAP(sdma_fck, "core_l3_clkdm");
+DEFINE_STRUCT_CLK(sdma_fck, gfx_ick_parent_names, core_ck_ops);
+
+static struct clk sdma_ick;
+
+static struct clk_hw_omap sdma_ick_hw = {
+	.hw = {
+		.clk = &sdma_ick,
+	},
+	.ops		= &clkhwops_iclk,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN3),
+	.enable_bit	= OMAP24XX_AUTO_SDMA_SHIFT,
+	.clkdm_name	= "core_l3_clkdm",
+};
+
+DEFINE_STRUCT_CLK(sdma_ick, gfx_ick_parent_names, core_ck_ops);
+
+static struct clk sdrc_ick;
+
+static struct clk_hw_omap sdrc_ick_hw = {
+	.hw = {
+		.clk = &sdrc_ick,
+	},
+	.ops		= &clkhwops_iclk,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN3),
+	.enable_bit	= OMAP2430_EN_SDRC_SHIFT,
+	.flags		= ENABLE_ON_INIT,
+	.clkdm_name	= "core_l3_clkdm",
+};
+
+DEFINE_STRUCT_CLK(sdrc_ick, gfx_ick_parent_names, core_ck_ops);
+
+static struct clk sha_ick;
+
+static struct clk_hw_omap sha_ick_hw = {
+	.hw = {
+		.clk = &sha_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_ICLKEN4),
+	.enable_bit	= OMAP24XX_EN_SHA_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(sha_ick, aes_ick_parent_names, aes_ick_ops);
+
+static struct clk ssi_l4_ick;
+
+static struct clk_hw_omap ssi_l4_ick_hw = {
+	.hw = {
+		.clk = &ssi_l4_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
+	.enable_bit	= OMAP24XX_EN_SSI_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(ssi_l4_ick, aes_ick_parent_names, aes_ick_ops);
+
+static const struct clksel_rate ssi_ssr_sst_fck_core_rates[] = {
+	{ .div = 1, .val = 1, .flags = RATE_IN_24XX },
+	{ .div = 2, .val = 2, .flags = RATE_IN_24XX },
+	{ .div = 3, .val = 3, .flags = RATE_IN_24XX },
+	{ .div = 4, .val = 4, .flags = RATE_IN_24XX },
+	{ .div = 5, .val = 5, .flags = RATE_IN_243X },
+	{ .div = 0 }
+};
+
+static const struct clksel ssi_ssr_sst_fck_clksel[] = {
+	{ .parent = &core_ck, .rates = ssi_ssr_sst_fck_core_rates },
+	{ .parent = NULL },
+};
+
+static const char *ssi_ssr_sst_fck_parent_names[] = {
+	"core_ck",
+};
+
+DEFINE_CLK_OMAP_MUX_GATE(ssi_ssr_sst_fck, "core_l3_clkdm",
+			 ssi_ssr_sst_fck_clksel,
+			 OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1),
+			 OMAP24XX_CLKSEL_SSI_MASK,
+			 OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
+			 OMAP24XX_EN_SSI_SHIFT, &clkhwops_wait,
+			 ssi_ssr_sst_fck_parent_names, dsp_fck_ops);
+
+static struct clk sync_32k_ick;
+
+static struct clk_hw_omap sync_32k_ick_hw = {
+	.hw = {
+		.clk = &sync_32k_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP24XX_EN_32KSYNC_SHIFT,
+	.flags		= ENABLE_ON_INIT,
+	.clkdm_name	= "wkup_clkdm",
+};
+
+DEFINE_STRUCT_CLK(sync_32k_ick, gpios_ick_parent_names, aes_ick_ops);
+
+static const struct clksel_rate common_clkout_src_core_rates[] = {
+	{ .div = 1, .val = 0, .flags = RATE_IN_24XX },
+	{ .div = 0 }
+};
+
+static const struct clksel_rate common_clkout_src_sys_rates[] = {
+	{ .div = 1, .val = 1, .flags = RATE_IN_24XX },
+	{ .div = 0 }
+};
+
+static const struct clksel_rate common_clkout_src_96m_rates[] = {
+	{ .div = 1, .val = 2, .flags = RATE_IN_24XX },
+	{ .div = 0 }
+};
+
+static const struct clksel_rate common_clkout_src_54m_rates[] = {
+	{ .div = 1, .val = 3, .flags = RATE_IN_24XX },
+	{ .div = 0 }
+};
+
+static const struct clksel common_clkout_src_clksel[] = {
+	{ .parent = &core_ck, .rates = common_clkout_src_core_rates },
+	{ .parent = &sys_ck, .rates = common_clkout_src_sys_rates },
+	{ .parent = &func_96m_ck, .rates = common_clkout_src_96m_rates },
+	{ .parent = &func_54m_ck, .rates = common_clkout_src_54m_rates },
+	{ .parent = NULL },
+};
+
+static const char *sys_clkout_src_parent_names[] = {
+	"core_ck", "sys_ck", "func_96m_ck", "func_54m_ck",
+};
+
+DEFINE_CLK_OMAP_MUX_GATE(sys_clkout_src, "wkup_clkdm", common_clkout_src_clksel,
+			 OMAP2430_PRCM_CLKOUT_CTRL, OMAP24XX_CLKOUT_SOURCE_MASK,
+			 OMAP2430_PRCM_CLKOUT_CTRL, OMAP24XX_CLKOUT_EN_SHIFT,
+			 NULL, sys_clkout_src_parent_names, gpt1_fck_ops);
+
+DEFINE_CLK_DIVIDER(sys_clkout, "sys_clkout_src", &sys_clkout_src, 0x0,
+		   OMAP2430_PRCM_CLKOUT_CTRL, OMAP24XX_CLKOUT_DIV_SHIFT,
+		   OMAP24XX_CLKOUT_DIV_WIDTH, CLK_DIVIDER_POWER_OF_TWO, NULL);
+
+static struct clk uart1_fck;
+
+static struct clk_hw_omap uart1_fck_hw = {
+	.hw = {
+		.clk = &uart1_fck,
+	},
+	.ops		= &clkhwops_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP24XX_EN_UART1_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(uart1_fck, mcspi1_fck_parent_names, aes_ick_ops);
+
+static struct clk uart1_ick;
+
+static struct clk_hw_omap uart1_ick_hw = {
+	.hw = {
+		.clk = &uart1_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_UART1_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(uart1_ick, aes_ick_parent_names, aes_ick_ops);
+
+static struct clk uart2_fck;
+
+static struct clk_hw_omap uart2_fck_hw = {
+	.hw = {
+		.clk = &uart2_fck,
+	},
+	.ops		= &clkhwops_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP24XX_EN_UART2_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(uart2_fck, mcspi1_fck_parent_names, aes_ick_ops);
+
+static struct clk uart2_ick;
+
+static struct clk_hw_omap uart2_ick_hw = {
+	.hw = {
+		.clk = &uart2_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_UART2_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(uart2_ick, aes_ick_parent_names, aes_ick_ops);
+
+static struct clk uart3_fck;
+
+static struct clk_hw_omap uart3_fck_hw = {
+	.hw = {
+		.clk = &uart3_fck,
+	},
+	.ops		= &clkhwops_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
+	.enable_bit	= OMAP24XX_EN_UART3_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(uart3_fck, mcspi1_fck_parent_names, aes_ick_ops);
+
+static struct clk uart3_ick;
+
+static struct clk_hw_omap uart3_ick_hw = {
+	.hw = {
+		.clk = &uart3_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
+	.enable_bit	= OMAP24XX_EN_UART3_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(uart3_ick, aes_ick_parent_names, aes_ick_ops);
+
+static struct clk usb_fck;
+
+static struct clk_hw_omap usb_fck_hw = {
+	.hw = {
+		.clk = &usb_fck,
+	},
+	.ops		= &clkhwops_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
+	.enable_bit	= OMAP24XX_EN_USB_SHIFT,
+	.clkdm_name	= "core_l3_clkdm",
+};
+
+DEFINE_STRUCT_CLK(usb_fck, mcspi1_fck_parent_names, aes_ick_ops);
+
+static const struct clksel_rate usb_l4_ick_core_l3_rates[] = {
+	{ .div = 1, .val = 1, .flags = RATE_IN_24XX },
+	{ .div = 2, .val = 2, .flags = RATE_IN_24XX },
+	{ .div = 4, .val = 4, .flags = RATE_IN_24XX },
+	{ .div = 0 }
+};
+
+static const struct clksel usb_l4_ick_clksel[] = {
+	{ .parent = &core_l3_ck, .rates = usb_l4_ick_core_l3_rates },
+	{ .parent = NULL },
+};
+
+static const char *usb_l4_ick_parent_names[] = {
+	"core_l3_ck",
+};
+
+DEFINE_CLK_OMAP_MUX_GATE(usb_l4_ick, "core_l4_clkdm", usb_l4_ick_clksel,
+			 OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1),
+			 OMAP24XX_CLKSEL_USB_MASK,
+			 OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
+			 OMAP24XX_EN_USB_SHIFT, &clkhwops_iclk_wait,
+			 usb_l4_ick_parent_names, dsp_fck_ops);
+
+static struct clk usbhs_ick;
+
+static struct clk_hw_omap usbhs_ick_hw = {
+	.hw = {
+		.clk = &usbhs_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
+	.enable_bit	= OMAP2430_EN_USBHS_SHIFT,
+	.clkdm_name	= "core_l3_clkdm",
+};
+
+DEFINE_STRUCT_CLK(usbhs_ick, gfx_ick_parent_names, aes_ick_ops);
+
+static struct clk virt_prcm_set;
+
+static const char *virt_prcm_set_parent_names[] = {
+	"mpu_ck",
+};
+
+static const struct clk_ops virt_prcm_set_ops = {
+	.recalc_rate	= &omap2_table_mpu_recalc,
+	.set_rate	= &omap2_select_table_rate,
+	.round_rate	= &omap2_round_to_table_rate,
+};
+
+DEFINE_STRUCT_CLK_HW_OMAP(virt_prcm_set, NULL);
+DEFINE_STRUCT_CLK(virt_prcm_set, virt_prcm_set_parent_names, virt_prcm_set_ops);
+
+static struct clk wdt1_ick;
+
+static struct clk_hw_omap wdt1_ick_hw = {
+	.hw = {
+		.clk = &wdt1_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP24XX_EN_WDT1_SHIFT,
+	.clkdm_name	= "wkup_clkdm",
+};
+
+DEFINE_STRUCT_CLK(wdt1_ick, gpios_ick_parent_names, aes_ick_ops);
+
+static struct clk wdt1_osc_ck;
+
+static const struct clk_ops wdt1_osc_ck_ops = {};
+
+DEFINE_STRUCT_CLK_HW_OMAP(wdt1_osc_ck, NULL);
+DEFINE_STRUCT_CLK(wdt1_osc_ck, sys_ck_parent_names, wdt1_osc_ck_ops);
+
+static struct clk wdt4_fck;
+
+static struct clk_hw_omap wdt4_fck_hw = {
+	.hw = {
+		.clk = &wdt4_fck,
+	},
+	.ops		= &clkhwops_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP24XX_EN_WDT4_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(wdt4_fck, gpio5_fck_parent_names, aes_ick_ops);
+
+static struct clk wdt4_ick;
+
+static struct clk_hw_omap wdt4_ick_hw = {
+	.hw = {
+		.clk = &wdt4_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP24XX_EN_WDT4_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(wdt4_ick, aes_ick_parent_names, aes_ick_ops);
+
+/*
+ * clkdev integration
+ */
+
+static struct omap_clk omap2430_clks[] = {
+	/* external root sources */
+	CLK(NULL,	"func_32k_ck",	&func_32k_ck,	CK_243X),
+	CLK(NULL,	"secure_32k_ck", &secure_32k_ck, CK_243X),
+	CLK(NULL,	"osc_ck",	&osc_ck,	CK_243X),
+	CLK("twl",	"fck",		&osc_ck,	CK_243X),
+	CLK(NULL,	"sys_ck",	&sys_ck,	CK_243X),
+	CLK(NULL,	"alt_ck",	&alt_ck,	CK_243X),
+	CLK(NULL,	"mcbsp_clks",	&mcbsp_clks,	CK_243X),
+	/* internal analog sources */
+	CLK(NULL,	"dpll_ck",	&dpll_ck,	CK_243X),
+	CLK(NULL,	"apll96_ck",	&apll96_ck,	CK_243X),
+	CLK(NULL,	"apll54_ck",	&apll54_ck,	CK_243X),
+	/* internal prcm root sources */
+	CLK(NULL,	"func_54m_ck",	&func_54m_ck,	CK_243X),
+	CLK(NULL,	"core_ck",	&core_ck,	CK_243X),
+	CLK(NULL,	"func_96m_ck",	&func_96m_ck,	CK_243X),
+	CLK(NULL,	"func_48m_ck",	&func_48m_ck,	CK_243X),
+	CLK(NULL,	"func_12m_ck",	&func_12m_ck,	CK_243X),
+	CLK(NULL,	"ck_wdt1_osc",	&wdt1_osc_ck,	CK_243X),
+	CLK(NULL,	"sys_clkout_src", &sys_clkout_src, CK_243X),
+	CLK(NULL,	"sys_clkout",	&sys_clkout,	CK_243X),
+	CLK(NULL,	"emul_ck",	&emul_ck,	CK_243X),
+	/* mpu domain clocks */
+	CLK(NULL,	"mpu_ck",	&mpu_ck,	CK_243X),
+	/* dsp domain clocks */
+	CLK(NULL,	"dsp_fck",	&dsp_fck,	CK_243X),
+	CLK(NULL,	"iva2_1_ick",	&iva2_1_ick,	CK_243X),
+	/* GFX domain clocks */
+	CLK(NULL,	"gfx_3d_fck",	&gfx_3d_fck,	CK_243X),
+	CLK(NULL,	"gfx_2d_fck",	&gfx_2d_fck,	CK_243X),
+	CLK(NULL,	"gfx_ick",	&gfx_ick,	CK_243X),
+	/* Modem domain clocks */
+	CLK(NULL,	"mdm_ick",	&mdm_ick,	CK_243X),
+	CLK(NULL,	"mdm_osc_ck",	&mdm_osc_ck,	CK_243X),
+	/* DSS domain clocks */
+	CLK("omapdss_dss",	"ick",		&dss_ick,	CK_243X),
+	CLK(NULL,	"dss_ick",		&dss_ick,	CK_243X),
+	CLK(NULL,	"dss1_fck",		&dss1_fck,	CK_243X),
+	CLK(NULL,	"dss2_fck",	&dss2_fck,	CK_243X),
+	CLK(NULL,	"dss_54m_fck",	&dss_54m_fck,	CK_243X),
+	/* L3 domain clocks */
+	CLK(NULL,	"core_l3_ck",	&core_l3_ck,	CK_243X),
+	CLK(NULL,	"ssi_fck",	&ssi_ssr_sst_fck, CK_243X),
+	CLK(NULL,	"usb_l4_ick",	&usb_l4_ick,	CK_243X),
+	/* L4 domain clocks */
+	CLK(NULL,	"l4_ck",	&l4_ck,		CK_243X),
+	CLK(NULL,	"ssi_l4_ick",	&ssi_l4_ick,	CK_243X),
+	CLK(NULL,	"wu_l4_ick",	&wu_l4_ick,	CK_243X),
+	/* virtual meta-group clock */
+	CLK(NULL,	"virt_prcm_set", &virt_prcm_set, CK_243X),
+	/* general l4 interface ck, multi-parent functional clk */
+	CLK(NULL,	"gpt1_ick",	&gpt1_ick,	CK_243X),
+	CLK(NULL,	"gpt1_fck",	&gpt1_fck,	CK_243X),
+	CLK(NULL,	"gpt2_ick",	&gpt2_ick,	CK_243X),
+	CLK(NULL,	"gpt2_fck",	&gpt2_fck,	CK_243X),
+	CLK(NULL,	"gpt3_ick",	&gpt3_ick,	CK_243X),
+	CLK(NULL,	"gpt3_fck",	&gpt3_fck,	CK_243X),
+	CLK(NULL,	"gpt4_ick",	&gpt4_ick,	CK_243X),
+	CLK(NULL,	"gpt4_fck",	&gpt4_fck,	CK_243X),
+	CLK(NULL,	"gpt5_ick",	&gpt5_ick,	CK_243X),
+	CLK(NULL,	"gpt5_fck",	&gpt5_fck,	CK_243X),
+	CLK(NULL,	"gpt6_ick",	&gpt6_ick,	CK_243X),
+	CLK(NULL,	"gpt6_fck",	&gpt6_fck,	CK_243X),
+	CLK(NULL,	"gpt7_ick",	&gpt7_ick,	CK_243X),
+	CLK(NULL,	"gpt7_fck",	&gpt7_fck,	CK_243X),
+	CLK(NULL,	"gpt8_ick",	&gpt8_ick,	CK_243X),
+	CLK(NULL,	"gpt8_fck",	&gpt8_fck,	CK_243X),
+	CLK(NULL,	"gpt9_ick",	&gpt9_ick,	CK_243X),
+	CLK(NULL,	"gpt9_fck",	&gpt9_fck,	CK_243X),
+	CLK(NULL,	"gpt10_ick",	&gpt10_ick,	CK_243X),
+	CLK(NULL,	"gpt10_fck",	&gpt10_fck,	CK_243X),
+	CLK(NULL,	"gpt11_ick",	&gpt11_ick,	CK_243X),
+	CLK(NULL,	"gpt11_fck",	&gpt11_fck,	CK_243X),
+	CLK(NULL,	"gpt12_ick",	&gpt12_ick,	CK_243X),
+	CLK(NULL,	"gpt12_fck",	&gpt12_fck,	CK_243X),
+	CLK("omap-mcbsp.1", "ick",	&mcbsp1_ick,	CK_243X),
+	CLK(NULL,	"mcbsp1_ick",	&mcbsp1_ick,	CK_243X),
+	CLK(NULL,	"mcbsp1_fck",	&mcbsp1_fck,	CK_243X),
+	CLK("omap-mcbsp.2", "ick",	&mcbsp2_ick,	CK_243X),
+	CLK(NULL,	"mcbsp2_ick",	&mcbsp2_ick,	CK_243X),
+	CLK(NULL,	"mcbsp2_fck",	&mcbsp2_fck,	CK_243X),
+	CLK("omap-mcbsp.3", "ick",	&mcbsp3_ick,	CK_243X),
+	CLK(NULL,	"mcbsp3_ick",	&mcbsp3_ick,	CK_243X),
+	CLK(NULL,	"mcbsp3_fck",	&mcbsp3_fck,	CK_243X),
+	CLK("omap-mcbsp.4", "ick",	&mcbsp4_ick,	CK_243X),
+	CLK(NULL,	"mcbsp4_ick",	&mcbsp4_ick,	CK_243X),
+	CLK(NULL,	"mcbsp4_fck",	&mcbsp4_fck,	CK_243X),
+	CLK("omap-mcbsp.5", "ick",	&mcbsp5_ick,	CK_243X),
+	CLK(NULL,	"mcbsp5_ick",	&mcbsp5_ick,	CK_243X),
+	CLK(NULL,	"mcbsp5_fck",	&mcbsp5_fck,	CK_243X),
+	CLK("omap2_mcspi.1", "ick",	&mcspi1_ick,	CK_243X),
+	CLK(NULL,	"mcspi1_ick",	&mcspi1_ick,	CK_243X),
+	CLK(NULL,	"mcspi1_fck",	&mcspi1_fck,	CK_243X),
+	CLK("omap2_mcspi.2", "ick",	&mcspi2_ick,	CK_243X),
+	CLK(NULL,	"mcspi2_ick",	&mcspi2_ick,	CK_243X),
+	CLK(NULL,	"mcspi2_fck",	&mcspi2_fck,	CK_243X),
+	CLK("omap2_mcspi.3", "ick",	&mcspi3_ick,	CK_243X),
+	CLK(NULL,	"mcspi3_ick",	&mcspi3_ick,	CK_243X),
+	CLK(NULL,	"mcspi3_fck",	&mcspi3_fck,	CK_243X),
+	CLK(NULL,	"uart1_ick",	&uart1_ick,	CK_243X),
+	CLK(NULL,	"uart1_fck",	&uart1_fck,	CK_243X),
+	CLK(NULL,	"uart2_ick",	&uart2_ick,	CK_243X),
+	CLK(NULL,	"uart2_fck",	&uart2_fck,	CK_243X),
+	CLK(NULL,	"uart3_ick",	&uart3_ick,	CK_243X),
+	CLK(NULL,	"uart3_fck",	&uart3_fck,	CK_243X),
+	CLK(NULL,	"gpios_ick",	&gpios_ick,	CK_243X),
+	CLK(NULL,	"gpios_fck",	&gpios_fck,	CK_243X),
+	CLK("omap_wdt",	"ick",		&mpu_wdt_ick,	CK_243X),
+	CLK(NULL,	"mpu_wdt_ick",	&mpu_wdt_ick,	CK_243X),
+	CLK(NULL,	"mpu_wdt_fck",	&mpu_wdt_fck,	CK_243X),
+	CLK(NULL,	"sync_32k_ick",	&sync_32k_ick,	CK_243X),
+	CLK(NULL,	"wdt1_ick",	&wdt1_ick,	CK_243X),
+	CLK(NULL,	"omapctrl_ick",	&omapctrl_ick,	CK_243X),
+	CLK(NULL,	"icr_ick",	&icr_ick,	CK_243X),
+	CLK("omap24xxcam", "fck",	&cam_fck,	CK_243X),
+	CLK(NULL,	"cam_fck",	&cam_fck,	CK_243X),
+	CLK("omap24xxcam", "ick",	&cam_ick,	CK_243X),
+	CLK(NULL,	"cam_ick",	&cam_ick,	CK_243X),
+	CLK(NULL,	"mailboxes_ick", &mailboxes_ick,	CK_243X),
+	CLK(NULL,	"wdt4_ick",	&wdt4_ick,	CK_243X),
+	CLK(NULL,	"wdt4_fck",	&wdt4_fck,	CK_243X),
+	CLK(NULL,	"mspro_ick",	&mspro_ick,	CK_243X),
+	CLK(NULL,	"mspro_fck",	&mspro_fck,	CK_243X),
+	CLK(NULL,	"fac_ick",	&fac_ick,	CK_243X),
+	CLK(NULL,	"fac_fck",	&fac_fck,	CK_243X),
+	CLK("omap_hdq.0", "ick",	&hdq_ick,	CK_243X),
+	CLK(NULL,	"hdq_ick",	&hdq_ick,	CK_243X),
+	CLK("omap_hdq.1", "fck",	&hdq_fck,	CK_243X),
+	CLK(NULL,	"hdq_fck",	&hdq_fck,	CK_243X),
+	CLK("omap_i2c.1", "ick",	&i2c1_ick,	CK_243X),
+	CLK(NULL,	"i2c1_ick",	&i2c1_ick,	CK_243X),
+	CLK(NULL,	"i2chs1_fck",	&i2chs1_fck,	CK_243X),
+	CLK("omap_i2c.2", "ick",	&i2c2_ick,	CK_243X),
+	CLK(NULL,	"i2c2_ick",	&i2c2_ick,	CK_243X),
+	CLK(NULL,	"i2chs2_fck",	&i2chs2_fck,	CK_243X),
+	CLK(NULL,	"gpmc_fck",	&gpmc_fck,	CK_243X),
+	CLK(NULL,	"sdma_fck",	&sdma_fck,	CK_243X),
+	CLK(NULL,	"sdma_ick",	&sdma_ick,	CK_243X),
+	CLK(NULL,	"sdrc_ick",	&sdrc_ick,	CK_243X),
+	CLK(NULL,	"des_ick",	&des_ick,	CK_243X),
+	CLK("omap-sham",	"ick",	&sha_ick,	CK_243X),
+	CLK("omap_rng",	"ick",		&rng_ick,	CK_243X),
+	CLK(NULL,	"rng_ick",	&rng_ick,	CK_243X),
+	CLK("omap-aes",	"ick",	&aes_ick,	CK_243X),
+	CLK(NULL,	"pka_ick",	&pka_ick,	CK_243X),
+	CLK(NULL,	"usb_fck",	&usb_fck,	CK_243X),
+	CLK("musb-omap2430",	"ick",	&usbhs_ick,	CK_243X),
+	CLK(NULL,	"usbhs_ick",	&usbhs_ick,	CK_243X),
+	CLK("omap_hsmmc.0", "ick",	&mmchs1_ick,	CK_243X),
+	CLK(NULL,	"mmchs1_ick",	&mmchs1_ick,	CK_243X),
+	CLK(NULL,	"mmchs1_fck",	&mmchs1_fck,	CK_243X),
+	CLK("omap_hsmmc.1", "ick",	&mmchs2_ick,	CK_243X),
+	CLK(NULL,	"mmchs2_ick",	&mmchs2_ick,	CK_243X),
+	CLK(NULL,	"mmchs2_fck",	&mmchs2_fck,	CK_243X),
+	CLK(NULL,	"gpio5_ick",	&gpio5_ick,	CK_243X),
+	CLK(NULL,	"gpio5_fck",	&gpio5_fck,	CK_243X),
+	CLK(NULL,	"mdm_intc_ick",	&mdm_intc_ick,	CK_243X),
+	CLK("omap_hsmmc.0", "mmchsdb_fck",	&mmchsdb1_fck,	CK_243X),
+	CLK(NULL,	 "mmchsdb1_fck",	&mmchsdb1_fck,	CK_243X),
+	CLK("omap_hsmmc.1", "mmchsdb_fck",	&mmchsdb2_fck,	CK_243X),
+	CLK(NULL,	 "mmchsdb2_fck",	&mmchsdb2_fck,	CK_243X),
+	CLK(NULL,	"timer_32k_ck",  &func_32k_ck,   CK_243X),
+	CLK(NULL,	"timer_sys_ck",	&sys_ck,	CK_243X),
+	CLK(NULL,	"timer_ext_ck",	&alt_ck,	CK_243X),
+	CLK(NULL,	"cpufreq_ck",	&virt_prcm_set,	CK_243X),
+};
+
+static const char *enable_init_clks[] = {
+	"apll96_ck",
+	"apll54_ck",
+	"sync_32k_ick",
+	"omapctrl_ick",
+	"gpmc_fck",
+	"sdrc_ick",
+};
+
+/*
+ * init code
+ */
+
+int __init omap2430_clk_init(void)
+{
+	struct omap_clk *c;
+
+	prcm_clksrc_ctrl = OMAP2430_PRCM_CLKSRC_CTRL;
+	cpu_mask = RATE_IN_243X;
+	rate_table = omap2430_rate_table;
+
+	omap2xxx_clkt_dpllcore_init(&dpll_ck_hw.hw);
+
+	omap2xxx_clkt_vps_check_bootloader_rates();
+
+	for (c = omap2430_clks; c < omap2430_clks + ARRAY_SIZE(omap2430_clks);
+	     c++) {
+		clkdev_add(&c->lk);
+		if (!__clk_init(NULL, c->lk.clk))
+			omap2_init_clk_hw_omap_clocks(c->lk.clk);
+	}
+
+	omap2_clk_disable_autoidle_all();
+
+	omap2_clk_enable_init_clocks(enable_init_clks,
+				     ARRAY_SIZE(enable_init_clks));
+
+	pr_info("Clocking rate (Crystal/DPLL/MPU): %ld.%01ld/%ld/%ld MHz\n",
+		(clk_get_rate(&sys_ck) / 1000000),
+		(clk_get_rate(&sys_ck) / 100000) % 10,
+		(clk_get_rate(&dpll_ck) / 1000000),
+		(clk_get_rate(&mpu_ck) / 1000000));
+
+	return 0;
+}
diff --git a/arch/arm/mach-omap2/cclock33xx_data.c b/arch/arm/mach-omap2/cclock33xx_data.c
new file mode 100644
index 0000000..ea64ad60
--- /dev/null
+++ b/arch/arm/mach-omap2/cclock33xx_data.c
@@ -0,0 +1,961 @@
+/*
+ * AM33XX Clock data
+ *
+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
+ * Vaibhav Hiremath <hvaibhav@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/list.h>
+#include <linux/clk-private.h>
+#include <linux/clkdev.h>
+#include <linux/io.h>
+
+#include "am33xx.h"
+#include "soc.h"
+#include "iomap.h"
+#include "clock.h"
+#include "control.h"
+#include "cm.h"
+#include "cm33xx.h"
+#include "cm-regbits-33xx.h"
+#include "prm.h"
+
+/* Modulemode control */
+#define AM33XX_MODULEMODE_HWCTRL_SHIFT		0
+#define AM33XX_MODULEMODE_SWCTRL_SHIFT		1
+
+/*LIST_HEAD(clocks);*/
+
+/* Root clocks */
+
+/* RTC 32k */
+DEFINE_CLK_FIXED_RATE(clk_32768_ck, CLK_IS_ROOT, 32768, 0x0);
+
+/* On-Chip 32KHz RC OSC */
+DEFINE_CLK_FIXED_RATE(clk_rc32k_ck, CLK_IS_ROOT, 32000, 0x0);
+
+/* Crystal input clks */
+DEFINE_CLK_FIXED_RATE(virt_19200000_ck, CLK_IS_ROOT, 19200000, 0x0);
+
+DEFINE_CLK_FIXED_RATE(virt_24000000_ck, CLK_IS_ROOT, 24000000, 0x0);
+
+DEFINE_CLK_FIXED_RATE(virt_25000000_ck, CLK_IS_ROOT, 25000000, 0x0);
+
+DEFINE_CLK_FIXED_RATE(virt_26000000_ck, CLK_IS_ROOT, 26000000, 0x0);
+
+/* Oscillator clock */
+/* 19.2, 24, 25 or 26 MHz */
+static const char *sys_clkin_ck_parents[] = {
+	"virt_19200000_ck", "virt_24000000_ck", "virt_25000000_ck",
+	"virt_26000000_ck",
+};
+
+/*
+ * sys_clk in: input to the dpll and also used as funtional clock for,
+ *   adc_tsc, smartreflex0-1, timer1-7, mcasp0-1, dcan0-1, cefuse
+ *
+ */
+DEFINE_CLK_MUX(sys_clkin_ck, sys_clkin_ck_parents, NULL, 0x0,
+	       AM33XX_CTRL_REGADDR(AM33XX_CONTROL_STATUS),
+	       AM33XX_CONTROL_STATUS_SYSBOOT1_SHIFT,
+	       AM33XX_CONTROL_STATUS_SYSBOOT1_WIDTH,
+	       0, NULL);
+
+/* External clock - 12 MHz */
+DEFINE_CLK_FIXED_RATE(tclkin_ck, CLK_IS_ROOT, 12000000, 0x0);
+
+/* Module clocks and DPLL outputs */
+
+/* DPLL_CORE */
+static struct dpll_data dpll_core_dd = {
+	.mult_div1_reg	= AM33XX_CM_CLKSEL_DPLL_CORE,
+	.clk_bypass	= &sys_clkin_ck,
+	.clk_ref	= &sys_clkin_ck,
+	.control_reg	= AM33XX_CM_CLKMODE_DPLL_CORE,
+	.modes		= (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
+	.idlest_reg	= AM33XX_CM_IDLEST_DPLL_CORE,
+	.mult_mask	= AM33XX_DPLL_MULT_MASK,
+	.div1_mask	= AM33XX_DPLL_DIV_MASK,
+	.enable_mask	= AM33XX_DPLL_EN_MASK,
+	.idlest_mask	= AM33XX_ST_DPLL_CLK_MASK,
+	.max_multiplier	= 2047,
+	.max_divider	= 128,
+	.min_divider	= 1,
+};
+
+/* CLKDCOLDO output */
+static const char *dpll_core_ck_parents[] = {
+	"sys_clkin_ck",
+};
+
+static struct clk dpll_core_ck;
+
+static const struct clk_ops dpll_core_ck_ops = {
+	.recalc_rate	= &omap3_dpll_recalc,
+	.get_parent	= &omap2_init_dpll_parent,
+};
+
+static struct clk_hw_omap dpll_core_ck_hw = {
+	.hw	= {
+		.clk	= &dpll_core_ck,
+	},
+	.dpll_data	= &dpll_core_dd,
+	.ops		= &clkhwops_omap3_dpll,
+};
+
+DEFINE_STRUCT_CLK(dpll_core_ck, dpll_core_ck_parents, dpll_core_ck_ops);
+
+static const char *dpll_core_x2_ck_parents[] = {
+	"dpll_core_ck",
+};
+
+static struct clk dpll_core_x2_ck;
+
+static const struct clk_ops dpll_x2_ck_ops = {
+	.recalc_rate	= &omap3_clkoutx2_recalc,
+};
+
+static struct clk_hw_omap dpll_core_x2_ck_hw = {
+	.hw	= {
+		.clk	= &dpll_core_x2_ck,
+	},
+	.flags		= CLOCK_CLKOUTX2,
+};
+
+DEFINE_STRUCT_CLK(dpll_core_x2_ck, dpll_core_x2_ck_parents, dpll_x2_ck_ops);
+
+DEFINE_CLK_DIVIDER(dpll_core_m4_ck, "dpll_core_x2_ck", &dpll_core_x2_ck,
+		   0x0, AM33XX_CM_DIV_M4_DPLL_CORE,
+		   AM33XX_HSDIVIDER_CLKOUT1_DIV_SHIFT,
+		   AM33XX_HSDIVIDER_CLKOUT1_DIV_WIDTH, CLK_DIVIDER_ONE_BASED,
+		   NULL);
+
+DEFINE_CLK_DIVIDER(dpll_core_m5_ck, "dpll_core_x2_ck", &dpll_core_x2_ck,
+		   0x0, AM33XX_CM_DIV_M5_DPLL_CORE,
+		   AM33XX_HSDIVIDER_CLKOUT2_DIV_SHIFT,
+		   AM33XX_HSDIVIDER_CLKOUT2_DIV_WIDTH,
+		   CLK_DIVIDER_ONE_BASED, NULL);
+
+DEFINE_CLK_DIVIDER(dpll_core_m6_ck, "dpll_core_x2_ck", &dpll_core_x2_ck,
+		   0x0, AM33XX_CM_DIV_M6_DPLL_CORE,
+		   AM33XX_HSDIVIDER_CLKOUT3_DIV_SHIFT,
+		   AM33XX_HSDIVIDER_CLKOUT3_DIV_WIDTH,
+		   CLK_DIVIDER_ONE_BASED, NULL);
+
+
+/* DPLL_MPU */
+static struct dpll_data dpll_mpu_dd = {
+	.mult_div1_reg	= AM33XX_CM_CLKSEL_DPLL_MPU,
+	.clk_bypass	= &sys_clkin_ck,
+	.clk_ref	= &sys_clkin_ck,
+	.control_reg	= AM33XX_CM_CLKMODE_DPLL_MPU,
+	.modes		= (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
+	.idlest_reg	= AM33XX_CM_IDLEST_DPLL_MPU,
+	.mult_mask	= AM33XX_DPLL_MULT_MASK,
+	.div1_mask	= AM33XX_DPLL_DIV_MASK,
+	.enable_mask	= AM33XX_DPLL_EN_MASK,
+	.idlest_mask	= AM33XX_ST_DPLL_CLK_MASK,
+	.max_multiplier	= 2047,
+	.max_divider	= 128,
+	.min_divider	= 1,
+};
+
+/* CLKOUT: fdpll/M2 */
+static struct clk dpll_mpu_ck;
+
+static const struct clk_ops dpll_mpu_ck_ops = {
+	.enable		= &omap3_noncore_dpll_enable,
+	.disable	= &omap3_noncore_dpll_disable,
+	.recalc_rate	= &omap3_dpll_recalc,
+	.round_rate	= &omap2_dpll_round_rate,
+	.set_rate	= &omap3_noncore_dpll_set_rate,
+	.get_parent	= &omap2_init_dpll_parent,
+};
+
+static struct clk_hw_omap dpll_mpu_ck_hw = {
+	.hw = {
+		.clk	= &dpll_mpu_ck,
+	},
+	.dpll_data	= &dpll_mpu_dd,
+	.ops		= &clkhwops_omap3_dpll,
+};
+
+DEFINE_STRUCT_CLK(dpll_mpu_ck, dpll_core_ck_parents, dpll_mpu_ck_ops);
+
+/*
+ * TODO: Add clksel here (sys_clkin, CORE_CLKOUTM6, PER_CLKOUTM2
+ * and ALT_CLK1/2)
+ */
+DEFINE_CLK_DIVIDER(dpll_mpu_m2_ck, "dpll_mpu_ck", &dpll_mpu_ck,
+		   0x0, AM33XX_CM_DIV_M2_DPLL_MPU, AM33XX_DPLL_CLKOUT_DIV_SHIFT,
+		   AM33XX_DPLL_CLKOUT_DIV_WIDTH, CLK_DIVIDER_ONE_BASED, NULL);
+
+/* DPLL_DDR */
+static struct dpll_data dpll_ddr_dd = {
+	.mult_div1_reg	= AM33XX_CM_CLKSEL_DPLL_DDR,
+	.clk_bypass	= &sys_clkin_ck,
+	.clk_ref	= &sys_clkin_ck,
+	.control_reg	= AM33XX_CM_CLKMODE_DPLL_DDR,
+	.modes		= (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
+	.idlest_reg	= AM33XX_CM_IDLEST_DPLL_DDR,
+	.mult_mask	= AM33XX_DPLL_MULT_MASK,
+	.div1_mask	= AM33XX_DPLL_DIV_MASK,
+	.enable_mask	= AM33XX_DPLL_EN_MASK,
+	.idlest_mask	= AM33XX_ST_DPLL_CLK_MASK,
+	.max_multiplier	= 2047,
+	.max_divider	= 128,
+	.min_divider	= 1,
+};
+
+/* CLKOUT: fdpll/M2 */
+static struct clk dpll_ddr_ck;
+
+static const struct clk_ops dpll_ddr_ck_ops = {
+	.recalc_rate	= &omap3_dpll_recalc,
+	.get_parent	= &omap2_init_dpll_parent,
+	.round_rate	= &omap2_dpll_round_rate,
+	.set_rate	= &omap3_noncore_dpll_set_rate,
+};
+
+static struct clk_hw_omap dpll_ddr_ck_hw = {
+	.hw = {
+		.clk	= &dpll_ddr_ck,
+	},
+	.dpll_data	= &dpll_ddr_dd,
+	.ops		= &clkhwops_omap3_dpll,
+};
+
+DEFINE_STRUCT_CLK(dpll_ddr_ck, dpll_core_ck_parents, dpll_ddr_ck_ops);
+
+/*
+ * TODO: Add clksel here (sys_clkin, CORE_CLKOUTM6, PER_CLKOUTM2
+ * and ALT_CLK1/2)
+ */
+DEFINE_CLK_DIVIDER(dpll_ddr_m2_ck, "dpll_ddr_ck", &dpll_ddr_ck,
+		   0x0, AM33XX_CM_DIV_M2_DPLL_DDR,
+		   AM33XX_DPLL_CLKOUT_DIV_SHIFT, AM33XX_DPLL_CLKOUT_DIV_WIDTH,
+		   CLK_DIVIDER_ONE_BASED, NULL);
+
+/* emif_fck functional clock */
+DEFINE_CLK_FIXED_FACTOR(dpll_ddr_m2_div2_ck, "dpll_ddr_m2_ck", &dpll_ddr_m2_ck,
+			0x0, 1, 2);
+
+/* DPLL_DISP */
+static struct dpll_data dpll_disp_dd = {
+	.mult_div1_reg	= AM33XX_CM_CLKSEL_DPLL_DISP,
+	.clk_bypass	= &sys_clkin_ck,
+	.clk_ref	= &sys_clkin_ck,
+	.control_reg	= AM33XX_CM_CLKMODE_DPLL_DISP,
+	.modes		= (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
+	.idlest_reg	= AM33XX_CM_IDLEST_DPLL_DISP,
+	.mult_mask	= AM33XX_DPLL_MULT_MASK,
+	.div1_mask	= AM33XX_DPLL_DIV_MASK,
+	.enable_mask	= AM33XX_DPLL_EN_MASK,
+	.idlest_mask	= AM33XX_ST_DPLL_CLK_MASK,
+	.max_multiplier	= 2047,
+	.max_divider	= 128,
+	.min_divider	= 1,
+};
+
+/* CLKOUT: fdpll/M2 */
+static struct clk dpll_disp_ck;
+
+static struct clk_hw_omap dpll_disp_ck_hw = {
+	.hw = {
+		.clk	= &dpll_disp_ck,
+	},
+	.dpll_data	= &dpll_disp_dd,
+	.ops		= &clkhwops_omap3_dpll,
+};
+
+DEFINE_STRUCT_CLK(dpll_disp_ck, dpll_core_ck_parents, dpll_ddr_ck_ops);
+
+/*
+ * TODO: Add clksel here (sys_clkin, CORE_CLKOUTM6, PER_CLKOUTM2
+ * and ALT_CLK1/2)
+ */
+DEFINE_CLK_DIVIDER(dpll_disp_m2_ck, "dpll_disp_ck", &dpll_disp_ck, 0x0,
+		   AM33XX_CM_DIV_M2_DPLL_DISP, AM33XX_DPLL_CLKOUT_DIV_SHIFT,
+		   AM33XX_DPLL_CLKOUT_DIV_WIDTH, CLK_DIVIDER_ONE_BASED, NULL);
+
+/* DPLL_PER */
+static struct dpll_data dpll_per_dd = {
+	.mult_div1_reg	= AM33XX_CM_CLKSEL_DPLL_PERIPH,
+	.clk_bypass	= &sys_clkin_ck,
+	.clk_ref	= &sys_clkin_ck,
+	.control_reg	= AM33XX_CM_CLKMODE_DPLL_PER,
+	.modes		= (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
+	.idlest_reg	= AM33XX_CM_IDLEST_DPLL_PER,
+	.mult_mask	= AM33XX_DPLL_MULT_PERIPH_MASK,
+	.div1_mask	= AM33XX_DPLL_PER_DIV_MASK,
+	.enable_mask	= AM33XX_DPLL_EN_MASK,
+	.idlest_mask	= AM33XX_ST_DPLL_CLK_MASK,
+	.max_multiplier	= 2047,
+	.max_divider	= 128,
+	.min_divider	= 1,
+	.flags		= DPLL_J_TYPE,
+};
+
+/* CLKDCOLDO */
+static struct clk dpll_per_ck;
+
+static struct clk_hw_omap dpll_per_ck_hw = {
+	.hw	= {
+		.clk	= &dpll_per_ck,
+	},
+	.dpll_data	= &dpll_per_dd,
+	.ops		= &clkhwops_omap3_dpll,
+};
+
+DEFINE_STRUCT_CLK(dpll_per_ck, dpll_core_ck_parents, dpll_ddr_ck_ops);
+
+/* CLKOUT: fdpll/M2 */
+DEFINE_CLK_DIVIDER(dpll_per_m2_ck, "dpll_per_ck", &dpll_per_ck, 0x0,
+		   AM33XX_CM_DIV_M2_DPLL_PER, AM33XX_DPLL_CLKOUT_DIV_SHIFT,
+		   AM33XX_DPLL_CLKOUT_DIV_WIDTH, CLK_DIVIDER_ONE_BASED,
+		   NULL);
+
+DEFINE_CLK_FIXED_FACTOR(dpll_per_m2_div4_wkupdm_ck, "dpll_per_m2_ck",
+			&dpll_per_m2_ck, 0x0, 1, 4);
+
+DEFINE_CLK_FIXED_FACTOR(dpll_per_m2_div4_ck, "dpll_per_m2_ck",
+			&dpll_per_m2_ck, 0x0, 1, 4);
+
+DEFINE_CLK_FIXED_FACTOR(dpll_core_m4_div2_ck, "dpll_core_m4_ck",
+			&dpll_core_m4_ck, 0x0, 1, 2);
+
+DEFINE_CLK_FIXED_FACTOR(l4_rtc_gclk, "dpll_core_m4_ck", &dpll_core_m4_ck, 0x0,
+			1, 2);
+
+DEFINE_CLK_FIXED_FACTOR(clk_24mhz, "dpll_per_m2_ck", &dpll_per_m2_ck, 0x0, 1,
+			8);
+
+/*
+ * Below clock nodes describes clockdomains derived out
+ * of core clock.
+ */
+static const struct clk_ops clk_ops_null = {
+};
+
+static const char *l3_gclk_parents[] = {
+	"dpll_core_m4_ck"
+};
+
+static struct clk l3_gclk;
+DEFINE_STRUCT_CLK_HW_OMAP(l3_gclk, NULL);
+DEFINE_STRUCT_CLK(l3_gclk, l3_gclk_parents, clk_ops_null);
+
+static struct clk l4hs_gclk;
+DEFINE_STRUCT_CLK_HW_OMAP(l4hs_gclk, NULL);
+DEFINE_STRUCT_CLK(l4hs_gclk, l3_gclk_parents, clk_ops_null);
+
+static const char *l3s_gclk_parents[] = {
+	"dpll_core_m4_div2_ck"
+};
+
+static struct clk l3s_gclk;
+DEFINE_STRUCT_CLK_HW_OMAP(l3s_gclk, NULL);
+DEFINE_STRUCT_CLK(l3s_gclk, l3s_gclk_parents, clk_ops_null);
+
+static struct clk l4fw_gclk;
+DEFINE_STRUCT_CLK_HW_OMAP(l4fw_gclk, NULL);
+DEFINE_STRUCT_CLK(l4fw_gclk, l3s_gclk_parents, clk_ops_null);
+
+static struct clk l4ls_gclk;
+DEFINE_STRUCT_CLK_HW_OMAP(l4ls_gclk, NULL);
+DEFINE_STRUCT_CLK(l4ls_gclk, l3s_gclk_parents, clk_ops_null);
+
+static struct clk sysclk_div_ck;
+DEFINE_STRUCT_CLK_HW_OMAP(sysclk_div_ck, NULL);
+DEFINE_STRUCT_CLK(sysclk_div_ck, l3_gclk_parents, clk_ops_null);
+
+/*
+ * In order to match the clock domain with hwmod clockdomain entry,
+ * separate clock nodes is required for the modules which are
+ * directly getting their funtioncal clock from sys_clkin.
+ */
+static struct clk adc_tsc_fck;
+DEFINE_STRUCT_CLK_HW_OMAP(adc_tsc_fck, NULL);
+DEFINE_STRUCT_CLK(adc_tsc_fck, dpll_core_ck_parents, clk_ops_null);
+
+static struct clk dcan0_fck;
+DEFINE_STRUCT_CLK_HW_OMAP(dcan0_fck, NULL);
+DEFINE_STRUCT_CLK(dcan0_fck, dpll_core_ck_parents, clk_ops_null);
+
+static struct clk dcan1_fck;
+DEFINE_STRUCT_CLK_HW_OMAP(dcan1_fck, NULL);
+DEFINE_STRUCT_CLK(dcan1_fck, dpll_core_ck_parents, clk_ops_null);
+
+static struct clk mcasp0_fck;
+DEFINE_STRUCT_CLK_HW_OMAP(mcasp0_fck, NULL);
+DEFINE_STRUCT_CLK(mcasp0_fck, dpll_core_ck_parents, clk_ops_null);
+
+static struct clk mcasp1_fck;
+DEFINE_STRUCT_CLK_HW_OMAP(mcasp1_fck, NULL);
+DEFINE_STRUCT_CLK(mcasp1_fck, dpll_core_ck_parents, clk_ops_null);
+
+static struct clk smartreflex0_fck;
+DEFINE_STRUCT_CLK_HW_OMAP(smartreflex0_fck, NULL);
+DEFINE_STRUCT_CLK(smartreflex0_fck, dpll_core_ck_parents, clk_ops_null);
+
+static struct clk smartreflex1_fck;
+DEFINE_STRUCT_CLK_HW_OMAP(smartreflex1_fck, NULL);
+DEFINE_STRUCT_CLK(smartreflex1_fck, dpll_core_ck_parents, clk_ops_null);
+
+/*
+ * Modules clock nodes
+ *
+ * The following clock leaf nodes are added for the moment because:
+ *
+ *  - hwmod data is not present for these modules, either hwmod
+ *    control is not required or its not populated.
+ *  - Driver code is not yet migrated to use hwmod/runtime pm
+ *  - Modules outside kernel access (to disable them by default)
+ *
+ *     - debugss
+ *     - mmu (gfx domain)
+ *     - cefuse
+ *     - usbotg_fck (its additional clock and not really a modulemode)
+ *     - ieee5000
+ */
+DEFINE_CLK_GATE(debugss_ick, "dpll_core_m4_ck", &dpll_core_m4_ck, 0x0,
+		AM33XX_CM_WKUP_DEBUGSS_CLKCTRL, AM33XX_MODULEMODE_SWCTRL_SHIFT,
+		0x0, NULL);
+
+DEFINE_CLK_GATE(mmu_fck, "dpll_core_m4_ck", &dpll_core_m4_ck, 0x0,
+		AM33XX_CM_GFX_MMUDATA_CLKCTRL, AM33XX_MODULEMODE_SWCTRL_SHIFT,
+		0x0, NULL);
+
+DEFINE_CLK_GATE(cefuse_fck, "sys_clkin_ck", &sys_clkin_ck, 0x0,
+		AM33XX_CM_CEFUSE_CEFUSE_CLKCTRL, AM33XX_MODULEMODE_SWCTRL_SHIFT,
+		0x0, NULL);
+
+/*
+ * clkdiv32 is generated from fixed division of 732.4219
+ */
+DEFINE_CLK_FIXED_FACTOR(clkdiv32k_ck, "clk_24mhz", &clk_24mhz, 0x0, 1, 732);
+
+DEFINE_CLK_GATE(clkdiv32k_ick, "clkdiv32k_ck", &clkdiv32k_ck, 0x0,
+		AM33XX_CM_PER_CLKDIV32K_CLKCTRL, AM33XX_MODULEMODE_SWCTRL_SHIFT,
+		0x0, NULL);
+
+/* "usbotg_fck" is an additional clock and not really a modulemode */
+DEFINE_CLK_GATE(usbotg_fck, "dpll_per_ck", &dpll_per_ck, 0x0,
+		AM33XX_CM_CLKDCOLDO_DPLL_PER, AM33XX_ST_DPLL_CLKDCOLDO_SHIFT,
+		0x0, NULL);
+
+DEFINE_CLK_GATE(ieee5000_fck, "dpll_core_m4_div2_ck", &dpll_core_m4_div2_ck,
+		0x0, AM33XX_CM_PER_IEEE5000_CLKCTRL,
+		AM33XX_MODULEMODE_SWCTRL_SHIFT, 0x0, NULL);
+
+/* Timers */
+static const struct clksel timer1_clkmux_sel[] = {
+	{ .parent = &sys_clkin_ck, .rates = div_1_0_rates },
+	{ .parent = &clkdiv32k_ick, .rates = div_1_1_rates },
+	{ .parent = &tclkin_ck, .rates = div_1_2_rates },
+	{ .parent = &clk_rc32k_ck, .rates = div_1_3_rates },
+	{ .parent = &clk_32768_ck, .rates = div_1_4_rates },
+	{ .parent = NULL },
+};
+
+static const char *timer1_ck_parents[] = {
+	"sys_clkin_ck", "clkdiv32k_ick", "tclkin_ck", "clk_rc32k_ck",
+	"clk_32768_ck",
+};
+
+static struct clk timer1_fck;
+
+static const struct clk_ops timer1_fck_ops = {
+	.recalc_rate	= &omap2_clksel_recalc,
+	.get_parent	= &omap2_clksel_find_parent_index,
+	.set_parent	= &omap2_clksel_set_parent,
+	.init		= &omap2_init_clk_clkdm,
+};
+
+static struct clk_hw_omap timer1_fck_hw = {
+	.hw	= {
+		.clk	= &timer1_fck,
+	},
+	.clkdm_name	= "l4ls_clkdm",
+	.clksel		= timer1_clkmux_sel,
+	.clksel_reg	= AM33XX_CLKSEL_TIMER1MS_CLK,
+	.clksel_mask	= AM33XX_CLKSEL_0_2_MASK,
+};
+
+DEFINE_STRUCT_CLK(timer1_fck, timer1_ck_parents, timer1_fck_ops);
+
+static const struct clksel timer2_to_7_clk_sel[] = {
+	{ .parent = &tclkin_ck, .rates = div_1_0_rates },
+	{ .parent = &sys_clkin_ck, .rates = div_1_1_rates },
+	{ .parent = &clkdiv32k_ick, .rates = div_1_2_rates },
+	{ .parent = NULL },
+};
+
+static const char *timer2_to_7_ck_parents[] = {
+	"tclkin_ck", "sys_clkin_ck", "clkdiv32k_ick",
+};
+
+static struct clk timer2_fck;
+
+static struct clk_hw_omap timer2_fck_hw = {
+	.hw	= {
+		.clk	= &timer2_fck,
+	},
+	.clkdm_name	= "l4ls_clkdm",
+	.clksel		= timer2_to_7_clk_sel,
+	.clksel_reg	= AM33XX_CLKSEL_TIMER2_CLK,
+	.clksel_mask	= AM33XX_CLKSEL_0_1_MASK,
+};
+
+DEFINE_STRUCT_CLK(timer2_fck, timer2_to_7_ck_parents, timer1_fck_ops);
+
+static struct clk timer3_fck;
+
+static struct clk_hw_omap timer3_fck_hw = {
+	.hw	= {
+		.clk	= &timer3_fck,
+	},
+	.clkdm_name	= "l4ls_clkdm",
+	.clksel		= timer2_to_7_clk_sel,
+	.clksel_reg	= AM33XX_CLKSEL_TIMER3_CLK,
+	.clksel_mask	= AM33XX_CLKSEL_0_1_MASK,
+};
+
+DEFINE_STRUCT_CLK(timer3_fck, timer2_to_7_ck_parents, timer1_fck_ops);
+
+static struct clk timer4_fck;
+
+static struct clk_hw_omap timer4_fck_hw = {
+	.hw	= {
+		.clk	= &timer4_fck,
+	},
+	.clkdm_name	= "l4ls_clkdm",
+	.clksel		= timer2_to_7_clk_sel,
+	.clksel_reg	= AM33XX_CLKSEL_TIMER4_CLK,
+	.clksel_mask	= AM33XX_CLKSEL_0_1_MASK,
+};
+
+DEFINE_STRUCT_CLK(timer4_fck, timer2_to_7_ck_parents, timer1_fck_ops);
+
+static struct clk timer5_fck;
+
+static struct clk_hw_omap timer5_fck_hw = {
+	.hw	= {
+		.clk	= &timer5_fck,
+	},
+	.clkdm_name	= "l4ls_clkdm",
+	.clksel		= timer2_to_7_clk_sel,
+	.clksel_reg	= AM33XX_CLKSEL_TIMER5_CLK,
+	.clksel_mask	= AM33XX_CLKSEL_0_1_MASK,
+};
+
+DEFINE_STRUCT_CLK(timer5_fck, timer2_to_7_ck_parents, timer1_fck_ops);
+
+static struct clk timer6_fck;
+
+static struct clk_hw_omap timer6_fck_hw = {
+	.hw	= {
+		.clk	= &timer6_fck,
+	},
+	.clkdm_name	= "l4ls_clkdm",
+	.clksel		= timer2_to_7_clk_sel,
+	.clksel_reg	= AM33XX_CLKSEL_TIMER6_CLK,
+	.clksel_mask	= AM33XX_CLKSEL_0_1_MASK,
+};
+
+DEFINE_STRUCT_CLK(timer6_fck, timer2_to_7_ck_parents, timer1_fck_ops);
+
+static struct clk timer7_fck;
+
+static struct clk_hw_omap timer7_fck_hw = {
+	.hw	= {
+		.clk	= &timer7_fck,
+	},
+	.clkdm_name	= "l4ls_clkdm",
+	.clksel		= timer2_to_7_clk_sel,
+	.clksel_reg	= AM33XX_CLKSEL_TIMER7_CLK,
+	.clksel_mask	= AM33XX_CLKSEL_0_1_MASK,
+};
+
+DEFINE_STRUCT_CLK(timer7_fck, timer2_to_7_ck_parents, timer1_fck_ops);
+
+DEFINE_CLK_FIXED_FACTOR(cpsw_125mhz_gclk,
+			"dpll_core_m5_ck",
+			&dpll_core_m5_ck,
+			0x0,
+			1, 2);
+
+static const struct clk_ops cpsw_fck_ops = {
+	.recalc_rate	= &omap2_clksel_recalc,
+	.get_parent	= &omap2_clksel_find_parent_index,
+	.set_parent	= &omap2_clksel_set_parent,
+};
+
+static const struct clksel cpsw_cpts_rft_clkmux_sel[] = {
+	{ .parent = &dpll_core_m5_ck, .rates = div_1_0_rates },
+	{ .parent = &dpll_core_m4_ck, .rates = div_1_1_rates },
+	{ .parent = NULL },
+};
+
+static const char *cpsw_cpts_rft_ck_parents[] = {
+	"dpll_core_m5_ck", "dpll_core_m4_ck",
+};
+
+static struct clk cpsw_cpts_rft_clk;
+
+static struct clk_hw_omap cpsw_cpts_rft_clk_hw = {
+	.hw	= {
+		.clk	= &cpsw_cpts_rft_clk,
+	},
+	.clkdm_name	= "cpsw_125mhz_clkdm",
+	.clksel		= cpsw_cpts_rft_clkmux_sel,
+	.clksel_reg	= AM33XX_CM_CPTS_RFT_CLKSEL,
+	.clksel_mask	= AM33XX_CLKSEL_0_0_MASK,
+};
+
+DEFINE_STRUCT_CLK(cpsw_cpts_rft_clk, cpsw_cpts_rft_ck_parents, cpsw_fck_ops);
+
+
+/* gpio */
+static const char *gpio0_ck_parents[] = {
+	"clk_rc32k_ck", "clk_32768_ck", "clkdiv32k_ick",
+};
+
+static const struct clksel gpio0_dbclk_mux_sel[] = {
+	{ .parent = &clk_rc32k_ck, .rates = div_1_0_rates },
+	{ .parent = &clk_32768_ck, .rates = div_1_1_rates },
+	{ .parent = &clkdiv32k_ick, .rates = div_1_2_rates },
+	{ .parent = NULL },
+};
+
+static const struct clk_ops gpio_fck_ops = {
+	.recalc_rate	= &omap2_clksel_recalc,
+	.get_parent	= &omap2_clksel_find_parent_index,
+	.set_parent	= &omap2_clksel_set_parent,
+	.init		= &omap2_init_clk_clkdm,
+};
+
+static struct clk gpio0_dbclk_mux_ck;
+
+static struct clk_hw_omap gpio0_dbclk_mux_ck_hw = {
+	.hw	= {
+		.clk	= &gpio0_dbclk_mux_ck,
+	},
+	.clkdm_name	= "l4_wkup_clkdm",
+	.clksel		= gpio0_dbclk_mux_sel,
+	.clksel_reg	= AM33XX_CLKSEL_GPIO0_DBCLK,
+	.clksel_mask	= AM33XX_CLKSEL_0_1_MASK,
+};
+
+DEFINE_STRUCT_CLK(gpio0_dbclk_mux_ck, gpio0_ck_parents, gpio_fck_ops);
+
+DEFINE_CLK_GATE(gpio0_dbclk, "gpio0_dbclk_mux_ck", &gpio0_dbclk_mux_ck, 0x0,
+		AM33XX_CM_WKUP_GPIO0_CLKCTRL,
+		AM33XX_OPTFCLKEN_GPIO0_GDBCLK_SHIFT, 0x0, NULL);
+
+DEFINE_CLK_GATE(gpio1_dbclk, "clkdiv32k_ick", &clkdiv32k_ick, 0x0,
+		AM33XX_CM_PER_GPIO1_CLKCTRL,
+		AM33XX_OPTFCLKEN_GPIO_1_GDBCLK_SHIFT, 0x0, NULL);
+
+DEFINE_CLK_GATE(gpio2_dbclk, "clkdiv32k_ick", &clkdiv32k_ick, 0x0,
+		AM33XX_CM_PER_GPIO2_CLKCTRL,
+		AM33XX_OPTFCLKEN_GPIO_2_GDBCLK_SHIFT, 0x0, NULL);
+
+DEFINE_CLK_GATE(gpio3_dbclk, "clkdiv32k_ick", &clkdiv32k_ick, 0x0,
+		AM33XX_CM_PER_GPIO3_CLKCTRL,
+		AM33XX_OPTFCLKEN_GPIO_3_GDBCLK_SHIFT, 0x0, NULL);
+
+
+static const char *pruss_ck_parents[] = {
+	"l3_gclk", "dpll_disp_m2_ck",
+};
+
+static const struct clksel pruss_ocp_clk_mux_sel[] = {
+	{ .parent = &l3_gclk, .rates = div_1_0_rates },
+	{ .parent = &dpll_disp_m2_ck, .rates = div_1_1_rates },
+	{ .parent = NULL },
+};
+
+static struct clk pruss_ocp_gclk;
+
+static struct clk_hw_omap pruss_ocp_gclk_hw = {
+	.hw	= {
+		.clk	= &pruss_ocp_gclk,
+	},
+	.clkdm_name	= "pruss_ocp_clkdm",
+	.clksel		= pruss_ocp_clk_mux_sel,
+	.clksel_reg	= AM33XX_CLKSEL_PRUSS_OCP_CLK,
+	.clksel_mask	= AM33XX_CLKSEL_0_0_MASK,
+};
+
+DEFINE_STRUCT_CLK(pruss_ocp_gclk, pruss_ck_parents, gpio_fck_ops);
+
+static const char *lcd_ck_parents[] = {
+	"dpll_disp_m2_ck", "dpll_core_m5_ck", "dpll_per_m2_ck",
+};
+
+static const struct clksel lcd_clk_mux_sel[] = {
+	{ .parent = &dpll_disp_m2_ck, .rates = div_1_0_rates },
+	{ .parent = &dpll_core_m5_ck, .rates = div_1_1_rates },
+	{ .parent = &dpll_per_m2_ck, .rates = div_1_2_rates },
+	{ .parent = NULL },
+};
+
+static struct clk lcd_gclk;
+
+static struct clk_hw_omap lcd_gclk_hw = {
+	.hw	= {
+		.clk	= &lcd_gclk,
+	},
+	.clkdm_name	= "lcdc_clkdm",
+	.clksel		= lcd_clk_mux_sel,
+	.clksel_reg	= AM33XX_CLKSEL_LCDC_PIXEL_CLK,
+	.clksel_mask	= AM33XX_CLKSEL_0_1_MASK,
+};
+
+DEFINE_STRUCT_CLK(lcd_gclk, lcd_ck_parents, gpio_fck_ops);
+
+DEFINE_CLK_FIXED_FACTOR(mmc_clk, "dpll_per_m2_ck", &dpll_per_m2_ck, 0x0, 1, 2);
+
+static const char *gfx_ck_parents[] = {
+	"dpll_core_m4_ck", "dpll_per_m2_ck",
+};
+
+static const struct clksel gfx_clksel_sel[] = {
+	{ .parent = &dpll_core_m4_ck, .rates = div_1_0_rates },
+	{ .parent = &dpll_per_m2_ck, .rates = div_1_1_rates },
+	{ .parent = NULL },
+};
+
+static struct clk gfx_fclk_clksel_ck;
+
+static struct clk_hw_omap gfx_fclk_clksel_ck_hw = {
+	.hw	= {
+		.clk	= &gfx_fclk_clksel_ck,
+	},
+	.clksel		= gfx_clksel_sel,
+	.clksel_reg	= AM33XX_CLKSEL_GFX_FCLK,
+	.clksel_mask	= AM33XX_CLKSEL_GFX_FCLK_MASK,
+};
+
+DEFINE_STRUCT_CLK(gfx_fclk_clksel_ck, gfx_ck_parents, gpio_fck_ops);
+
+static const struct clk_div_table div_1_0_2_1_rates[] = {
+	{ .div = 1, .val = 0, },
+	{ .div = 2, .val = 1, },
+	{ .div = 0 },
+};
+
+DEFINE_CLK_DIVIDER_TABLE(gfx_fck_div_ck, "gfx_fclk_clksel_ck",
+			 &gfx_fclk_clksel_ck, 0x0, AM33XX_CLKSEL_GFX_FCLK,
+			 AM33XX_CLKSEL_0_0_SHIFT, AM33XX_CLKSEL_0_0_WIDTH,
+			 0x0, div_1_0_2_1_rates, NULL);
+
+static const char *sysclkout_ck_parents[] = {
+	"clk_32768_ck", "l3_gclk", "dpll_ddr_m2_ck", "dpll_per_m2_ck",
+	"lcd_gclk",
+};
+
+static const struct clksel sysclkout_pre_sel[] = {
+	{ .parent = &clk_32768_ck, .rates = div_1_0_rates },
+	{ .parent = &l3_gclk, .rates = div_1_1_rates },
+	{ .parent = &dpll_ddr_m2_ck, .rates = div_1_2_rates },
+	{ .parent = &dpll_per_m2_ck, .rates = div_1_3_rates },
+	{ .parent = &lcd_gclk, .rates = div_1_4_rates },
+	{ .parent = NULL },
+};
+
+static struct clk sysclkout_pre_ck;
+
+static struct clk_hw_omap sysclkout_pre_ck_hw = {
+	.hw	= {
+		.clk	= &sysclkout_pre_ck,
+	},
+	.clksel		= sysclkout_pre_sel,
+	.clksel_reg	= AM33XX_CM_CLKOUT_CTRL,
+	.clksel_mask	= AM33XX_CLKOUT2SOURCE_MASK,
+};
+
+DEFINE_STRUCT_CLK(sysclkout_pre_ck, sysclkout_ck_parents, gpio_fck_ops);
+
+/* Divide by 8 clock rates with default clock is 1/1*/
+static const struct clk_div_table div8_rates[] = {
+	{ .div = 1, .val = 0, },
+	{ .div = 2, .val = 1, },
+	{ .div = 3, .val = 2, },
+	{ .div = 4, .val = 3, },
+	{ .div = 5, .val = 4, },
+	{ .div = 6, .val = 5, },
+	{ .div = 7, .val = 6, },
+	{ .div = 8, .val = 7, },
+	{ .div = 0 },
+};
+
+DEFINE_CLK_DIVIDER_TABLE(clkout2_div_ck, "sysclkout_pre_ck", &sysclkout_pre_ck,
+			 0x0, AM33XX_CM_CLKOUT_CTRL, AM33XX_CLKOUT2DIV_SHIFT,
+			 AM33XX_CLKOUT2DIV_WIDTH, 0x0, div8_rates, NULL);
+
+DEFINE_CLK_GATE(clkout2_ck, "clkout2_div_ck", &clkout2_div_ck, 0x0,
+		AM33XX_CM_CLKOUT_CTRL, AM33XX_CLKOUT2EN_SHIFT, 0x0, NULL);
+
+static const char *wdt_ck_parents[] = {
+	"clk_rc32k_ck", "clkdiv32k_ick",
+};
+
+static const struct clksel wdt_clkmux_sel[] = {
+	{ .parent = &clk_rc32k_ck, .rates = div_1_0_rates },
+	{ .parent = &clkdiv32k_ick, .rates = div_1_1_rates },
+	{ .parent = NULL },
+};
+
+static struct clk wdt1_fck;
+
+static struct clk_hw_omap wdt1_fck_hw = {
+	.hw	= {
+		.clk	= &wdt1_fck,
+	},
+	.clkdm_name	= "l4_wkup_clkdm",
+	.clksel		= wdt_clkmux_sel,
+	.clksel_reg	= AM33XX_CLKSEL_WDT1_CLK,
+	.clksel_mask	= AM33XX_CLKSEL_0_1_MASK,
+};
+
+DEFINE_STRUCT_CLK(wdt1_fck, wdt_ck_parents, gpio_fck_ops);
+
+/*
+ * clkdev
+ */
+static struct omap_clk am33xx_clks[] = {
+	CLK(NULL,	"clk_32768_ck",		&clk_32768_ck,	CK_AM33XX),
+	CLK(NULL,	"clk_rc32k_ck",		&clk_rc32k_ck,	CK_AM33XX),
+	CLK(NULL,	"virt_19200000_ck",	&virt_19200000_ck,	CK_AM33XX),
+	CLK(NULL,	"virt_24000000_ck",	&virt_24000000_ck,	CK_AM33XX),
+	CLK(NULL,	"virt_25000000_ck",	&virt_25000000_ck,	CK_AM33XX),
+	CLK(NULL,	"virt_26000000_ck",	&virt_26000000_ck,	CK_AM33XX),
+	CLK(NULL,	"sys_clkin_ck",		&sys_clkin_ck,	CK_AM33XX),
+	CLK(NULL,	"tclkin_ck",		&tclkin_ck,	CK_AM33XX),
+	CLK(NULL,	"dpll_core_ck",		&dpll_core_ck,	CK_AM33XX),
+	CLK(NULL,	"dpll_core_x2_ck",	&dpll_core_x2_ck,	CK_AM33XX),
+	CLK(NULL,	"dpll_core_m4_ck",	&dpll_core_m4_ck,	CK_AM33XX),
+	CLK(NULL,	"dpll_core_m5_ck",	&dpll_core_m5_ck,	CK_AM33XX),
+	CLK(NULL,	"dpll_core_m6_ck",	&dpll_core_m6_ck,	CK_AM33XX),
+	CLK(NULL,	"dpll_mpu_ck",		&dpll_mpu_ck,	CK_AM33XX),
+	CLK("cpu0",	NULL,			&dpll_mpu_ck,	CK_AM33XX),
+	CLK(NULL,	"dpll_mpu_m2_ck",	&dpll_mpu_m2_ck,	CK_AM33XX),
+	CLK(NULL,	"dpll_ddr_ck",		&dpll_ddr_ck,	CK_AM33XX),
+	CLK(NULL,	"dpll_ddr_m2_ck",	&dpll_ddr_m2_ck,	CK_AM33XX),
+	CLK(NULL,	"dpll_ddr_m2_div2_ck",	&dpll_ddr_m2_div2_ck,	CK_AM33XX),
+	CLK(NULL,	"dpll_disp_ck",		&dpll_disp_ck,	CK_AM33XX),
+	CLK(NULL,	"dpll_disp_m2_ck",	&dpll_disp_m2_ck,	CK_AM33XX),
+	CLK(NULL,	"dpll_per_ck",		&dpll_per_ck,	CK_AM33XX),
+	CLK(NULL,	"dpll_per_m2_ck",	&dpll_per_m2_ck,	CK_AM33XX),
+	CLK(NULL,	"dpll_per_m2_div4_wkupdm_ck",	&dpll_per_m2_div4_wkupdm_ck,	CK_AM33XX),
+	CLK(NULL,	"dpll_per_m2_div4_ck",	&dpll_per_m2_div4_ck,	CK_AM33XX),
+	CLK(NULL,	"adc_tsc_fck",		&adc_tsc_fck,	CK_AM33XX),
+	CLK(NULL,	"cefuse_fck",		&cefuse_fck,	CK_AM33XX),
+	CLK(NULL,	"clkdiv32k_ck",		&clkdiv32k_ck,	CK_AM33XX),
+	CLK(NULL,	"clkdiv32k_ick",	&clkdiv32k_ick,	CK_AM33XX),
+	CLK(NULL,	"dcan0_fck",		&dcan0_fck,	CK_AM33XX),
+	CLK("481cc000.d_can",	NULL,		&dcan0_fck,	CK_AM33XX),
+	CLK(NULL,	"dcan1_fck",		&dcan1_fck,	CK_AM33XX),
+	CLK("481d0000.d_can",	NULL,		&dcan1_fck,	CK_AM33XX),
+	CLK(NULL,	"debugss_ick",		&debugss_ick,	CK_AM33XX),
+	CLK(NULL,	"pruss_ocp_gclk",	&pruss_ocp_gclk,	CK_AM33XX),
+	CLK(NULL,	"mcasp0_fck",		&mcasp0_fck,	CK_AM33XX),
+	CLK(NULL,	"mcasp1_fck",		&mcasp1_fck,	CK_AM33XX),
+	CLK(NULL,	"mmu_fck",		&mmu_fck,	CK_AM33XX),
+	CLK(NULL,	"smartreflex0_fck",	&smartreflex0_fck,	CK_AM33XX),
+	CLK(NULL,	"smartreflex1_fck",	&smartreflex1_fck,	CK_AM33XX),
+	CLK(NULL,	"timer1_fck",		&timer1_fck,	CK_AM33XX),
+	CLK(NULL,	"timer2_fck",		&timer2_fck,	CK_AM33XX),
+	CLK(NULL,	"timer3_fck",		&timer3_fck,	CK_AM33XX),
+	CLK(NULL,	"timer4_fck",		&timer4_fck,	CK_AM33XX),
+	CLK(NULL,	"timer5_fck",		&timer5_fck,	CK_AM33XX),
+	CLK(NULL,	"timer6_fck",		&timer6_fck,	CK_AM33XX),
+	CLK(NULL,	"timer7_fck",		&timer7_fck,	CK_AM33XX),
+	CLK(NULL,	"usbotg_fck",		&usbotg_fck,	CK_AM33XX),
+	CLK(NULL,	"ieee5000_fck",		&ieee5000_fck,	CK_AM33XX),
+	CLK(NULL,	"wdt1_fck",		&wdt1_fck,	CK_AM33XX),
+	CLK(NULL,	"l4_rtc_gclk",		&l4_rtc_gclk,	CK_AM33XX),
+	CLK(NULL,	"l3_gclk",		&l3_gclk,	CK_AM33XX),
+	CLK(NULL,	"dpll_core_m4_div2_ck",	&dpll_core_m4_div2_ck,	CK_AM33XX),
+	CLK(NULL,	"l4hs_gclk",		&l4hs_gclk,	CK_AM33XX),
+	CLK(NULL,	"l3s_gclk",		&l3s_gclk,	CK_AM33XX),
+	CLK(NULL,	"l4fw_gclk",		&l4fw_gclk,	CK_AM33XX),
+	CLK(NULL,	"l4ls_gclk",		&l4ls_gclk,	CK_AM33XX),
+	CLK(NULL,	"clk_24mhz",		&clk_24mhz,	CK_AM33XX),
+	CLK(NULL,	"sysclk_div_ck",	&sysclk_div_ck,	CK_AM33XX),
+	CLK(NULL,	"cpsw_125mhz_gclk",	&cpsw_125mhz_gclk,	CK_AM33XX),
+	CLK(NULL,	"cpsw_cpts_rft_clk",	&cpsw_cpts_rft_clk,	CK_AM33XX),
+	CLK(NULL,	"gpio0_dbclk_mux_ck",	&gpio0_dbclk_mux_ck,	CK_AM33XX),
+	CLK(NULL,	"gpio0_dbclk",		&gpio0_dbclk,	CK_AM33XX),
+	CLK(NULL,	"gpio1_dbclk",		&gpio1_dbclk,	CK_AM33XX),
+	CLK(NULL,	"gpio2_dbclk",		&gpio2_dbclk,	CK_AM33XX),
+	CLK(NULL,	"gpio3_dbclk",		&gpio3_dbclk,	CK_AM33XX),
+	CLK(NULL,	"lcd_gclk",		&lcd_gclk,	CK_AM33XX),
+	CLK(NULL,	"mmc_clk",		&mmc_clk,	CK_AM33XX),
+	CLK(NULL,	"gfx_fclk_clksel_ck",	&gfx_fclk_clksel_ck,	CK_AM33XX),
+	CLK(NULL,	"gfx_fck_div_ck",	&gfx_fck_div_ck,	CK_AM33XX),
+	CLK(NULL,	"sysclkout_pre_ck",	&sysclkout_pre_ck,	CK_AM33XX),
+	CLK(NULL,	"clkout2_div_ck",	&clkout2_div_ck,	CK_AM33XX),
+	CLK(NULL,	"timer_32k_ck",		&clkdiv32k_ick,	CK_AM33XX),
+	CLK(NULL,	"timer_sys_ck",		&sys_clkin_ck,	CK_AM33XX),
+};
+
+
+static const char *enable_init_clks[] = {
+	"dpll_ddr_m2_ck",
+	"dpll_mpu_m2_ck",
+	"l3_gclk",
+	"l4hs_gclk",
+	"l4fw_gclk",
+	"l4ls_gclk",
+};
+
+int __init am33xx_clk_init(void)
+{
+	struct omap_clk *c;
+	u32 cpu_clkflg;
+
+	if (soc_is_am33xx()) {
+		cpu_mask = RATE_IN_AM33XX;
+		cpu_clkflg = CK_AM33XX;
+	}
+
+	for (c = am33xx_clks; c < am33xx_clks + ARRAY_SIZE(am33xx_clks); c++) {
+		if (c->cpu & cpu_clkflg) {
+			clkdev_add(&c->lk);
+			if (!__clk_init(NULL, c->lk.clk))
+				omap2_init_clk_hw_omap_clocks(c->lk.clk);
+		}
+	}
+
+	omap2_clk_disable_autoidle_all();
+
+	omap2_clk_enable_init_clocks(enable_init_clks,
+				     ARRAY_SIZE(enable_init_clks));
+
+	/* TRM ERRATA: Timer 3 & 6 default parent (TCLKIN) may not be always
+	 *    physically present, in such a case HWMOD enabling of
+	 *    clock would be failure with default parent. And timer
+	 *    probe thinks clock is already enabled, this leads to
+	 *    crash upon accessing timer 3 & 6 registers in probe.
+	 *    Fix by setting parent of both these timers to master
+	 *    oscillator clock.
+	 */
+
+	clk_set_parent(&timer3_fck, &sys_clkin_ck);
+	clk_set_parent(&timer6_fck, &sys_clkin_ck);
+
+	return 0;
+}
diff --git a/arch/arm/mach-omap2/cclock3xxx_data.c b/arch/arm/mach-omap2/cclock3xxx_data.c
new file mode 100644
index 0000000..bdf3948
--- /dev/null
+++ b/arch/arm/mach-omap2/cclock3xxx_data.c
@@ -0,0 +1,3595 @@
+/*
+ * OMAP3 clock data
+ *
+ * Copyright (C) 2007-2012 Texas Instruments, Inc.
+ * Copyright (C) 2007-2011 Nokia Corporation
+ *
+ * Written by Paul Walmsley
+ * Updated to COMMON clk data format by Rajendra Nayak <rnayak@ti.com>
+ * With many device clock fixes by Kevin Hilman and Jouni Högander
+ * DPLL bypass clock support added by Roman Tereshonkov
+ *
+ */
+
+/*
+ * Virtual clocks are introduced as convenient tools.
+ * They are sources for other clocks and not supposed
+ * to be requested from drivers directly.
+ */
+
+#include <linux/kernel.h>
+#include <linux/clk.h>
+#include <linux/clk-private.h>
+#include <linux/list.h>
+#include <linux/io.h>
+
+#include "soc.h"
+#include "iomap.h"
+#include "clock.h"
+#include "clock3xxx.h"
+#include "clock34xx.h"
+#include "clock36xx.h"
+#include "clock3517.h"
+#include "cm3xxx.h"
+#include "cm-regbits-34xx.h"
+#include "prm3xxx.h"
+#include "prm-regbits-34xx.h"
+#include "control.h"
+
+/*
+ * clocks
+ */
+
+#define OMAP_CM_REGADDR		OMAP34XX_CM_REGADDR
+
+/* Maximum DPLL multiplier, divider values for OMAP3 */
+#define OMAP3_MAX_DPLL_MULT		2047
+#define OMAP3630_MAX_JTYPE_DPLL_MULT	4095
+#define OMAP3_MAX_DPLL_DIV		128
+
+DEFINE_CLK_FIXED_RATE(dummy_apb_pclk, CLK_IS_ROOT, 0x0, 0x0);
+
+DEFINE_CLK_FIXED_RATE(mcbsp_clks, CLK_IS_ROOT, 0x0, 0x0);
+
+DEFINE_CLK_FIXED_RATE(omap_32k_fck, CLK_IS_ROOT, 32768, 0x0);
+
+DEFINE_CLK_FIXED_RATE(pclk_ck, CLK_IS_ROOT, 27000000, 0x0);
+
+DEFINE_CLK_FIXED_RATE(rmii_ck, CLK_IS_ROOT, 50000000, 0x0);
+
+DEFINE_CLK_FIXED_RATE(secure_32k_fck, CLK_IS_ROOT, 32768, 0x0);
+
+DEFINE_CLK_FIXED_RATE(sys_altclk, CLK_IS_ROOT, 0x0, 0x0);
+
+DEFINE_CLK_FIXED_RATE(virt_12m_ck, CLK_IS_ROOT, 12000000, 0x0);
+
+DEFINE_CLK_FIXED_RATE(virt_13m_ck, CLK_IS_ROOT, 13000000, 0x0);
+
+DEFINE_CLK_FIXED_RATE(virt_16_8m_ck, CLK_IS_ROOT, 16800000, 0x0);
+
+DEFINE_CLK_FIXED_RATE(virt_19200000_ck, CLK_IS_ROOT, 19200000, 0x0);
+
+DEFINE_CLK_FIXED_RATE(virt_26000000_ck, CLK_IS_ROOT, 26000000, 0x0);
+
+DEFINE_CLK_FIXED_RATE(virt_38_4m_ck, CLK_IS_ROOT, 38400000, 0x0);
+
+static const char *osc_sys_ck_parent_names[] = {
+	"virt_12m_ck", "virt_13m_ck", "virt_19200000_ck", "virt_26000000_ck",
+	"virt_38_4m_ck", "virt_16_8m_ck",
+};
+
+DEFINE_CLK_MUX(osc_sys_ck, osc_sys_ck_parent_names, NULL, 0x0,
+	       OMAP3430_PRM_CLKSEL, OMAP3430_SYS_CLKIN_SEL_SHIFT,
+	       OMAP3430_SYS_CLKIN_SEL_WIDTH, 0x0, NULL);
+
+DEFINE_CLK_DIVIDER(sys_ck, "osc_sys_ck", &osc_sys_ck, 0x0,
+		   OMAP3430_PRM_CLKSRC_CTRL, OMAP_SYSCLKDIV_SHIFT,
+		   OMAP_SYSCLKDIV_WIDTH, CLK_DIVIDER_ONE_BASED, NULL);
+
+static struct dpll_data dpll3_dd = {
+	.mult_div1_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1),
+	.mult_mask	= OMAP3430_CORE_DPLL_MULT_MASK,
+	.div1_mask	= OMAP3430_CORE_DPLL_DIV_MASK,
+	.clk_bypass	= &sys_ck,
+	.clk_ref	= &sys_ck,
+	.freqsel_mask	= OMAP3430_CORE_DPLL_FREQSEL_MASK,
+	.control_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
+	.enable_mask	= OMAP3430_EN_CORE_DPLL_MASK,
+	.auto_recal_bit	= OMAP3430_EN_CORE_DPLL_DRIFTGUARD_SHIFT,
+	.recal_en_bit	= OMAP3430_CORE_DPLL_RECAL_EN_SHIFT,
+	.recal_st_bit	= OMAP3430_CORE_DPLL_ST_SHIFT,
+	.autoidle_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_AUTOIDLE),
+	.autoidle_mask	= OMAP3430_AUTO_CORE_DPLL_MASK,
+	.idlest_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST),
+	.idlest_mask	= OMAP3430_ST_CORE_CLK_MASK,
+	.max_multiplier	= OMAP3_MAX_DPLL_MULT,
+	.min_divider	= 1,
+	.max_divider	= OMAP3_MAX_DPLL_DIV,
+};
+
+static struct clk dpll3_ck;
+
+static const char *dpll3_ck_parent_names[] = {
+	"sys_ck",
+};
+
+static const struct clk_ops dpll3_ck_ops = {
+	.init		= &omap2_init_clk_clkdm,
+	.get_parent	= &omap2_init_dpll_parent,
+	.recalc_rate	= &omap3_dpll_recalc,
+	.round_rate	= &omap2_dpll_round_rate,
+};
+
+static struct clk_hw_omap dpll3_ck_hw = {
+	.hw = {
+		.clk = &dpll3_ck,
+	},
+	.ops		= &clkhwops_omap3_dpll,
+	.dpll_data	= &dpll3_dd,
+	.clkdm_name	= "dpll3_clkdm",
+};
+
+DEFINE_STRUCT_CLK(dpll3_ck, dpll3_ck_parent_names, dpll3_ck_ops);
+
+DEFINE_CLK_DIVIDER(dpll3_m2_ck, "dpll3_ck", &dpll3_ck, 0x0,
+		   OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1),
+		   OMAP3430_CORE_DPLL_CLKOUT_DIV_SHIFT,
+		   OMAP3430_CORE_DPLL_CLKOUT_DIV_WIDTH,
+		   CLK_DIVIDER_ONE_BASED, NULL);
+
+static struct clk core_ck;
+
+static const char *core_ck_parent_names[] = {
+	"dpll3_m2_ck",
+};
+
+static const struct clk_ops core_ck_ops = {};
+
+DEFINE_STRUCT_CLK_HW_OMAP(core_ck, NULL);
+DEFINE_STRUCT_CLK(core_ck, core_ck_parent_names, core_ck_ops);
+
+DEFINE_CLK_DIVIDER(l3_ick, "core_ck", &core_ck, 0x0,
+		   OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL),
+		   OMAP3430_CLKSEL_L3_SHIFT, OMAP3430_CLKSEL_L3_WIDTH,
+		   CLK_DIVIDER_ONE_BASED, NULL);
+
+DEFINE_CLK_DIVIDER(l4_ick, "l3_ick", &l3_ick, 0x0,
+		   OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL),
+		   OMAP3430_CLKSEL_L4_SHIFT, OMAP3430_CLKSEL_L4_WIDTH,
+		   CLK_DIVIDER_ONE_BASED, NULL);
+
+static struct clk security_l4_ick2;
+
+static const char *security_l4_ick2_parent_names[] = {
+	"l4_ick",
+};
+
+DEFINE_STRUCT_CLK_HW_OMAP(security_l4_ick2, NULL);
+DEFINE_STRUCT_CLK(security_l4_ick2, security_l4_ick2_parent_names, core_ck_ops);
+
+static struct clk aes1_ick;
+
+static const char *aes1_ick_parent_names[] = {
+	"security_l4_ick2",
+};
+
+static const struct clk_ops aes1_ick_ops = {
+	.enable		= &omap2_dflt_clk_enable,
+	.disable	= &omap2_dflt_clk_disable,
+	.is_enabled	= &omap2_dflt_clk_is_enabled,
+};
+
+static struct clk_hw_omap aes1_ick_hw = {
+	.hw = {
+		.clk = &aes1_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
+	.enable_bit	= OMAP3430_EN_AES1_SHIFT,
+};
+
+DEFINE_STRUCT_CLK(aes1_ick, aes1_ick_parent_names, aes1_ick_ops);
+
+static struct clk core_l4_ick;
+
+static const struct clk_ops core_l4_ick_ops = {
+	.init		= &omap2_init_clk_clkdm,
+};
+
+DEFINE_STRUCT_CLK_HW_OMAP(core_l4_ick, "core_l4_clkdm");
+DEFINE_STRUCT_CLK(core_l4_ick, security_l4_ick2_parent_names, core_l4_ick_ops);
+
+static struct clk aes2_ick;
+
+static const char *aes2_ick_parent_names[] = {
+	"core_l4_ick",
+};
+
+static const struct clk_ops aes2_ick_ops = {
+	.init		= &omap2_init_clk_clkdm,
+	.enable		= &omap2_dflt_clk_enable,
+	.disable	= &omap2_dflt_clk_disable,
+	.is_enabled	= &omap2_dflt_clk_is_enabled,
+};
+
+static struct clk_hw_omap aes2_ick_hw = {
+	.hw = {
+		.clk = &aes2_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP3430_EN_AES2_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(aes2_ick, aes2_ick_parent_names, aes2_ick_ops);
+
+static struct clk dpll1_fck;
+
+static struct dpll_data dpll1_dd = {
+	.mult_div1_reg	= OMAP_CM_REGADDR(MPU_MOD, OMAP3430_CM_CLKSEL1_PLL),
+	.mult_mask	= OMAP3430_MPU_DPLL_MULT_MASK,
+	.div1_mask	= OMAP3430_MPU_DPLL_DIV_MASK,
+	.clk_bypass	= &dpll1_fck,
+	.clk_ref	= &sys_ck,
+	.freqsel_mask	= OMAP3430_MPU_DPLL_FREQSEL_MASK,
+	.control_reg	= OMAP_CM_REGADDR(MPU_MOD, OMAP3430_CM_CLKEN_PLL),
+	.enable_mask	= OMAP3430_EN_MPU_DPLL_MASK,
+	.modes		= (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
+	.auto_recal_bit	= OMAP3430_EN_MPU_DPLL_DRIFTGUARD_SHIFT,
+	.recal_en_bit	= OMAP3430_MPU_DPLL_RECAL_EN_SHIFT,
+	.recal_st_bit	= OMAP3430_MPU_DPLL_ST_SHIFT,
+	.autoidle_reg	= OMAP_CM_REGADDR(MPU_MOD, OMAP3430_CM_AUTOIDLE_PLL),
+	.autoidle_mask	= OMAP3430_AUTO_MPU_DPLL_MASK,
+	.idlest_reg	= OMAP_CM_REGADDR(MPU_MOD, OMAP3430_CM_IDLEST_PLL),
+	.idlest_mask	= OMAP3430_ST_MPU_CLK_MASK,
+	.max_multiplier	= OMAP3_MAX_DPLL_MULT,
+	.min_divider	= 1,
+	.max_divider	= OMAP3_MAX_DPLL_DIV,
+};
+
+static struct clk dpll1_ck;
+
+static const struct clk_ops dpll1_ck_ops = {
+	.init		= &omap2_init_clk_clkdm,
+	.enable		= &omap3_noncore_dpll_enable,
+	.disable	= &omap3_noncore_dpll_disable,
+	.get_parent	= &omap2_init_dpll_parent,
+	.recalc_rate	= &omap3_dpll_recalc,
+	.set_rate	= &omap3_noncore_dpll_set_rate,
+	.round_rate	= &omap2_dpll_round_rate,
+};
+
+static struct clk_hw_omap dpll1_ck_hw = {
+	.hw = {
+		.clk = &dpll1_ck,
+	},
+	.ops		= &clkhwops_omap3_dpll,
+	.dpll_data	= &dpll1_dd,
+	.clkdm_name	= "dpll1_clkdm",
+};
+
+DEFINE_STRUCT_CLK(dpll1_ck, dpll3_ck_parent_names, dpll1_ck_ops);
+
+DEFINE_CLK_FIXED_FACTOR(dpll1_x2_ck, "dpll1_ck", &dpll1_ck, 0x0, 2, 1);
+
+DEFINE_CLK_DIVIDER(dpll1_x2m2_ck, "dpll1_x2_ck", &dpll1_x2_ck, 0x0,
+		   OMAP_CM_REGADDR(MPU_MOD, OMAP3430_CM_CLKSEL2_PLL),
+		   OMAP3430_MPU_DPLL_CLKOUT_DIV_SHIFT,
+		   OMAP3430_MPU_DPLL_CLKOUT_DIV_WIDTH,
+		   CLK_DIVIDER_ONE_BASED, NULL);
+
+static struct clk mpu_ck;
+
+static const char *mpu_ck_parent_names[] = {
+	"dpll1_x2m2_ck",
+};
+
+DEFINE_STRUCT_CLK_HW_OMAP(mpu_ck, "mpu_clkdm");
+DEFINE_STRUCT_CLK(mpu_ck, mpu_ck_parent_names, core_l4_ick_ops);
+
+DEFINE_CLK_DIVIDER(arm_fck, "mpu_ck", &mpu_ck, 0x0,
+		   OMAP_CM_REGADDR(MPU_MOD, OMAP3430_CM_IDLEST_PLL),
+		   OMAP3430_ST_MPU_CLK_SHIFT, OMAP3430_ST_MPU_CLK_WIDTH,
+		   0x0, NULL);
+
+static struct clk cam_ick;
+
+static struct clk_hw_omap cam_ick_hw = {
+	.hw = {
+		.clk = &cam_ick,
+	},
+	.ops		= &clkhwops_iclk,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_CAM_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP3430_EN_CAM_SHIFT,
+	.clkdm_name	= "cam_clkdm",
+};
+
+DEFINE_STRUCT_CLK(cam_ick, security_l4_ick2_parent_names, aes2_ick_ops);
+
+/* DPLL4 */
+/* Supplies 96MHz, 54Mhz TV DAC, DSS fclk, CAM sensor clock, emul trace clk */
+/* Type: DPLL */
+static struct dpll_data dpll4_dd;
+
+static struct dpll_data dpll4_dd_34xx __initdata = {
+	.mult_div1_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL2),
+	.mult_mask	= OMAP3430_PERIPH_DPLL_MULT_MASK,
+	.div1_mask	= OMAP3430_PERIPH_DPLL_DIV_MASK,
+	.clk_bypass	= &sys_ck,
+	.clk_ref	= &sys_ck,
+	.freqsel_mask	= OMAP3430_PERIPH_DPLL_FREQSEL_MASK,
+	.control_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
+	.enable_mask	= OMAP3430_EN_PERIPH_DPLL_MASK,
+	.modes		= (1 << DPLL_LOW_POWER_STOP) | (1 << DPLL_LOCKED),
+	.auto_recal_bit	= OMAP3430_EN_PERIPH_DPLL_DRIFTGUARD_SHIFT,
+	.recal_en_bit	= OMAP3430_PERIPH_DPLL_RECAL_EN_SHIFT,
+	.recal_st_bit	= OMAP3430_PERIPH_DPLL_ST_SHIFT,
+	.autoidle_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_AUTOIDLE),
+	.autoidle_mask	= OMAP3430_AUTO_PERIPH_DPLL_MASK,
+	.idlest_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST),
+	.idlest_mask	= OMAP3430_ST_PERIPH_CLK_MASK,
+	.max_multiplier = OMAP3_MAX_DPLL_MULT,
+	.min_divider	= 1,
+	.max_divider	= OMAP3_MAX_DPLL_DIV,
+};
+
+static struct dpll_data dpll4_dd_3630 __initdata = {
+	.mult_div1_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL2),
+	.mult_mask	= OMAP3630_PERIPH_DPLL_MULT_MASK,
+	.div1_mask	= OMAP3430_PERIPH_DPLL_DIV_MASK,
+	.clk_bypass	= &sys_ck,
+	.clk_ref	= &sys_ck,
+	.control_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
+	.enable_mask	= OMAP3430_EN_PERIPH_DPLL_MASK,
+	.modes		= (1 << DPLL_LOW_POWER_STOP) | (1 << DPLL_LOCKED),
+	.auto_recal_bit	= OMAP3430_EN_PERIPH_DPLL_DRIFTGUARD_SHIFT,
+	.recal_en_bit	= OMAP3430_PERIPH_DPLL_RECAL_EN_SHIFT,
+	.recal_st_bit	= OMAP3430_PERIPH_DPLL_ST_SHIFT,
+	.autoidle_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_AUTOIDLE),
+	.autoidle_mask	= OMAP3430_AUTO_PERIPH_DPLL_MASK,
+	.idlest_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST),
+	.idlest_mask	= OMAP3430_ST_PERIPH_CLK_MASK,
+	.dco_mask	= OMAP3630_PERIPH_DPLL_DCO_SEL_MASK,
+	.sddiv_mask	= OMAP3630_PERIPH_DPLL_SD_DIV_MASK,
+	.max_multiplier = OMAP3630_MAX_JTYPE_DPLL_MULT,
+	.min_divider	= 1,
+	.max_divider	= OMAP3_MAX_DPLL_DIV,
+	.flags		= DPLL_J_TYPE
+};
+
+static struct clk dpll4_ck;
+
+static const struct clk_ops dpll4_ck_ops = {
+	.init		= &omap2_init_clk_clkdm,
+	.enable		= &omap3_noncore_dpll_enable,
+	.disable	= &omap3_noncore_dpll_disable,
+	.get_parent	= &omap2_init_dpll_parent,
+	.recalc_rate	= &omap3_dpll_recalc,
+	.set_rate	= &omap3_dpll4_set_rate,
+	.round_rate	= &omap2_dpll_round_rate,
+};
+
+static struct clk_hw_omap dpll4_ck_hw = {
+	.hw = {
+		.clk = &dpll4_ck,
+	},
+	.dpll_data	= &dpll4_dd,
+	.ops		= &clkhwops_omap3_dpll,
+	.clkdm_name	= "dpll4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(dpll4_ck, dpll3_ck_parent_names, dpll4_ck_ops);
+
+DEFINE_CLK_DIVIDER(dpll4_m5_ck, "dpll4_ck", &dpll4_ck, 0x0,
+		   OMAP_CM_REGADDR(OMAP3430_CAM_MOD, CM_CLKSEL),
+		   OMAP3430_CLKSEL_CAM_SHIFT, OMAP3630_CLKSEL_CAM_WIDTH,
+		   CLK_DIVIDER_ONE_BASED, NULL);
+
+static struct clk dpll4_m5x2_ck;
+
+static const char *dpll4_m5x2_ck_parent_names[] = {
+	"dpll4_m5_ck",
+};
+
+static const struct clk_ops dpll4_m5x2_ck_ops = {
+	.init		= &omap2_init_clk_clkdm,
+	.enable		= &omap2_dflt_clk_enable,
+	.disable	= &omap2_dflt_clk_disable,
+	.is_enabled	= &omap2_dflt_clk_is_enabled,
+	.recalc_rate	= &omap3_clkoutx2_recalc,
+};
+
+static const struct clk_ops dpll4_m5x2_ck_3630_ops = {
+	.init		= &omap2_init_clk_clkdm,
+	.enable		= &omap36xx_pwrdn_clk_enable_with_hsdiv_restore,
+	.disable	= &omap2_dflt_clk_disable,
+	.recalc_rate	= &omap3_clkoutx2_recalc,
+};
+
+static struct clk_hw_omap dpll4_m5x2_ck_hw = {
+	.hw = {
+		.clk = &dpll4_m5x2_ck,
+	},
+	.ops		= &clkhwops_wait,
+	.enable_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
+	.enable_bit	= OMAP3430_PWRDN_CAM_SHIFT,
+	.flags		= INVERT_ENABLE,
+	.clkdm_name	= "dpll4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(dpll4_m5x2_ck, dpll4_m5x2_ck_parent_names, dpll4_m5x2_ck_ops);
+
+static struct clk dpll4_m5x2_ck_3630 = {
+	.name		= "dpll4_m5x2_ck",
+	.hw		= &dpll4_m5x2_ck_hw.hw,
+	.parent_names	= dpll4_m5x2_ck_parent_names,
+	.num_parents	= ARRAY_SIZE(dpll4_m5x2_ck_parent_names),
+	.ops		= &dpll4_m5x2_ck_3630_ops,
+};
+
+static struct clk cam_mclk;
+
+static const char *cam_mclk_parent_names[] = {
+	"dpll4_m5x2_ck",
+};
+
+static struct clk_hw_omap cam_mclk_hw = {
+	.hw = {
+		.clk = &cam_mclk,
+	},
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_CAM_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP3430_EN_CAM_SHIFT,
+	.clkdm_name	= "cam_clkdm",
+};
+
+DEFINE_STRUCT_CLK(cam_mclk, cam_mclk_parent_names, aes2_ick_ops);
+
+static const struct clksel_rate clkout2_src_core_rates[] = {
+	{ .div = 1, .val = 0, .flags = RATE_IN_3XXX },
+	{ .div = 0 }
+};
+
+static const struct clksel_rate clkout2_src_sys_rates[] = {
+	{ .div = 1, .val = 1, .flags = RATE_IN_3XXX },
+	{ .div = 0 }
+};
+
+static const struct clksel_rate clkout2_src_96m_rates[] = {
+	{ .div = 1, .val = 2, .flags = RATE_IN_3XXX },
+	{ .div = 0 }
+};
+
+DEFINE_CLK_DIVIDER(dpll4_m2_ck, "dpll4_ck", &dpll4_ck, 0x0,
+		   OMAP_CM_REGADDR(PLL_MOD, OMAP3430_CM_CLKSEL3),
+		   OMAP3430_DIV_96M_SHIFT, OMAP3630_DIV_96M_WIDTH,
+		   CLK_DIVIDER_ONE_BASED, NULL);
+
+static struct clk dpll4_m2x2_ck;
+
+static const char *dpll4_m2x2_ck_parent_names[] = {
+	"dpll4_m2_ck",
+};
+
+static struct clk_hw_omap dpll4_m2x2_ck_hw = {
+	.hw = {
+		.clk = &dpll4_m2x2_ck,
+	},
+	.ops		= &clkhwops_wait,
+	.enable_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
+	.enable_bit	= OMAP3430_PWRDN_96M_SHIFT,
+	.flags		= INVERT_ENABLE,
+	.clkdm_name	= "dpll4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(dpll4_m2x2_ck, dpll4_m2x2_ck_parent_names, dpll4_m5x2_ck_ops);
+
+static struct clk dpll4_m2x2_ck_3630 = {
+	.name		= "dpll4_m2x2_ck",
+	.hw		= &dpll4_m2x2_ck_hw.hw,
+	.parent_names	= dpll4_m2x2_ck_parent_names,
+	.num_parents	= ARRAY_SIZE(dpll4_m2x2_ck_parent_names),
+	.ops		= &dpll4_m5x2_ck_3630_ops,
+};
+
+static struct clk omap_96m_alwon_fck;
+
+static const char *omap_96m_alwon_fck_parent_names[] = {
+	"dpll4_m2x2_ck",
+};
+
+DEFINE_STRUCT_CLK_HW_OMAP(omap_96m_alwon_fck, NULL);
+DEFINE_STRUCT_CLK(omap_96m_alwon_fck, omap_96m_alwon_fck_parent_names,
+		  core_ck_ops);
+
+static struct clk cm_96m_fck;
+
+static const char *cm_96m_fck_parent_names[] = {
+	"omap_96m_alwon_fck",
+};
+
+DEFINE_STRUCT_CLK_HW_OMAP(cm_96m_fck, NULL);
+DEFINE_STRUCT_CLK(cm_96m_fck, cm_96m_fck_parent_names, core_ck_ops);
+
+static const struct clksel_rate clkout2_src_54m_rates[] = {
+	{ .div = 1, .val = 3, .flags = RATE_IN_3XXX },
+	{ .div = 0 }
+};
+
+DEFINE_CLK_DIVIDER(dpll4_m3_ck, "dpll4_ck", &dpll4_ck, 0x0,
+		   OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_CLKSEL),
+		   OMAP3430_CLKSEL_TV_SHIFT, OMAP3630_CLKSEL_TV_WIDTH,
+		   CLK_DIVIDER_ONE_BASED, NULL);
+
+static struct clk dpll4_m3x2_ck;
+
+static const char *dpll4_m3x2_ck_parent_names[] = {
+	"dpll4_m3_ck",
+};
+
+static struct clk_hw_omap dpll4_m3x2_ck_hw = {
+	.hw = {
+		.clk = &dpll4_m3x2_ck,
+	},
+	.ops		= &clkhwops_wait,
+	.enable_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
+	.enable_bit	= OMAP3430_PWRDN_TV_SHIFT,
+	.flags		= INVERT_ENABLE,
+	.clkdm_name	= "dpll4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(dpll4_m3x2_ck, dpll4_m3x2_ck_parent_names, dpll4_m5x2_ck_ops);
+
+static struct clk dpll4_m3x2_ck_3630 = {
+	.name		= "dpll4_m3x2_ck",
+	.hw		= &dpll4_m3x2_ck_hw.hw,
+	.parent_names	= dpll4_m3x2_ck_parent_names,
+	.num_parents	= ARRAY_SIZE(dpll4_m3x2_ck_parent_names),
+	.ops		= &dpll4_m5x2_ck_3630_ops,
+};
+
+static const char *omap_54m_fck_parent_names[] = {
+	"dpll4_m3x2_ck", "sys_altclk",
+};
+
+DEFINE_CLK_MUX(omap_54m_fck, omap_54m_fck_parent_names, NULL, 0x0,
+	       OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1), OMAP3430_SOURCE_54M_SHIFT,
+	       OMAP3430_SOURCE_54M_WIDTH, 0x0, NULL);
+
+static const struct clksel clkout2_src_clksel[] = {
+	{ .parent = &core_ck, .rates = clkout2_src_core_rates },
+	{ .parent = &sys_ck, .rates = clkout2_src_sys_rates },
+	{ .parent = &cm_96m_fck, .rates = clkout2_src_96m_rates },
+	{ .parent = &omap_54m_fck, .rates = clkout2_src_54m_rates },
+	{ .parent = NULL },
+};
+
+static const char *clkout2_src_ck_parent_names[] = {
+	"core_ck", "sys_ck", "cm_96m_fck", "omap_54m_fck",
+};
+
+static const struct clk_ops clkout2_src_ck_ops = {
+	.init		= &omap2_init_clk_clkdm,
+	.enable		= &omap2_dflt_clk_enable,
+	.disable	= &omap2_dflt_clk_disable,
+	.is_enabled	= &omap2_dflt_clk_is_enabled,
+	.recalc_rate	= &omap2_clksel_recalc,
+	.get_parent	= &omap2_clksel_find_parent_index,
+	.set_parent	= &omap2_clksel_set_parent,
+};
+
+DEFINE_CLK_OMAP_MUX_GATE(clkout2_src_ck, "core_clkdm",
+			 clkout2_src_clksel, OMAP3430_CM_CLKOUT_CTRL,
+			 OMAP3430_CLKOUT2SOURCE_MASK,
+			 OMAP3430_CM_CLKOUT_CTRL, OMAP3430_CLKOUT2_EN_SHIFT,
+			 NULL, clkout2_src_ck_parent_names, clkout2_src_ck_ops);
+
+static const struct clksel_rate omap_48m_cm96m_rates[] = {
+	{ .div = 2, .val = 0, .flags = RATE_IN_3XXX },
+	{ .div = 0 }
+};
+
+static const struct clksel_rate omap_48m_alt_rates[] = {
+	{ .div = 1, .val = 1, .flags = RATE_IN_3XXX },
+	{ .div = 0 }
+};
+
+static const struct clksel omap_48m_clksel[] = {
+	{ .parent = &cm_96m_fck, .rates = omap_48m_cm96m_rates },
+	{ .parent = &sys_altclk, .rates = omap_48m_alt_rates },
+	{ .parent = NULL },
+};
+
+static const char *omap_48m_fck_parent_names[] = {
+	"cm_96m_fck", "sys_altclk",
+};
+
+static struct clk omap_48m_fck;
+
+static const struct clk_ops omap_48m_fck_ops = {
+	.recalc_rate	= &omap2_clksel_recalc,
+	.get_parent	= &omap2_clksel_find_parent_index,
+	.set_parent	= &omap2_clksel_set_parent,
+};
+
+static struct clk_hw_omap omap_48m_fck_hw = {
+	.hw = {
+		.clk = &omap_48m_fck,
+	},
+	.clksel		= omap_48m_clksel,
+	.clksel_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1),
+	.clksel_mask	= OMAP3430_SOURCE_48M_MASK,
+};
+
+DEFINE_STRUCT_CLK(omap_48m_fck, omap_48m_fck_parent_names, omap_48m_fck_ops);
+
+DEFINE_CLK_FIXED_FACTOR(omap_12m_fck, "omap_48m_fck", &omap_48m_fck, 0x0, 1, 4);
+
+static struct clk core_12m_fck;
+
+static const char *core_12m_fck_parent_names[] = {
+	"omap_12m_fck",
+};
+
+DEFINE_STRUCT_CLK_HW_OMAP(core_12m_fck, "core_l4_clkdm");
+DEFINE_STRUCT_CLK(core_12m_fck, core_12m_fck_parent_names, core_l4_ick_ops);
+
+static struct clk core_48m_fck;
+
+static const char *core_48m_fck_parent_names[] = {
+	"omap_48m_fck",
+};
+
+DEFINE_STRUCT_CLK_HW_OMAP(core_48m_fck, "core_l4_clkdm");
+DEFINE_STRUCT_CLK(core_48m_fck, core_48m_fck_parent_names, core_l4_ick_ops);
+
+static const char *omap_96m_fck_parent_names[] = {
+	"cm_96m_fck", "sys_ck",
+};
+
+DEFINE_CLK_MUX(omap_96m_fck, omap_96m_fck_parent_names, NULL, 0x0,
+	       OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1),
+	       OMAP3430_SOURCE_96M_SHIFT, OMAP3430_SOURCE_96M_WIDTH, 0x0, NULL);
+
+static struct clk core_96m_fck;
+
+static const char *core_96m_fck_parent_names[] = {
+	"omap_96m_fck",
+};
+
+DEFINE_STRUCT_CLK_HW_OMAP(core_96m_fck, "core_l4_clkdm");
+DEFINE_STRUCT_CLK(core_96m_fck, core_96m_fck_parent_names, core_l4_ick_ops);
+
+static struct clk core_l3_ick;
+
+static const char *core_l3_ick_parent_names[] = {
+	"l3_ick",
+};
+
+DEFINE_STRUCT_CLK_HW_OMAP(core_l3_ick, "core_l3_clkdm");
+DEFINE_STRUCT_CLK(core_l3_ick, core_l3_ick_parent_names, core_l4_ick_ops);
+
+DEFINE_CLK_FIXED_FACTOR(dpll3_m2x2_ck, "dpll3_m2_ck", &dpll3_m2_ck, 0x0, 2, 1);
+
+static struct clk corex2_fck;
+
+static const char *corex2_fck_parent_names[] = {
+	"dpll3_m2x2_ck",
+};
+
+DEFINE_STRUCT_CLK_HW_OMAP(corex2_fck, NULL);
+DEFINE_STRUCT_CLK(corex2_fck, corex2_fck_parent_names, core_ck_ops);
+
+static struct clk cpefuse_fck;
+
+static struct clk_hw_omap cpefuse_fck_hw = {
+	.hw = {
+		.clk = &cpefuse_fck,
+	},
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP3430ES2_CM_FCLKEN3),
+	.enable_bit	= OMAP3430ES2_EN_CPEFUSE_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(cpefuse_fck, dpll3_ck_parent_names, aes2_ick_ops);
+
+static struct clk csi2_96m_fck;
+
+static const char *csi2_96m_fck_parent_names[] = {
+	"core_96m_fck",
+};
+
+static struct clk_hw_omap csi2_96m_fck_hw = {
+	.hw = {
+		.clk = &csi2_96m_fck,
+	},
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_CAM_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP3430_EN_CSI2_SHIFT,
+	.clkdm_name	= "cam_clkdm",
+};
+
+DEFINE_STRUCT_CLK(csi2_96m_fck, csi2_96m_fck_parent_names, aes2_ick_ops);
+
+static struct clk d2d_26m_fck;
+
+static struct clk_hw_omap d2d_26m_fck_hw = {
+	.hw = {
+		.clk = &d2d_26m_fck,
+	},
+	.ops		= &clkhwops_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP3430ES1_EN_D2D_SHIFT,
+	.clkdm_name	= "d2d_clkdm",
+};
+
+DEFINE_STRUCT_CLK(d2d_26m_fck, dpll3_ck_parent_names, aes2_ick_ops);
+
+static struct clk des1_ick;
+
+static struct clk_hw_omap des1_ick_hw = {
+	.hw = {
+		.clk = &des1_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
+	.enable_bit	= OMAP3430_EN_DES1_SHIFT,
+};
+
+DEFINE_STRUCT_CLK(des1_ick, aes1_ick_parent_names, aes1_ick_ops);
+
+static struct clk des2_ick;
+
+static struct clk_hw_omap des2_ick_hw = {
+	.hw = {
+		.clk = &des2_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP3430_EN_DES2_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(des2_ick, aes2_ick_parent_names, aes2_ick_ops);
+
+DEFINE_CLK_DIVIDER(dpll1_fck, "core_ck", &core_ck, 0x0,
+		   OMAP_CM_REGADDR(MPU_MOD, OMAP3430_CM_CLKSEL1_PLL),
+		   OMAP3430_MPU_CLK_SRC_SHIFT, OMAP3430_MPU_CLK_SRC_WIDTH,
+		   CLK_DIVIDER_ONE_BASED, NULL);
+
+static struct clk dpll2_fck;
+
+static struct dpll_data dpll2_dd = {
+	.mult_div1_reg	= OMAP_CM_REGADDR(OMAP3430_IVA2_MOD, OMAP3430_CM_CLKSEL1_PLL),
+	.mult_mask	= OMAP3430_IVA2_DPLL_MULT_MASK,
+	.div1_mask	= OMAP3430_IVA2_DPLL_DIV_MASK,
+	.clk_bypass	= &dpll2_fck,
+	.clk_ref	= &sys_ck,
+	.freqsel_mask	= OMAP3430_IVA2_DPLL_FREQSEL_MASK,
+	.control_reg	= OMAP_CM_REGADDR(OMAP3430_IVA2_MOD, OMAP3430_CM_CLKEN_PLL),
+	.enable_mask	= OMAP3430_EN_IVA2_DPLL_MASK,
+	.modes		= ((1 << DPLL_LOW_POWER_STOP) | (1 << DPLL_LOCKED) |
+			   (1 << DPLL_LOW_POWER_BYPASS)),
+	.auto_recal_bit	= OMAP3430_EN_IVA2_DPLL_DRIFTGUARD_SHIFT,
+	.recal_en_bit	= OMAP3430_PRM_IRQENABLE_MPU_IVA2_DPLL_RECAL_EN_SHIFT,
+	.recal_st_bit	= OMAP3430_PRM_IRQSTATUS_MPU_IVA2_DPLL_ST_SHIFT,
+	.autoidle_reg	= OMAP_CM_REGADDR(OMAP3430_IVA2_MOD, OMAP3430_CM_AUTOIDLE_PLL),
+	.autoidle_mask	= OMAP3430_AUTO_IVA2_DPLL_MASK,
+	.idlest_reg	= OMAP_CM_REGADDR(OMAP3430_IVA2_MOD, OMAP3430_CM_IDLEST_PLL),
+	.idlest_mask	= OMAP3430_ST_IVA2_CLK_MASK,
+	.max_multiplier	= OMAP3_MAX_DPLL_MULT,
+	.min_divider	= 1,
+	.max_divider	= OMAP3_MAX_DPLL_DIV,
+};
+
+static struct clk dpll2_ck;
+
+static struct clk_hw_omap dpll2_ck_hw = {
+	.hw = {
+		.clk = &dpll2_ck,
+	},
+	.ops		= &clkhwops_omap3_dpll,
+	.dpll_data	= &dpll2_dd,
+	.clkdm_name	= "dpll2_clkdm",
+};
+
+DEFINE_STRUCT_CLK(dpll2_ck, dpll3_ck_parent_names, dpll1_ck_ops);
+
+DEFINE_CLK_DIVIDER(dpll2_fck, "core_ck", &core_ck, 0x0,
+		   OMAP_CM_REGADDR(OMAP3430_IVA2_MOD, OMAP3430_CM_CLKSEL1_PLL),
+		   OMAP3430_IVA2_CLK_SRC_SHIFT, OMAP3430_IVA2_CLK_SRC_WIDTH,
+		   CLK_DIVIDER_ONE_BASED, NULL);
+
+DEFINE_CLK_DIVIDER(dpll2_m2_ck, "dpll2_ck", &dpll2_ck, 0x0,
+		   OMAP_CM_REGADDR(OMAP3430_IVA2_MOD, OMAP3430_CM_CLKSEL2_PLL),
+		   OMAP3430_IVA2_DPLL_CLKOUT_DIV_SHIFT,
+		   OMAP3430_IVA2_DPLL_CLKOUT_DIV_WIDTH,
+		   CLK_DIVIDER_ONE_BASED, NULL);
+
+DEFINE_CLK_DIVIDER(dpll3_m3_ck, "dpll3_ck", &dpll3_ck, 0x0,
+		   OMAP_CM_REGADDR(OMAP3430_EMU_MOD, CM_CLKSEL1),
+		   OMAP3430_DIV_DPLL3_SHIFT, OMAP3430_DIV_DPLL3_WIDTH,
+		   CLK_DIVIDER_ONE_BASED, NULL);
+
+static struct clk dpll3_m3x2_ck;
+
+static const char *dpll3_m3x2_ck_parent_names[] = {
+	"dpll3_m3_ck",
+};
+
+static struct clk_hw_omap dpll3_m3x2_ck_hw = {
+	.hw = {
+		.clk = &dpll3_m3x2_ck,
+	},
+	.ops		= &clkhwops_wait,
+	.enable_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
+	.enable_bit	= OMAP3430_PWRDN_EMU_CORE_SHIFT,
+	.flags		= INVERT_ENABLE,
+	.clkdm_name	= "dpll3_clkdm",
+};
+
+DEFINE_STRUCT_CLK(dpll3_m3x2_ck, dpll3_m3x2_ck_parent_names, dpll4_m5x2_ck_ops);
+
+static struct clk dpll3_m3x2_ck_3630 = {
+	.name		= "dpll3_m3x2_ck",
+	.hw		= &dpll3_m3x2_ck_hw.hw,
+	.parent_names	= dpll3_m3x2_ck_parent_names,
+	.num_parents	= ARRAY_SIZE(dpll3_m3x2_ck_parent_names),
+	.ops		= &dpll4_m5x2_ck_3630_ops,
+};
+
+DEFINE_CLK_FIXED_FACTOR(dpll3_x2_ck, "dpll3_ck", &dpll3_ck, 0x0, 2, 1);
+
+DEFINE_CLK_DIVIDER(dpll4_m4_ck, "dpll4_ck", &dpll4_ck, 0x0,
+		   OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_CLKSEL),
+		   OMAP3430_CLKSEL_DSS1_SHIFT, OMAP3630_CLKSEL_DSS1_WIDTH,
+		   CLK_DIVIDER_ONE_BASED, NULL);
+
+static struct clk dpll4_m4x2_ck;
+
+static const char *dpll4_m4x2_ck_parent_names[] = {
+	"dpll4_m4_ck",
+};
+
+static struct clk_hw_omap dpll4_m4x2_ck_hw = {
+	.hw = {
+		.clk = &dpll4_m4x2_ck,
+	},
+	.ops		= &clkhwops_wait,
+	.enable_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
+	.enable_bit	= OMAP3430_PWRDN_DSS1_SHIFT,
+	.flags		= INVERT_ENABLE,
+	.clkdm_name	= "dpll4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(dpll4_m4x2_ck, dpll4_m4x2_ck_parent_names, dpll4_m5x2_ck_ops);
+
+static struct clk dpll4_m4x2_ck_3630 = {
+	.name		= "dpll4_m4x2_ck",
+	.hw		= &dpll4_m4x2_ck_hw.hw,
+	.parent_names	= dpll4_m4x2_ck_parent_names,
+	.num_parents	= ARRAY_SIZE(dpll4_m4x2_ck_parent_names),
+	.ops		= &dpll4_m5x2_ck_3630_ops,
+};
+
+DEFINE_CLK_DIVIDER(dpll4_m6_ck, "dpll4_ck", &dpll4_ck, 0x0,
+		   OMAP_CM_REGADDR(OMAP3430_EMU_MOD, CM_CLKSEL1),
+		   OMAP3430_DIV_DPLL4_SHIFT, OMAP3630_DIV_DPLL4_WIDTH,
+		   CLK_DIVIDER_ONE_BASED, NULL);
+
+static struct clk dpll4_m6x2_ck;
+
+static const char *dpll4_m6x2_ck_parent_names[] = {
+	"dpll4_m6_ck",
+};
+
+static struct clk_hw_omap dpll4_m6x2_ck_hw = {
+	.hw = {
+		.clk = &dpll4_m6x2_ck,
+	},
+	.ops		= &clkhwops_wait,
+	.enable_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
+	.enable_bit	= OMAP3430_PWRDN_EMU_PERIPH_SHIFT,
+	.flags		= INVERT_ENABLE,
+	.clkdm_name	= "dpll4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(dpll4_m6x2_ck, dpll4_m6x2_ck_parent_names, dpll4_m5x2_ck_ops);
+
+static struct clk dpll4_m6x2_ck_3630 = {
+	.name		= "dpll4_m6x2_ck",
+	.hw		= &dpll4_m6x2_ck_hw.hw,
+	.parent_names	= dpll4_m6x2_ck_parent_names,
+	.num_parents	= ARRAY_SIZE(dpll4_m6x2_ck_parent_names),
+	.ops		= &dpll4_m5x2_ck_3630_ops,
+};
+
+DEFINE_CLK_FIXED_FACTOR(dpll4_x2_ck, "dpll4_ck", &dpll4_ck, 0x0, 2, 1);
+
+static struct dpll_data dpll5_dd = {
+	.mult_div1_reg	= OMAP_CM_REGADDR(PLL_MOD, OMAP3430ES2_CM_CLKSEL4),
+	.mult_mask	= OMAP3430ES2_PERIPH2_DPLL_MULT_MASK,
+	.div1_mask	= OMAP3430ES2_PERIPH2_DPLL_DIV_MASK,
+	.clk_bypass	= &sys_ck,
+	.clk_ref	= &sys_ck,
+	.freqsel_mask	= OMAP3430ES2_PERIPH2_DPLL_FREQSEL_MASK,
+	.control_reg	= OMAP_CM_REGADDR(PLL_MOD, OMAP3430ES2_CM_CLKEN2),
+	.enable_mask	= OMAP3430ES2_EN_PERIPH2_DPLL_MASK,
+	.modes		= (1 << DPLL_LOW_POWER_STOP) | (1 << DPLL_LOCKED),
+	.auto_recal_bit	= OMAP3430ES2_EN_PERIPH2_DPLL_DRIFTGUARD_SHIFT,
+	.recal_en_bit	= OMAP3430ES2_SND_PERIPH_DPLL_RECAL_EN_SHIFT,
+	.recal_st_bit	= OMAP3430ES2_SND_PERIPH_DPLL_ST_SHIFT,
+	.autoidle_reg	= OMAP_CM_REGADDR(PLL_MOD, OMAP3430ES2_CM_AUTOIDLE2_PLL),
+	.autoidle_mask	= OMAP3430ES2_AUTO_PERIPH2_DPLL_MASK,
+	.idlest_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST2),
+	.idlest_mask	= OMAP3430ES2_ST_PERIPH2_CLK_MASK,
+	.max_multiplier	= OMAP3_MAX_DPLL_MULT,
+	.min_divider	= 1,
+	.max_divider	= OMAP3_MAX_DPLL_DIV,
+};
+
+static struct clk dpll5_ck;
+
+static struct clk_hw_omap dpll5_ck_hw = {
+	.hw = {
+		.clk = &dpll5_ck,
+	},
+	.ops		= &clkhwops_omap3_dpll,
+	.dpll_data	= &dpll5_dd,
+	.clkdm_name	= "dpll5_clkdm",
+};
+
+DEFINE_STRUCT_CLK(dpll5_ck, dpll3_ck_parent_names, dpll1_ck_ops);
+
+DEFINE_CLK_DIVIDER(dpll5_m2_ck, "dpll5_ck", &dpll5_ck, 0x0,
+		   OMAP_CM_REGADDR(PLL_MOD, OMAP3430ES2_CM_CLKSEL5),
+		   OMAP3430ES2_DIV_120M_SHIFT, OMAP3430ES2_DIV_120M_WIDTH,
+		   CLK_DIVIDER_ONE_BASED, NULL);
+
+static struct clk dss1_alwon_fck_3430es1;
+
+static const char *dss1_alwon_fck_3430es1_parent_names[] = {
+	"dpll4_m4x2_ck",
+};
+
+static struct clk_hw_omap dss1_alwon_fck_3430es1_hw = {
+	.hw = {
+		.clk = &dss1_alwon_fck_3430es1,
+	},
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP3430_EN_DSS1_SHIFT,
+	.clkdm_name	= "dss_clkdm",
+};
+
+DEFINE_STRUCT_CLK(dss1_alwon_fck_3430es1, dss1_alwon_fck_3430es1_parent_names,
+		  aes2_ick_ops);
+
+static struct clk dss1_alwon_fck_3430es2;
+
+static struct clk_hw_omap dss1_alwon_fck_3430es2_hw = {
+	.hw = {
+		.clk = &dss1_alwon_fck_3430es2,
+	},
+	.ops		= &clkhwops_omap3430es2_dss_usbhost_wait,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP3430_EN_DSS1_SHIFT,
+	.clkdm_name	= "dss_clkdm",
+};
+
+DEFINE_STRUCT_CLK(dss1_alwon_fck_3430es2, dss1_alwon_fck_3430es1_parent_names,
+		  aes2_ick_ops);
+
+static struct clk dss2_alwon_fck;
+
+static struct clk_hw_omap dss2_alwon_fck_hw = {
+	.hw = {
+		.clk = &dss2_alwon_fck,
+	},
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP3430_EN_DSS2_SHIFT,
+	.clkdm_name	= "dss_clkdm",
+};
+
+DEFINE_STRUCT_CLK(dss2_alwon_fck, dpll3_ck_parent_names, aes2_ick_ops);
+
+static struct clk dss_96m_fck;
+
+static struct clk_hw_omap dss_96m_fck_hw = {
+	.hw = {
+		.clk = &dss_96m_fck,
+	},
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP3430_EN_TV_SHIFT,
+	.clkdm_name	= "dss_clkdm",
+};
+
+DEFINE_STRUCT_CLK(dss_96m_fck, core_96m_fck_parent_names, aes2_ick_ops);
+
+static struct clk dss_ick_3430es1;
+
+static struct clk_hw_omap dss_ick_3430es1_hw = {
+	.hw = {
+		.clk = &dss_ick_3430es1,
+	},
+	.ops		= &clkhwops_iclk,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP3430_CM_ICLKEN_DSS_EN_DSS_SHIFT,
+	.clkdm_name	= "dss_clkdm",
+};
+
+DEFINE_STRUCT_CLK(dss_ick_3430es1, security_l4_ick2_parent_names, aes2_ick_ops);
+
+static struct clk dss_ick_3430es2;
+
+static struct clk_hw_omap dss_ick_3430es2_hw = {
+	.hw = {
+		.clk = &dss_ick_3430es2,
+	},
+	.ops		= &clkhwops_omap3430es2_iclk_dss_usbhost_wait,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP3430_CM_ICLKEN_DSS_EN_DSS_SHIFT,
+	.clkdm_name	= "dss_clkdm",
+};
+
+DEFINE_STRUCT_CLK(dss_ick_3430es2, security_l4_ick2_parent_names, aes2_ick_ops);
+
+static struct clk dss_tv_fck;
+
+static const char *dss_tv_fck_parent_names[] = {
+	"omap_54m_fck",
+};
+
+static struct clk_hw_omap dss_tv_fck_hw = {
+	.hw = {
+		.clk = &dss_tv_fck,
+	},
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP3430_EN_TV_SHIFT,
+	.clkdm_name	= "dss_clkdm",
+};
+
+DEFINE_STRUCT_CLK(dss_tv_fck, dss_tv_fck_parent_names, aes2_ick_ops);
+
+static struct clk emac_fck;
+
+static const char *emac_fck_parent_names[] = {
+	"rmii_ck",
+};
+
+static struct clk_hw_omap emac_fck_hw = {
+	.hw = {
+		.clk = &emac_fck,
+	},
+	.enable_reg	= OMAP343X_CTRL_REGADDR(AM35XX_CONTROL_IPSS_CLK_CTRL),
+	.enable_bit	= AM35XX_CPGMAC_FCLK_SHIFT,
+};
+
+DEFINE_STRUCT_CLK(emac_fck, emac_fck_parent_names, aes1_ick_ops);
+
+static struct clk ipss_ick;
+
+static const char *ipss_ick_parent_names[] = {
+	"core_l3_ick",
+};
+
+static struct clk_hw_omap ipss_ick_hw = {
+	.hw = {
+		.clk = &ipss_ick,
+	},
+	.ops		= &clkhwops_am35xx_ipss_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= AM35XX_EN_IPSS_SHIFT,
+	.clkdm_name	= "core_l3_clkdm",
+};
+
+DEFINE_STRUCT_CLK(ipss_ick, ipss_ick_parent_names, aes2_ick_ops);
+
+static struct clk emac_ick;
+
+static const char *emac_ick_parent_names[] = {
+	"ipss_ick",
+};
+
+static struct clk_hw_omap emac_ick_hw = {
+	.hw = {
+		.clk = &emac_ick,
+	},
+	.ops		= &clkhwops_am35xx_ipss_module_wait,
+	.enable_reg	= OMAP343X_CTRL_REGADDR(AM35XX_CONTROL_IPSS_CLK_CTRL),
+	.enable_bit	= AM35XX_CPGMAC_VBUSP_CLK_SHIFT,
+	.clkdm_name	= "core_l3_clkdm",
+};
+
+DEFINE_STRUCT_CLK(emac_ick, emac_ick_parent_names, aes2_ick_ops);
+
+static struct clk emu_core_alwon_ck;
+
+static const char *emu_core_alwon_ck_parent_names[] = {
+	"dpll3_m3x2_ck",
+};
+
+DEFINE_STRUCT_CLK_HW_OMAP(emu_core_alwon_ck, "dpll3_clkdm");
+DEFINE_STRUCT_CLK(emu_core_alwon_ck, emu_core_alwon_ck_parent_names,
+		  core_l4_ick_ops);
+
+static struct clk emu_mpu_alwon_ck;
+
+static const char *emu_mpu_alwon_ck_parent_names[] = {
+	"mpu_ck",
+};
+
+DEFINE_STRUCT_CLK_HW_OMAP(emu_mpu_alwon_ck, NULL);
+DEFINE_STRUCT_CLK(emu_mpu_alwon_ck, emu_mpu_alwon_ck_parent_names, core_ck_ops);
+
+static struct clk emu_per_alwon_ck;
+
+static const char *emu_per_alwon_ck_parent_names[] = {
+	"dpll4_m6x2_ck",
+};
+
+DEFINE_STRUCT_CLK_HW_OMAP(emu_per_alwon_ck, "dpll4_clkdm");
+DEFINE_STRUCT_CLK(emu_per_alwon_ck, emu_per_alwon_ck_parent_names,
+		  core_l4_ick_ops);
+
+static const char *emu_src_ck_parent_names[] = {
+	"sys_ck", "emu_core_alwon_ck", "emu_per_alwon_ck", "emu_mpu_alwon_ck",
+};
+
+static const struct clksel_rate emu_src_sys_rates[] = {
+	{ .div = 1, .val = 0, .flags = RATE_IN_3XXX },
+	{ .div = 0 },
+};
+
+static const struct clksel_rate emu_src_core_rates[] = {
+	{ .div = 1, .val = 1, .flags = RATE_IN_3XXX },
+	{ .div = 0 },
+};
+
+static const struct clksel_rate emu_src_per_rates[] = {
+	{ .div = 1, .val = 2, .flags = RATE_IN_3XXX },
+	{ .div = 0 },
+};
+
+static const struct clksel_rate emu_src_mpu_rates[] = {
+	{ .div = 1, .val = 3, .flags = RATE_IN_3XXX },
+	{ .div = 0 },
+};
+
+static const struct clksel emu_src_clksel[] = {
+	{ .parent = &sys_ck,		.rates = emu_src_sys_rates },
+	{ .parent = &emu_core_alwon_ck, .rates = emu_src_core_rates },
+	{ .parent = &emu_per_alwon_ck,	.rates = emu_src_per_rates },
+	{ .parent = &emu_mpu_alwon_ck,	.rates = emu_src_mpu_rates },
+	{ .parent = NULL },
+};
+
+static const struct clk_ops emu_src_ck_ops = {
+	.init		= &omap2_init_clk_clkdm,
+	.recalc_rate	= &omap2_clksel_recalc,
+	.get_parent	= &omap2_clksel_find_parent_index,
+	.set_parent	= &omap2_clksel_set_parent,
+};
+
+static struct clk emu_src_ck;
+
+static struct clk_hw_omap emu_src_ck_hw = {
+	.hw = {
+		.clk = &emu_src_ck,
+	},
+	.clksel		= emu_src_clksel,
+	.clksel_reg	= OMAP_CM_REGADDR(OMAP3430_EMU_MOD, CM_CLKSEL1),
+	.clksel_mask	= OMAP3430_MUX_CTRL_MASK,
+	.clkdm_name	= "emu_clkdm",
+};
+
+DEFINE_STRUCT_CLK(emu_src_ck, emu_src_ck_parent_names, emu_src_ck_ops);
+
+DEFINE_CLK_DIVIDER(atclk_fck, "emu_src_ck", &emu_src_ck, 0x0,
+		   OMAP_CM_REGADDR(OMAP3430_EMU_MOD, CM_CLKSEL1),
+		   OMAP3430_CLKSEL_ATCLK_SHIFT, OMAP3430_CLKSEL_ATCLK_WIDTH,
+		   CLK_DIVIDER_ONE_BASED, NULL);
+
+static struct clk fac_ick;
+
+static struct clk_hw_omap fac_ick_hw = {
+	.hw = {
+		.clk = &fac_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP3430ES1_EN_FAC_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(fac_ick, aes2_ick_parent_names, aes2_ick_ops);
+
+static struct clk fshostusb_fck;
+
+static const char *fshostusb_fck_parent_names[] = {
+	"core_48m_fck",
+};
+
+static struct clk_hw_omap fshostusb_fck_hw = {
+	.hw = {
+		.clk = &fshostusb_fck,
+	},
+	.ops		= &clkhwops_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP3430ES1_EN_FSHOSTUSB_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(fshostusb_fck, fshostusb_fck_parent_names, aes2_ick_ops);
+
+static struct clk gfx_l3_ck;
+
+static struct clk_hw_omap gfx_l3_ck_hw = {
+	.hw = {
+		.clk = &gfx_l3_ck,
+	},
+	.ops		= &clkhwops_wait,
+	.enable_reg	= OMAP_CM_REGADDR(GFX_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP_EN_GFX_SHIFT,
+	.clkdm_name	= "gfx_3430es1_clkdm",
+};
+
+DEFINE_STRUCT_CLK(gfx_l3_ck, core_l3_ick_parent_names, aes1_ick_ops);
+
+DEFINE_CLK_DIVIDER(gfx_l3_fck, "l3_ick", &l3_ick, 0x0,
+		   OMAP_CM_REGADDR(GFX_MOD, CM_CLKSEL),
+		   OMAP_CLKSEL_GFX_SHIFT, OMAP_CLKSEL_GFX_WIDTH,
+		   CLK_DIVIDER_ONE_BASED, NULL);
+
+static struct clk gfx_cg1_ck;
+
+static const char *gfx_cg1_ck_parent_names[] = {
+	"gfx_l3_fck",
+};
+
+static struct clk_hw_omap gfx_cg1_ck_hw = {
+	.hw = {
+		.clk = &gfx_cg1_ck,
+	},
+	.ops		= &clkhwops_wait,
+	.enable_reg	= OMAP_CM_REGADDR(GFX_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP3430ES1_EN_2D_SHIFT,
+	.clkdm_name	= "gfx_3430es1_clkdm",
+};
+
+DEFINE_STRUCT_CLK(gfx_cg1_ck, gfx_cg1_ck_parent_names, aes2_ick_ops);
+
+static struct clk gfx_cg2_ck;
+
+static struct clk_hw_omap gfx_cg2_ck_hw = {
+	.hw = {
+		.clk = &gfx_cg2_ck,
+	},
+	.ops		= &clkhwops_wait,
+	.enable_reg	= OMAP_CM_REGADDR(GFX_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP3430ES1_EN_3D_SHIFT,
+	.clkdm_name	= "gfx_3430es1_clkdm",
+};
+
+DEFINE_STRUCT_CLK(gfx_cg2_ck, gfx_cg1_ck_parent_names, aes2_ick_ops);
+
+static struct clk gfx_l3_ick;
+
+static const char *gfx_l3_ick_parent_names[] = {
+	"gfx_l3_ck",
+};
+
+DEFINE_STRUCT_CLK_HW_OMAP(gfx_l3_ick, "gfx_3430es1_clkdm");
+DEFINE_STRUCT_CLK(gfx_l3_ick, gfx_l3_ick_parent_names, core_l4_ick_ops);
+
+static struct clk wkup_32k_fck;
+
+static const char *wkup_32k_fck_parent_names[] = {
+	"omap_32k_fck",
+};
+
+DEFINE_STRUCT_CLK_HW_OMAP(wkup_32k_fck, "wkup_clkdm");
+DEFINE_STRUCT_CLK(wkup_32k_fck, wkup_32k_fck_parent_names, core_l4_ick_ops);
+
+static struct clk gpio1_dbck;
+
+static const char *gpio1_dbck_parent_names[] = {
+	"wkup_32k_fck",
+};
+
+static struct clk_hw_omap gpio1_dbck_hw = {
+	.hw = {
+		.clk = &gpio1_dbck,
+	},
+	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP3430_EN_GPIO1_SHIFT,
+	.clkdm_name	= "wkup_clkdm",
+};
+
+DEFINE_STRUCT_CLK(gpio1_dbck, gpio1_dbck_parent_names, aes2_ick_ops);
+
+static struct clk wkup_l4_ick;
+
+DEFINE_STRUCT_CLK_HW_OMAP(wkup_l4_ick, "wkup_clkdm");
+DEFINE_STRUCT_CLK(wkup_l4_ick, dpll3_ck_parent_names, core_l4_ick_ops);
+
+static struct clk gpio1_ick;
+
+static const char *gpio1_ick_parent_names[] = {
+	"wkup_l4_ick",
+};
+
+static struct clk_hw_omap gpio1_ick_hw = {
+	.hw = {
+		.clk = &gpio1_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP3430_EN_GPIO1_SHIFT,
+	.clkdm_name	= "wkup_clkdm",
+};
+
+DEFINE_STRUCT_CLK(gpio1_ick, gpio1_ick_parent_names, aes2_ick_ops);
+
+static struct clk per_32k_alwon_fck;
+
+DEFINE_STRUCT_CLK_HW_OMAP(per_32k_alwon_fck, "per_clkdm");
+DEFINE_STRUCT_CLK(per_32k_alwon_fck, wkup_32k_fck_parent_names,
+		  core_l4_ick_ops);
+
+static struct clk gpio2_dbck;
+
+static const char *gpio2_dbck_parent_names[] = {
+	"per_32k_alwon_fck",
+};
+
+static struct clk_hw_omap gpio2_dbck_hw = {
+	.hw = {
+		.clk = &gpio2_dbck,
+	},
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP3430_EN_GPIO2_SHIFT,
+	.clkdm_name	= "per_clkdm",
+};
+
+DEFINE_STRUCT_CLK(gpio2_dbck, gpio2_dbck_parent_names, aes2_ick_ops);
+
+static struct clk per_l4_ick;
+
+DEFINE_STRUCT_CLK_HW_OMAP(per_l4_ick, "per_clkdm");
+DEFINE_STRUCT_CLK(per_l4_ick, security_l4_ick2_parent_names, core_l4_ick_ops);
+
+static struct clk gpio2_ick;
+
+static const char *gpio2_ick_parent_names[] = {
+	"per_l4_ick",
+};
+
+static struct clk_hw_omap gpio2_ick_hw = {
+	.hw = {
+		.clk = &gpio2_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP3430_EN_GPIO2_SHIFT,
+	.clkdm_name	= "per_clkdm",
+};
+
+DEFINE_STRUCT_CLK(gpio2_ick, gpio2_ick_parent_names, aes2_ick_ops);
+
+static struct clk gpio3_dbck;
+
+static struct clk_hw_omap gpio3_dbck_hw = {
+	.hw = {
+		.clk = &gpio3_dbck,
+	},
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP3430_EN_GPIO3_SHIFT,
+	.clkdm_name	= "per_clkdm",
+};
+
+DEFINE_STRUCT_CLK(gpio3_dbck, gpio2_dbck_parent_names, aes2_ick_ops);
+
+static struct clk gpio3_ick;
+
+static struct clk_hw_omap gpio3_ick_hw = {
+	.hw = {
+		.clk = &gpio3_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP3430_EN_GPIO3_SHIFT,
+	.clkdm_name	= "per_clkdm",
+};
+
+DEFINE_STRUCT_CLK(gpio3_ick, gpio2_ick_parent_names, aes2_ick_ops);
+
+static struct clk gpio4_dbck;
+
+static struct clk_hw_omap gpio4_dbck_hw = {
+	.hw = {
+		.clk = &gpio4_dbck,
+	},
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP3430_EN_GPIO4_SHIFT,
+	.clkdm_name	= "per_clkdm",
+};
+
+DEFINE_STRUCT_CLK(gpio4_dbck, gpio2_dbck_parent_names, aes2_ick_ops);
+
+static struct clk gpio4_ick;
+
+static struct clk_hw_omap gpio4_ick_hw = {
+	.hw = {
+		.clk = &gpio4_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP3430_EN_GPIO4_SHIFT,
+	.clkdm_name	= "per_clkdm",
+};
+
+DEFINE_STRUCT_CLK(gpio4_ick, gpio2_ick_parent_names, aes2_ick_ops);
+
+static struct clk gpio5_dbck;
+
+static struct clk_hw_omap gpio5_dbck_hw = {
+	.hw = {
+		.clk = &gpio5_dbck,
+	},
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP3430_EN_GPIO5_SHIFT,
+	.clkdm_name	= "per_clkdm",
+};
+
+DEFINE_STRUCT_CLK(gpio5_dbck, gpio2_dbck_parent_names, aes2_ick_ops);
+
+static struct clk gpio5_ick;
+
+static struct clk_hw_omap gpio5_ick_hw = {
+	.hw = {
+		.clk = &gpio5_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP3430_EN_GPIO5_SHIFT,
+	.clkdm_name	= "per_clkdm",
+};
+
+DEFINE_STRUCT_CLK(gpio5_ick, gpio2_ick_parent_names, aes2_ick_ops);
+
+static struct clk gpio6_dbck;
+
+static struct clk_hw_omap gpio6_dbck_hw = {
+	.hw = {
+		.clk = &gpio6_dbck,
+	},
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP3430_EN_GPIO6_SHIFT,
+	.clkdm_name	= "per_clkdm",
+};
+
+DEFINE_STRUCT_CLK(gpio6_dbck, gpio2_dbck_parent_names, aes2_ick_ops);
+
+static struct clk gpio6_ick;
+
+static struct clk_hw_omap gpio6_ick_hw = {
+	.hw = {
+		.clk = &gpio6_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP3430_EN_GPIO6_SHIFT,
+	.clkdm_name	= "per_clkdm",
+};
+
+DEFINE_STRUCT_CLK(gpio6_ick, gpio2_ick_parent_names, aes2_ick_ops);
+
+static struct clk gpmc_fck;
+
+static struct clk_hw_omap gpmc_fck_hw = {
+	.hw = {
+		.clk = &gpmc_fck,
+	},
+	.flags		= ENABLE_ON_INIT,
+	.clkdm_name	= "core_l3_clkdm",
+};
+
+DEFINE_STRUCT_CLK(gpmc_fck, ipss_ick_parent_names, core_l4_ick_ops);
+
+static const struct clksel omap343x_gpt_clksel[] = {
+	{ .parent = &omap_32k_fck, .rates = gpt_32k_rates },
+	{ .parent = &sys_ck, .rates = gpt_sys_rates },
+	{ .parent = NULL },
+};
+
+static const char *gpt10_fck_parent_names[] = {
+	"omap_32k_fck", "sys_ck",
+};
+
+DEFINE_CLK_OMAP_MUX_GATE(gpt10_fck, "core_l4_clkdm", omap343x_gpt_clksel,
+			 OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL),
+			 OMAP3430_CLKSEL_GPT10_MASK,
+			 OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+			 OMAP3430_EN_GPT10_SHIFT, &clkhwops_wait,
+			 gpt10_fck_parent_names, clkout2_src_ck_ops);
+
+static struct clk gpt10_ick;
+
+static struct clk_hw_omap gpt10_ick_hw = {
+	.hw = {
+		.clk = &gpt10_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP3430_EN_GPT10_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(gpt10_ick, aes2_ick_parent_names, aes2_ick_ops);
+
+DEFINE_CLK_OMAP_MUX_GATE(gpt11_fck, "core_l4_clkdm", omap343x_gpt_clksel,
+			 OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL),
+			 OMAP3430_CLKSEL_GPT11_MASK,
+			 OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+			 OMAP3430_EN_GPT11_SHIFT, &clkhwops_wait,
+			 gpt10_fck_parent_names, clkout2_src_ck_ops);
+
+static struct clk gpt11_ick;
+
+static struct clk_hw_omap gpt11_ick_hw = {
+	.hw = {
+		.clk = &gpt11_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP3430_EN_GPT11_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(gpt11_ick, aes2_ick_parent_names, aes2_ick_ops);
+
+static struct clk gpt12_fck;
+
+static const char *gpt12_fck_parent_names[] = {
+	"secure_32k_fck",
+};
+
+DEFINE_STRUCT_CLK_HW_OMAP(gpt12_fck, "wkup_clkdm");
+DEFINE_STRUCT_CLK(gpt12_fck, gpt12_fck_parent_names, core_l4_ick_ops);
+
+static struct clk gpt12_ick;
+
+static struct clk_hw_omap gpt12_ick_hw = {
+	.hw = {
+		.clk = &gpt12_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP3430_EN_GPT12_SHIFT,
+	.clkdm_name	= "wkup_clkdm",
+};
+
+DEFINE_STRUCT_CLK(gpt12_ick, gpio1_ick_parent_names, aes2_ick_ops);
+
+DEFINE_CLK_OMAP_MUX_GATE(gpt1_fck, "wkup_clkdm", omap343x_gpt_clksel,
+			 OMAP_CM_REGADDR(WKUP_MOD, CM_CLKSEL),
+			 OMAP3430_CLKSEL_GPT1_MASK,
+			 OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN),
+			 OMAP3430_EN_GPT1_SHIFT, &clkhwops_wait,
+			 gpt10_fck_parent_names, clkout2_src_ck_ops);
+
+static struct clk gpt1_ick;
+
+static struct clk_hw_omap gpt1_ick_hw = {
+	.hw = {
+		.clk = &gpt1_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP3430_EN_GPT1_SHIFT,
+	.clkdm_name	= "wkup_clkdm",
+};
+
+DEFINE_STRUCT_CLK(gpt1_ick, gpio1_ick_parent_names, aes2_ick_ops);
+
+DEFINE_CLK_OMAP_MUX_GATE(gpt2_fck, "per_clkdm", omap343x_gpt_clksel,
+			 OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_CLKSEL),
+			 OMAP3430_CLKSEL_GPT2_MASK,
+			 OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
+			 OMAP3430_EN_GPT2_SHIFT, &clkhwops_wait,
+			 gpt10_fck_parent_names, clkout2_src_ck_ops);
+
+static struct clk gpt2_ick;
+
+static struct clk_hw_omap gpt2_ick_hw = {
+	.hw = {
+		.clk = &gpt2_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP3430_EN_GPT2_SHIFT,
+	.clkdm_name	= "per_clkdm",
+};
+
+DEFINE_STRUCT_CLK(gpt2_ick, gpio2_ick_parent_names, aes2_ick_ops);
+
+DEFINE_CLK_OMAP_MUX_GATE(gpt3_fck, "per_clkdm", omap343x_gpt_clksel,
+			 OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_CLKSEL),
+			 OMAP3430_CLKSEL_GPT3_MASK,
+			 OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
+			 OMAP3430_EN_GPT3_SHIFT, &clkhwops_wait,
+			 gpt10_fck_parent_names, clkout2_src_ck_ops);
+
+static struct clk gpt3_ick;
+
+static struct clk_hw_omap gpt3_ick_hw = {
+	.hw = {
+		.clk = &gpt3_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP3430_EN_GPT3_SHIFT,
+	.clkdm_name	= "per_clkdm",
+};
+
+DEFINE_STRUCT_CLK(gpt3_ick, gpio2_ick_parent_names, aes2_ick_ops);
+
+DEFINE_CLK_OMAP_MUX_GATE(gpt4_fck, "per_clkdm", omap343x_gpt_clksel,
+			 OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_CLKSEL),
+			 OMAP3430_CLKSEL_GPT4_MASK,
+			 OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
+			 OMAP3430_EN_GPT4_SHIFT, &clkhwops_wait,
+			 gpt10_fck_parent_names, clkout2_src_ck_ops);
+
+static struct clk gpt4_ick;
+
+static struct clk_hw_omap gpt4_ick_hw = {
+	.hw = {
+		.clk = &gpt4_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP3430_EN_GPT4_SHIFT,
+	.clkdm_name	= "per_clkdm",
+};
+
+DEFINE_STRUCT_CLK(gpt4_ick, gpio2_ick_parent_names, aes2_ick_ops);
+
+DEFINE_CLK_OMAP_MUX_GATE(gpt5_fck, "per_clkdm", omap343x_gpt_clksel,
+			 OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_CLKSEL),
+			 OMAP3430_CLKSEL_GPT5_MASK,
+			 OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
+			 OMAP3430_EN_GPT5_SHIFT, &clkhwops_wait,
+			 gpt10_fck_parent_names, clkout2_src_ck_ops);
+
+static struct clk gpt5_ick;
+
+static struct clk_hw_omap gpt5_ick_hw = {
+	.hw = {
+		.clk = &gpt5_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP3430_EN_GPT5_SHIFT,
+	.clkdm_name	= "per_clkdm",
+};
+
+DEFINE_STRUCT_CLK(gpt5_ick, gpio2_ick_parent_names, aes2_ick_ops);
+
+DEFINE_CLK_OMAP_MUX_GATE(gpt6_fck, "per_clkdm", omap343x_gpt_clksel,
+			 OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_CLKSEL),
+			 OMAP3430_CLKSEL_GPT6_MASK,
+			 OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
+			 OMAP3430_EN_GPT6_SHIFT, &clkhwops_wait,
+			 gpt10_fck_parent_names, clkout2_src_ck_ops);
+
+static struct clk gpt6_ick;
+
+static struct clk_hw_omap gpt6_ick_hw = {
+	.hw = {
+		.clk = &gpt6_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP3430_EN_GPT6_SHIFT,
+	.clkdm_name	= "per_clkdm",
+};
+
+DEFINE_STRUCT_CLK(gpt6_ick, gpio2_ick_parent_names, aes2_ick_ops);
+
+DEFINE_CLK_OMAP_MUX_GATE(gpt7_fck, "per_clkdm", omap343x_gpt_clksel,
+			 OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_CLKSEL),
+			 OMAP3430_CLKSEL_GPT7_MASK,
+			 OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
+			 OMAP3430_EN_GPT7_SHIFT, &clkhwops_wait,
+			 gpt10_fck_parent_names, clkout2_src_ck_ops);
+
+static struct clk gpt7_ick;
+
+static struct clk_hw_omap gpt7_ick_hw = {
+	.hw = {
+		.clk = &gpt7_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP3430_EN_GPT7_SHIFT,
+	.clkdm_name	= "per_clkdm",
+};
+
+DEFINE_STRUCT_CLK(gpt7_ick, gpio2_ick_parent_names, aes2_ick_ops);
+
+DEFINE_CLK_OMAP_MUX_GATE(gpt8_fck, "per_clkdm", omap343x_gpt_clksel,
+			 OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_CLKSEL),
+			 OMAP3430_CLKSEL_GPT8_MASK,
+			 OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
+			 OMAP3430_EN_GPT8_SHIFT, &clkhwops_wait,
+			 gpt10_fck_parent_names, clkout2_src_ck_ops);
+
+static struct clk gpt8_ick;
+
+static struct clk_hw_omap gpt8_ick_hw = {
+	.hw = {
+		.clk = &gpt8_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP3430_EN_GPT8_SHIFT,
+	.clkdm_name	= "per_clkdm",
+};
+
+DEFINE_STRUCT_CLK(gpt8_ick, gpio2_ick_parent_names, aes2_ick_ops);
+
+DEFINE_CLK_OMAP_MUX_GATE(gpt9_fck, "per_clkdm", omap343x_gpt_clksel,
+			 OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_CLKSEL),
+			 OMAP3430_CLKSEL_GPT9_MASK,
+			 OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
+			 OMAP3430_EN_GPT9_SHIFT, &clkhwops_wait,
+			 gpt10_fck_parent_names, clkout2_src_ck_ops);
+
+static struct clk gpt9_ick;
+
+static struct clk_hw_omap gpt9_ick_hw = {
+	.hw = {
+		.clk = &gpt9_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP3430_EN_GPT9_SHIFT,
+	.clkdm_name	= "per_clkdm",
+};
+
+DEFINE_STRUCT_CLK(gpt9_ick, gpio2_ick_parent_names, aes2_ick_ops);
+
+static struct clk hdq_fck;
+
+static const char *hdq_fck_parent_names[] = {
+	"core_12m_fck",
+};
+
+static struct clk_hw_omap hdq_fck_hw = {
+	.hw = {
+		.clk = &hdq_fck,
+	},
+	.ops		= &clkhwops_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP3430_EN_HDQ_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(hdq_fck, hdq_fck_parent_names, aes2_ick_ops);
+
+static struct clk hdq_ick;
+
+static struct clk_hw_omap hdq_ick_hw = {
+	.hw = {
+		.clk = &hdq_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP3430_EN_HDQ_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(hdq_ick, aes2_ick_parent_names, aes2_ick_ops);
+
+static struct clk hecc_ck;
+
+static struct clk_hw_omap hecc_ck_hw = {
+	.hw = {
+		.clk = &hecc_ck,
+	},
+	.ops		= &clkhwops_am35xx_ipss_module_wait,
+	.enable_reg	= OMAP343X_CTRL_REGADDR(AM35XX_CONTROL_IPSS_CLK_CTRL),
+	.enable_bit	= AM35XX_HECC_VBUSP_CLK_SHIFT,
+	.clkdm_name	= "core_l3_clkdm",
+};
+
+DEFINE_STRUCT_CLK(hecc_ck, dpll3_ck_parent_names, aes2_ick_ops);
+
+static struct clk hsotgusb_fck_am35xx;
+
+static struct clk_hw_omap hsotgusb_fck_am35xx_hw = {
+	.hw = {
+		.clk = &hsotgusb_fck_am35xx,
+	},
+	.enable_reg	= OMAP343X_CTRL_REGADDR(AM35XX_CONTROL_IPSS_CLK_CTRL),
+	.enable_bit	= AM35XX_USBOTG_FCLK_SHIFT,
+	.clkdm_name	= "core_l3_clkdm",
+};
+
+DEFINE_STRUCT_CLK(hsotgusb_fck_am35xx, dpll3_ck_parent_names, aes2_ick_ops);
+
+static struct clk hsotgusb_ick_3430es1;
+
+static struct clk_hw_omap hsotgusb_ick_3430es1_hw = {
+	.hw = {
+		.clk = &hsotgusb_ick_3430es1,
+	},
+	.ops		= &clkhwops_iclk,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP3430_EN_HSOTGUSB_SHIFT,
+	.clkdm_name	= "core_l3_clkdm",
+};
+
+DEFINE_STRUCT_CLK(hsotgusb_ick_3430es1, ipss_ick_parent_names, aes2_ick_ops);
+
+static struct clk hsotgusb_ick_3430es2;
+
+static struct clk_hw_omap hsotgusb_ick_3430es2_hw = {
+	.hw = {
+		.clk = &hsotgusb_ick_3430es2,
+	},
+	.ops		= &clkhwops_omap3430es2_iclk_hsotgusb_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP3430_EN_HSOTGUSB_SHIFT,
+	.clkdm_name	= "core_l3_clkdm",
+};
+
+DEFINE_STRUCT_CLK(hsotgusb_ick_3430es2, ipss_ick_parent_names, aes2_ick_ops);
+
+static struct clk hsotgusb_ick_am35xx;
+
+static struct clk_hw_omap hsotgusb_ick_am35xx_hw = {
+	.hw = {
+		.clk = &hsotgusb_ick_am35xx,
+	},
+	.ops		= &clkhwops_am35xx_ipss_module_wait,
+	.enable_reg	= OMAP343X_CTRL_REGADDR(AM35XX_CONTROL_IPSS_CLK_CTRL),
+	.enable_bit	= AM35XX_USBOTG_VBUSP_CLK_SHIFT,
+	.clkdm_name	= "core_l3_clkdm",
+};
+
+DEFINE_STRUCT_CLK(hsotgusb_ick_am35xx, emac_ick_parent_names, aes2_ick_ops);
+
+static struct clk i2c1_fck;
+
+static struct clk_hw_omap i2c1_fck_hw = {
+	.hw = {
+		.clk = &i2c1_fck,
+	},
+	.ops		= &clkhwops_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP3430_EN_I2C1_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(i2c1_fck, csi2_96m_fck_parent_names, aes2_ick_ops);
+
+static struct clk i2c1_ick;
+
+static struct clk_hw_omap i2c1_ick_hw = {
+	.hw = {
+		.clk = &i2c1_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP3430_EN_I2C1_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(i2c1_ick, aes2_ick_parent_names, aes2_ick_ops);
+
+static struct clk i2c2_fck;
+
+static struct clk_hw_omap i2c2_fck_hw = {
+	.hw = {
+		.clk = &i2c2_fck,
+	},
+	.ops		= &clkhwops_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP3430_EN_I2C2_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(i2c2_fck, csi2_96m_fck_parent_names, aes2_ick_ops);
+
+static struct clk i2c2_ick;
+
+static struct clk_hw_omap i2c2_ick_hw = {
+	.hw = {
+		.clk = &i2c2_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP3430_EN_I2C2_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(i2c2_ick, aes2_ick_parent_names, aes2_ick_ops);
+
+static struct clk i2c3_fck;
+
+static struct clk_hw_omap i2c3_fck_hw = {
+	.hw = {
+		.clk = &i2c3_fck,
+	},
+	.ops		= &clkhwops_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP3430_EN_I2C3_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(i2c3_fck, csi2_96m_fck_parent_names, aes2_ick_ops);
+
+static struct clk i2c3_ick;
+
+static struct clk_hw_omap i2c3_ick_hw = {
+	.hw = {
+		.clk = &i2c3_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP3430_EN_I2C3_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(i2c3_ick, aes2_ick_parent_names, aes2_ick_ops);
+
+static struct clk icr_ick;
+
+static struct clk_hw_omap icr_ick_hw = {
+	.hw = {
+		.clk = &icr_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP3430_EN_ICR_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(icr_ick, aes2_ick_parent_names, aes2_ick_ops);
+
+static struct clk iva2_ck;
+
+static const char *iva2_ck_parent_names[] = {
+	"dpll2_m2_ck",
+};
+
+static struct clk_hw_omap iva2_ck_hw = {
+	.hw = {
+		.clk = &iva2_ck,
+	},
+	.ops		= &clkhwops_wait,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_IVA2_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP3430_CM_FCLKEN_IVA2_EN_IVA2_SHIFT,
+	.clkdm_name	= "iva2_clkdm",
+};
+
+DEFINE_STRUCT_CLK(iva2_ck, iva2_ck_parent_names, aes2_ick_ops);
+
+static struct clk mad2d_ick;
+
+static struct clk_hw_omap mad2d_ick_hw = {
+	.hw = {
+		.clk = &mad2d_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN3),
+	.enable_bit	= OMAP3430_EN_MAD2D_SHIFT,
+	.clkdm_name	= "d2d_clkdm",
+};
+
+DEFINE_STRUCT_CLK(mad2d_ick, core_l3_ick_parent_names, aes2_ick_ops);
+
+static struct clk mailboxes_ick;
+
+static struct clk_hw_omap mailboxes_ick_hw = {
+	.hw = {
+		.clk = &mailboxes_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP3430_EN_MAILBOXES_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(mailboxes_ick, aes2_ick_parent_names, aes2_ick_ops);
+
+static const struct clksel_rate common_mcbsp_96m_rates[] = {
+	{ .div = 1, .val = 0, .flags = RATE_IN_3XXX },
+	{ .div = 0 }
+};
+
+static const struct clksel_rate common_mcbsp_mcbsp_rates[] = {
+	{ .div = 1, .val = 1, .flags = RATE_IN_3XXX },
+	{ .div = 0 }
+};
+
+static const struct clksel mcbsp_15_clksel[] = {
+	{ .parent = &core_96m_fck, .rates = common_mcbsp_96m_rates },
+	{ .parent = &mcbsp_clks, .rates = common_mcbsp_mcbsp_rates },
+	{ .parent = NULL },
+};
+
+static const char *mcbsp1_fck_parent_names[] = {
+	"core_96m_fck", "mcbsp_clks",
+};
+
+DEFINE_CLK_OMAP_MUX_GATE(mcbsp1_fck, "core_l4_clkdm", mcbsp_15_clksel,
+			 OMAP343X_CTRL_REGADDR(OMAP2_CONTROL_DEVCONF0),
+			 OMAP2_MCBSP1_CLKS_MASK,
+			 OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+			 OMAP3430_EN_MCBSP1_SHIFT, &clkhwops_wait,
+			 mcbsp1_fck_parent_names, clkout2_src_ck_ops);
+
+static struct clk mcbsp1_ick;
+
+static struct clk_hw_omap mcbsp1_ick_hw = {
+	.hw = {
+		.clk = &mcbsp1_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP3430_EN_MCBSP1_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(mcbsp1_ick, aes2_ick_parent_names, aes2_ick_ops);
+
+static struct clk per_96m_fck;
+
+DEFINE_STRUCT_CLK_HW_OMAP(per_96m_fck, "per_clkdm");
+DEFINE_STRUCT_CLK(per_96m_fck, cm_96m_fck_parent_names, core_l4_ick_ops);
+
+static const struct clksel mcbsp_234_clksel[] = {
+	{ .parent = &per_96m_fck, .rates = common_mcbsp_96m_rates },
+	{ .parent = &mcbsp_clks, .rates = common_mcbsp_mcbsp_rates },
+	{ .parent = NULL },
+};
+
+static const char *mcbsp2_fck_parent_names[] = {
+	"per_96m_fck", "mcbsp_clks",
+};
+
+DEFINE_CLK_OMAP_MUX_GATE(mcbsp2_fck, "per_clkdm", mcbsp_234_clksel,
+			 OMAP343X_CTRL_REGADDR(OMAP2_CONTROL_DEVCONF0),
+			 OMAP2_MCBSP2_CLKS_MASK,
+			 OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
+			 OMAP3430_EN_MCBSP2_SHIFT, &clkhwops_wait,
+			 mcbsp2_fck_parent_names, clkout2_src_ck_ops);
+
+static struct clk mcbsp2_ick;
+
+static struct clk_hw_omap mcbsp2_ick_hw = {
+	.hw = {
+		.clk = &mcbsp2_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP3430_EN_MCBSP2_SHIFT,
+	.clkdm_name	= "per_clkdm",
+};
+
+DEFINE_STRUCT_CLK(mcbsp2_ick, gpio2_ick_parent_names, aes2_ick_ops);
+
+DEFINE_CLK_OMAP_MUX_GATE(mcbsp3_fck, "per_clkdm", mcbsp_234_clksel,
+			 OMAP343X_CTRL_REGADDR(OMAP343X_CONTROL_DEVCONF1),
+			 OMAP2_MCBSP3_CLKS_MASK,
+			 OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
+			 OMAP3430_EN_MCBSP3_SHIFT, &clkhwops_wait,
+			 mcbsp2_fck_parent_names, clkout2_src_ck_ops);
+
+static struct clk mcbsp3_ick;
+
+static struct clk_hw_omap mcbsp3_ick_hw = {
+	.hw = {
+		.clk = &mcbsp3_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP3430_EN_MCBSP3_SHIFT,
+	.clkdm_name	= "per_clkdm",
+};
+
+DEFINE_STRUCT_CLK(mcbsp3_ick, gpio2_ick_parent_names, aes2_ick_ops);
+
+DEFINE_CLK_OMAP_MUX_GATE(mcbsp4_fck, "per_clkdm", mcbsp_234_clksel,
+			 OMAP343X_CTRL_REGADDR(OMAP343X_CONTROL_DEVCONF1),
+			 OMAP2_MCBSP4_CLKS_MASK,
+			 OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
+			 OMAP3430_EN_MCBSP4_SHIFT, &clkhwops_wait,
+			 mcbsp2_fck_parent_names, clkout2_src_ck_ops);
+
+static struct clk mcbsp4_ick;
+
+static struct clk_hw_omap mcbsp4_ick_hw = {
+	.hw = {
+		.clk = &mcbsp4_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP3430_EN_MCBSP4_SHIFT,
+	.clkdm_name	= "per_clkdm",
+};
+
+DEFINE_STRUCT_CLK(mcbsp4_ick, gpio2_ick_parent_names, aes2_ick_ops);
+
+DEFINE_CLK_OMAP_MUX_GATE(mcbsp5_fck, "core_l4_clkdm", mcbsp_15_clksel,
+			 OMAP343X_CTRL_REGADDR(OMAP343X_CONTROL_DEVCONF1),
+			 OMAP2_MCBSP5_CLKS_MASK,
+			 OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+			 OMAP3430_EN_MCBSP5_SHIFT, &clkhwops_wait,
+			 mcbsp1_fck_parent_names, clkout2_src_ck_ops);
+
+static struct clk mcbsp5_ick;
+
+static struct clk_hw_omap mcbsp5_ick_hw = {
+	.hw = {
+		.clk = &mcbsp5_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP3430_EN_MCBSP5_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(mcbsp5_ick, aes2_ick_parent_names, aes2_ick_ops);
+
+static struct clk mcspi1_fck;
+
+static struct clk_hw_omap mcspi1_fck_hw = {
+	.hw = {
+		.clk = &mcspi1_fck,
+	},
+	.ops		= &clkhwops_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP3430_EN_MCSPI1_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(mcspi1_fck, fshostusb_fck_parent_names, aes2_ick_ops);
+
+static struct clk mcspi1_ick;
+
+static struct clk_hw_omap mcspi1_ick_hw = {
+	.hw = {
+		.clk = &mcspi1_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP3430_EN_MCSPI1_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(mcspi1_ick, aes2_ick_parent_names, aes2_ick_ops);
+
+static struct clk mcspi2_fck;
+
+static struct clk_hw_omap mcspi2_fck_hw = {
+	.hw = {
+		.clk = &mcspi2_fck,
+	},
+	.ops		= &clkhwops_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP3430_EN_MCSPI2_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(mcspi2_fck, fshostusb_fck_parent_names, aes2_ick_ops);
+
+static struct clk mcspi2_ick;
+
+static struct clk_hw_omap mcspi2_ick_hw = {
+	.hw = {
+		.clk = &mcspi2_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP3430_EN_MCSPI2_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(mcspi2_ick, aes2_ick_parent_names, aes2_ick_ops);
+
+static struct clk mcspi3_fck;
+
+static struct clk_hw_omap mcspi3_fck_hw = {
+	.hw = {
+		.clk = &mcspi3_fck,
+	},
+	.ops		= &clkhwops_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP3430_EN_MCSPI3_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(mcspi3_fck, fshostusb_fck_parent_names, aes2_ick_ops);
+
+static struct clk mcspi3_ick;
+
+static struct clk_hw_omap mcspi3_ick_hw = {
+	.hw = {
+		.clk = &mcspi3_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP3430_EN_MCSPI3_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(mcspi3_ick, aes2_ick_parent_names, aes2_ick_ops);
+
+static struct clk mcspi4_fck;
+
+static struct clk_hw_omap mcspi4_fck_hw = {
+	.hw = {
+		.clk = &mcspi4_fck,
+	},
+	.ops		= &clkhwops_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP3430_EN_MCSPI4_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(mcspi4_fck, fshostusb_fck_parent_names, aes2_ick_ops);
+
+static struct clk mcspi4_ick;
+
+static struct clk_hw_omap mcspi4_ick_hw = {
+	.hw = {
+		.clk = &mcspi4_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP3430_EN_MCSPI4_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(mcspi4_ick, aes2_ick_parent_names, aes2_ick_ops);
+
+static struct clk mmchs1_fck;
+
+static struct clk_hw_omap mmchs1_fck_hw = {
+	.hw = {
+		.clk = &mmchs1_fck,
+	},
+	.ops		= &clkhwops_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP3430_EN_MMC1_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(mmchs1_fck, csi2_96m_fck_parent_names, aes2_ick_ops);
+
+static struct clk mmchs1_ick;
+
+static struct clk_hw_omap mmchs1_ick_hw = {
+	.hw = {
+		.clk = &mmchs1_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP3430_EN_MMC1_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(mmchs1_ick, aes2_ick_parent_names, aes2_ick_ops);
+
+static struct clk mmchs2_fck;
+
+static struct clk_hw_omap mmchs2_fck_hw = {
+	.hw = {
+		.clk = &mmchs2_fck,
+	},
+	.ops		= &clkhwops_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP3430_EN_MMC2_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(mmchs2_fck, csi2_96m_fck_parent_names, aes2_ick_ops);
+
+static struct clk mmchs2_ick;
+
+static struct clk_hw_omap mmchs2_ick_hw = {
+	.hw = {
+		.clk = &mmchs2_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP3430_EN_MMC2_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(mmchs2_ick, aes2_ick_parent_names, aes2_ick_ops);
+
+static struct clk mmchs3_fck;
+
+static struct clk_hw_omap mmchs3_fck_hw = {
+	.hw = {
+		.clk = &mmchs3_fck,
+	},
+	.ops		= &clkhwops_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP3430ES2_EN_MMC3_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(mmchs3_fck, csi2_96m_fck_parent_names, aes2_ick_ops);
+
+static struct clk mmchs3_ick;
+
+static struct clk_hw_omap mmchs3_ick_hw = {
+	.hw = {
+		.clk = &mmchs3_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP3430ES2_EN_MMC3_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(mmchs3_ick, aes2_ick_parent_names, aes2_ick_ops);
+
+static struct clk modem_fck;
+
+static struct clk_hw_omap modem_fck_hw = {
+	.hw = {
+		.clk = &modem_fck,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP3430_EN_MODEM_SHIFT,
+	.clkdm_name	= "d2d_clkdm",
+};
+
+DEFINE_STRUCT_CLK(modem_fck, dpll3_ck_parent_names, aes2_ick_ops);
+
+static struct clk mspro_fck;
+
+static struct clk_hw_omap mspro_fck_hw = {
+	.hw = {
+		.clk = &mspro_fck,
+	},
+	.ops		= &clkhwops_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP3430_EN_MSPRO_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(mspro_fck, csi2_96m_fck_parent_names, aes2_ick_ops);
+
+static struct clk mspro_ick;
+
+static struct clk_hw_omap mspro_ick_hw = {
+	.hw = {
+		.clk = &mspro_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP3430_EN_MSPRO_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(mspro_ick, aes2_ick_parent_names, aes2_ick_ops);
+
+static struct clk omap_192m_alwon_fck;
+
+DEFINE_STRUCT_CLK_HW_OMAP(omap_192m_alwon_fck, NULL);
+DEFINE_STRUCT_CLK(omap_192m_alwon_fck, omap_96m_alwon_fck_parent_names,
+		  core_ck_ops);
+
+static struct clk omap_32ksync_ick;
+
+static struct clk_hw_omap omap_32ksync_ick_hw = {
+	.hw = {
+		.clk = &omap_32ksync_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP3430_EN_32KSYNC_SHIFT,
+	.clkdm_name	= "wkup_clkdm",
+};
+
+DEFINE_STRUCT_CLK(omap_32ksync_ick, gpio1_ick_parent_names, aes2_ick_ops);
+
+static const struct clksel_rate omap_96m_alwon_fck_rates[] = {
+	{ .div = 1, .val = 1, .flags = RATE_IN_36XX },
+	{ .div = 2, .val = 2, .flags = RATE_IN_36XX },
+	{ .div = 0 }
+};
+
+static const struct clksel omap_96m_alwon_fck_clksel[] = {
+	{ .parent = &omap_192m_alwon_fck, .rates = omap_96m_alwon_fck_rates },
+	{ .parent = NULL }
+};
+
+static struct clk omap_96m_alwon_fck_3630;
+
+static const char *omap_96m_alwon_fck_3630_parent_names[] = {
+	"omap_192m_alwon_fck",
+};
+
+static const struct clk_ops omap_96m_alwon_fck_3630_ops = {
+	.set_rate	= &omap2_clksel_set_rate,
+	.recalc_rate	= &omap2_clksel_recalc,
+	.round_rate	= &omap2_clksel_round_rate,
+};
+
+static struct clk_hw_omap omap_96m_alwon_fck_3630_hw = {
+	.hw = {
+		.clk = &omap_96m_alwon_fck_3630,
+	},
+	.clksel		= omap_96m_alwon_fck_clksel,
+	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL),
+	.clksel_mask	= OMAP3630_CLKSEL_96M_MASK,
+};
+
+static struct clk omap_96m_alwon_fck_3630 = {
+	.name	= "omap_96m_alwon_fck",
+	.hw	= &omap_96m_alwon_fck_3630_hw.hw,
+	.parent_names	= omap_96m_alwon_fck_3630_parent_names,
+	.num_parents	= ARRAY_SIZE(omap_96m_alwon_fck_3630_parent_names),
+	.ops	= &omap_96m_alwon_fck_3630_ops,
+};
+
+static struct clk omapctrl_ick;
+
+static struct clk_hw_omap omapctrl_ick_hw = {
+	.hw = {
+		.clk = &omapctrl_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP3430_EN_OMAPCTRL_SHIFT,
+	.flags		= ENABLE_ON_INIT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(omapctrl_ick, aes2_ick_parent_names, aes2_ick_ops);
+
+DEFINE_CLK_DIVIDER(pclk_fck, "emu_src_ck", &emu_src_ck, 0x0,
+		   OMAP_CM_REGADDR(OMAP3430_EMU_MOD, CM_CLKSEL1),
+		   OMAP3430_CLKSEL_PCLK_SHIFT, OMAP3430_CLKSEL_PCLK_WIDTH,
+		   CLK_DIVIDER_ONE_BASED, NULL);
+
+DEFINE_CLK_DIVIDER(pclkx2_fck, "emu_src_ck", &emu_src_ck, 0x0,
+		   OMAP_CM_REGADDR(OMAP3430_EMU_MOD, CM_CLKSEL1),
+		   OMAP3430_CLKSEL_PCLKX2_SHIFT, OMAP3430_CLKSEL_PCLKX2_WIDTH,
+		   CLK_DIVIDER_ONE_BASED, NULL);
+
+static struct clk per_48m_fck;
+
+DEFINE_STRUCT_CLK_HW_OMAP(per_48m_fck, "per_clkdm");
+DEFINE_STRUCT_CLK(per_48m_fck, core_48m_fck_parent_names, core_l4_ick_ops);
+
+static struct clk security_l3_ick;
+
+DEFINE_STRUCT_CLK_HW_OMAP(security_l3_ick, NULL);
+DEFINE_STRUCT_CLK(security_l3_ick, core_l3_ick_parent_names, core_ck_ops);
+
+static struct clk pka_ick;
+
+static const char *pka_ick_parent_names[] = {
+	"security_l3_ick",
+};
+
+static struct clk_hw_omap pka_ick_hw = {
+	.hw = {
+		.clk = &pka_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
+	.enable_bit	= OMAP3430_EN_PKA_SHIFT,
+};
+
+DEFINE_STRUCT_CLK(pka_ick, pka_ick_parent_names, aes1_ick_ops);
+
+DEFINE_CLK_DIVIDER(rm_ick, "l4_ick", &l4_ick, 0x0,
+		   OMAP_CM_REGADDR(WKUP_MOD, CM_CLKSEL),
+		   OMAP3430_CLKSEL_RM_SHIFT, OMAP3430_CLKSEL_RM_WIDTH,
+		   CLK_DIVIDER_ONE_BASED, NULL);
+
+static struct clk rng_ick;
+
+static struct clk_hw_omap rng_ick_hw = {
+	.hw = {
+		.clk = &rng_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
+	.enable_bit	= OMAP3430_EN_RNG_SHIFT,
+};
+
+DEFINE_STRUCT_CLK(rng_ick, aes1_ick_parent_names, aes1_ick_ops);
+
+static struct clk sad2d_ick;
+
+static struct clk_hw_omap sad2d_ick_hw = {
+	.hw = {
+		.clk = &sad2d_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP3430_EN_SAD2D_SHIFT,
+	.clkdm_name	= "d2d_clkdm",
+};
+
+DEFINE_STRUCT_CLK(sad2d_ick, core_l3_ick_parent_names, aes2_ick_ops);
+
+static struct clk sdrc_ick;
+
+static struct clk_hw_omap sdrc_ick_hw = {
+	.hw = {
+		.clk = &sdrc_ick,
+	},
+	.ops		= &clkhwops_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP3430_EN_SDRC_SHIFT,
+	.flags		= ENABLE_ON_INIT,
+	.clkdm_name	= "core_l3_clkdm",
+};
+
+DEFINE_STRUCT_CLK(sdrc_ick, ipss_ick_parent_names, aes2_ick_ops);
+
+static const struct clksel_rate sgx_core_rates[] = {
+	{ .div = 2, .val = 5, .flags = RATE_IN_36XX },
+	{ .div = 3, .val = 0, .flags = RATE_IN_3XXX },
+	{ .div = 4, .val = 1, .flags = RATE_IN_3XXX },
+	{ .div = 6, .val = 2, .flags = RATE_IN_3XXX },
+	{ .div = 0 }
+};
+
+static const struct clksel_rate sgx_96m_rates[] = {
+	{ .div = 1, .val = 3, .flags = RATE_IN_3XXX },
+	{ .div = 0 }
+};
+
+static const struct clksel_rate sgx_192m_rates[] = {
+	{ .div = 1, .val = 4, .flags = RATE_IN_36XX },
+	{ .div = 0 }
+};
+
+static const struct clksel_rate sgx_corex2_rates[] = {
+	{ .div = 3, .val = 6, .flags = RATE_IN_36XX },
+	{ .div = 5, .val = 7, .flags = RATE_IN_36XX },
+	{ .div = 0 }
+};
+
+static const struct clksel sgx_clksel[] = {
+	{ .parent = &core_ck, .rates = sgx_core_rates },
+	{ .parent = &cm_96m_fck, .rates = sgx_96m_rates },
+	{ .parent = &omap_192m_alwon_fck, .rates = sgx_192m_rates },
+	{ .parent = &corex2_fck, .rates = sgx_corex2_rates },
+	{ .parent = NULL },
+};
+
+static const char *sgx_fck_parent_names[] = {
+	"core_ck", "cm_96m_fck", "omap_192m_alwon_fck", "corex2_fck",
+};
+
+static struct clk sgx_fck;
+
+static const struct clk_ops sgx_fck_ops = {
+	.init		= &omap2_init_clk_clkdm,
+	.enable		= &omap2_dflt_clk_enable,
+	.disable	= &omap2_dflt_clk_disable,
+	.is_enabled	= &omap2_dflt_clk_is_enabled,
+	.recalc_rate	= &omap2_clksel_recalc,
+	.set_rate	= &omap2_clksel_set_rate,
+	.round_rate	= &omap2_clksel_round_rate,
+	.get_parent	= &omap2_clksel_find_parent_index,
+	.set_parent	= &omap2_clksel_set_parent,
+};
+
+DEFINE_CLK_OMAP_MUX_GATE(sgx_fck, "sgx_clkdm", sgx_clksel,
+			 OMAP_CM_REGADDR(OMAP3430ES2_SGX_MOD, CM_CLKSEL),
+			 OMAP3430ES2_CLKSEL_SGX_MASK,
+			 OMAP_CM_REGADDR(OMAP3430ES2_SGX_MOD, CM_FCLKEN),
+			 OMAP3430ES2_CM_FCLKEN_SGX_EN_SGX_SHIFT,
+			 &clkhwops_wait, sgx_fck_parent_names, sgx_fck_ops);
+
+static struct clk sgx_ick;
+
+static struct clk_hw_omap sgx_ick_hw = {
+	.hw = {
+		.clk = &sgx_ick,
+	},
+	.ops		= &clkhwops_wait,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430ES2_SGX_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP3430ES2_CM_ICLKEN_SGX_EN_SGX_SHIFT,
+	.clkdm_name	= "sgx_clkdm",
+};
+
+DEFINE_STRUCT_CLK(sgx_ick, core_l3_ick_parent_names, aes2_ick_ops);
+
+static struct clk sha11_ick;
+
+static struct clk_hw_omap sha11_ick_hw = {
+	.hw = {
+		.clk = &sha11_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
+	.enable_bit	= OMAP3430_EN_SHA11_SHIFT,
+};
+
+DEFINE_STRUCT_CLK(sha11_ick, aes1_ick_parent_names, aes1_ick_ops);
+
+static struct clk sha12_ick;
+
+static struct clk_hw_omap sha12_ick_hw = {
+	.hw = {
+		.clk = &sha12_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP3430_EN_SHA12_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(sha12_ick, aes2_ick_parent_names, aes2_ick_ops);
+
+static struct clk sr1_fck;
+
+static struct clk_hw_omap sr1_fck_hw = {
+	.hw = {
+		.clk = &sr1_fck,
+	},
+	.ops		= &clkhwops_wait,
+	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP3430_EN_SR1_SHIFT,
+	.clkdm_name	= "wkup_clkdm",
+};
+
+DEFINE_STRUCT_CLK(sr1_fck, dpll3_ck_parent_names, aes2_ick_ops);
+
+static struct clk sr2_fck;
+
+static struct clk_hw_omap sr2_fck_hw = {
+	.hw = {
+		.clk = &sr2_fck,
+	},
+	.ops		= &clkhwops_wait,
+	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP3430_EN_SR2_SHIFT,
+	.clkdm_name	= "wkup_clkdm",
+};
+
+DEFINE_STRUCT_CLK(sr2_fck, dpll3_ck_parent_names, aes2_ick_ops);
+
+static struct clk sr_l4_ick;
+
+DEFINE_STRUCT_CLK_HW_OMAP(sr_l4_ick, "core_l4_clkdm");
+DEFINE_STRUCT_CLK(sr_l4_ick, security_l4_ick2_parent_names, core_l4_ick_ops);
+
+static struct clk ssi_l4_ick;
+
+DEFINE_STRUCT_CLK_HW_OMAP(ssi_l4_ick, "core_l4_clkdm");
+DEFINE_STRUCT_CLK(ssi_l4_ick, security_l4_ick2_parent_names, core_l4_ick_ops);
+
+static struct clk ssi_ick_3430es1;
+
+static const char *ssi_ick_3430es1_parent_names[] = {
+	"ssi_l4_ick",
+};
+
+static struct clk_hw_omap ssi_ick_3430es1_hw = {
+	.hw = {
+		.clk = &ssi_ick_3430es1,
+	},
+	.ops		= &clkhwops_iclk,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP3430_EN_SSI_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(ssi_ick_3430es1, ssi_ick_3430es1_parent_names, aes2_ick_ops);
+
+static struct clk ssi_ick_3430es2;
+
+static struct clk_hw_omap ssi_ick_3430es2_hw = {
+	.hw = {
+		.clk = &ssi_ick_3430es2,
+	},
+	.ops		= &clkhwops_omap3430es2_iclk_ssi_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP3430_EN_SSI_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(ssi_ick_3430es2, ssi_ick_3430es1_parent_names, aes2_ick_ops);
+
+static const struct clksel_rate ssi_ssr_corex2_rates[] = {
+	{ .div = 1, .val = 1, .flags = RATE_IN_3XXX },
+	{ .div = 2, .val = 2, .flags = RATE_IN_3XXX },
+	{ .div = 3, .val = 3, .flags = RATE_IN_3XXX },
+	{ .div = 4, .val = 4, .flags = RATE_IN_3XXX },
+	{ .div = 6, .val = 6, .flags = RATE_IN_3XXX },
+	{ .div = 8, .val = 8, .flags = RATE_IN_3XXX },
+	{ .div = 0 }
+};
+
+static const struct clksel ssi_ssr_clksel[] = {
+	{ .parent = &corex2_fck, .rates = ssi_ssr_corex2_rates },
+	{ .parent = NULL },
+};
+
+static const char *ssi_ssr_fck_3430es1_parent_names[] = {
+	"corex2_fck",
+};
+
+static const struct clk_ops ssi_ssr_fck_3430es1_ops = {
+	.init		= &omap2_init_clk_clkdm,
+	.enable		= &omap2_dflt_clk_enable,
+	.disable	= &omap2_dflt_clk_disable,
+	.is_enabled	= &omap2_dflt_clk_is_enabled,
+	.recalc_rate	= &omap2_clksel_recalc,
+	.set_rate	= &omap2_clksel_set_rate,
+	.round_rate	= &omap2_clksel_round_rate,
+};
+
+DEFINE_CLK_OMAP_MUX_GATE(ssi_ssr_fck_3430es1, "core_l4_clkdm",
+			 ssi_ssr_clksel, OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL),
+			 OMAP3430_CLKSEL_SSI_MASK,
+			 OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+			 OMAP3430_EN_SSI_SHIFT,
+			 NULL, ssi_ssr_fck_3430es1_parent_names,
+			 ssi_ssr_fck_3430es1_ops);
+
+DEFINE_CLK_OMAP_MUX_GATE(ssi_ssr_fck_3430es2, "core_l4_clkdm",
+			 ssi_ssr_clksel, OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL),
+			 OMAP3430_CLKSEL_SSI_MASK,
+			 OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+			 OMAP3430_EN_SSI_SHIFT,
+			 NULL, ssi_ssr_fck_3430es1_parent_names,
+			 ssi_ssr_fck_3430es1_ops);
+
+DEFINE_CLK_FIXED_FACTOR(ssi_sst_fck_3430es1, "ssi_ssr_fck_3430es1",
+			&ssi_ssr_fck_3430es1, 0x0, 1, 2);
+
+DEFINE_CLK_FIXED_FACTOR(ssi_sst_fck_3430es2, "ssi_ssr_fck_3430es2",
+			&ssi_ssr_fck_3430es2, 0x0, 1, 2);
+
+static struct clk sys_clkout1;
+
+static const char *sys_clkout1_parent_names[] = {
+	"osc_sys_ck",
+};
+
+static struct clk_hw_omap sys_clkout1_hw = {
+	.hw = {
+		.clk = &sys_clkout1,
+	},
+	.enable_reg	= OMAP3430_PRM_CLKOUT_CTRL,
+	.enable_bit	= OMAP3430_CLKOUT_EN_SHIFT,
+};
+
+DEFINE_STRUCT_CLK(sys_clkout1, sys_clkout1_parent_names, aes1_ick_ops);
+
+DEFINE_CLK_DIVIDER(sys_clkout2, "clkout2_src_ck", &clkout2_src_ck, 0x0,
+		   OMAP3430_CM_CLKOUT_CTRL, OMAP3430_CLKOUT2_DIV_SHIFT,
+		   OMAP3430_CLKOUT2_DIV_WIDTH, CLK_DIVIDER_POWER_OF_TWO, NULL);
+
+DEFINE_CLK_MUX(traceclk_src_fck, emu_src_ck_parent_names, NULL, 0x0,
+	       OMAP_CM_REGADDR(OMAP3430_EMU_MOD, CM_CLKSEL1),
+	       OMAP3430_TRACE_MUX_CTRL_SHIFT, OMAP3430_TRACE_MUX_CTRL_WIDTH,
+	       0x0, NULL);
+
+DEFINE_CLK_DIVIDER(traceclk_fck, "traceclk_src_fck", &traceclk_src_fck, 0x0,
+		   OMAP_CM_REGADDR(OMAP3430_EMU_MOD, CM_CLKSEL1),
+		   OMAP3430_CLKSEL_TRACECLK_SHIFT,
+		   OMAP3430_CLKSEL_TRACECLK_WIDTH, CLK_DIVIDER_ONE_BASED, NULL);
+
+static struct clk ts_fck;
+
+static struct clk_hw_omap ts_fck_hw = {
+	.hw = {
+		.clk = &ts_fck,
+	},
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP3430ES2_CM_FCLKEN3),
+	.enable_bit	= OMAP3430ES2_EN_TS_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(ts_fck, wkup_32k_fck_parent_names, aes2_ick_ops);
+
+static struct clk uart1_fck;
+
+static struct clk_hw_omap uart1_fck_hw = {
+	.hw = {
+		.clk = &uart1_fck,
+	},
+	.ops		= &clkhwops_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP3430_EN_UART1_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(uart1_fck, fshostusb_fck_parent_names, aes2_ick_ops);
+
+static struct clk uart1_ick;
+
+static struct clk_hw_omap uart1_ick_hw = {
+	.hw = {
+		.clk = &uart1_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP3430_EN_UART1_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(uart1_ick, aes2_ick_parent_names, aes2_ick_ops);
+
+static struct clk uart2_fck;
+
+static struct clk_hw_omap uart2_fck_hw = {
+	.hw = {
+		.clk = &uart2_fck,
+	},
+	.ops		= &clkhwops_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= OMAP3430_EN_UART2_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(uart2_fck, fshostusb_fck_parent_names, aes2_ick_ops);
+
+static struct clk uart2_ick;
+
+static struct clk_hw_omap uart2_ick_hw = {
+	.hw = {
+		.clk = &uart2_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= OMAP3430_EN_UART2_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(uart2_ick, aes2_ick_parent_names, aes2_ick_ops);
+
+static struct clk uart3_fck;
+
+static const char *uart3_fck_parent_names[] = {
+	"per_48m_fck",
+};
+
+static struct clk_hw_omap uart3_fck_hw = {
+	.hw = {
+		.clk = &uart3_fck,
+	},
+	.ops		= &clkhwops_wait,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP3430_EN_UART3_SHIFT,
+	.clkdm_name	= "per_clkdm",
+};
+
+DEFINE_STRUCT_CLK(uart3_fck, uart3_fck_parent_names, aes2_ick_ops);
+
+static struct clk uart3_ick;
+
+static struct clk_hw_omap uart3_ick_hw = {
+	.hw = {
+		.clk = &uart3_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP3430_EN_UART3_SHIFT,
+	.clkdm_name	= "per_clkdm",
+};
+
+DEFINE_STRUCT_CLK(uart3_ick, gpio2_ick_parent_names, aes2_ick_ops);
+
+static struct clk uart4_fck;
+
+static struct clk_hw_omap uart4_fck_hw = {
+	.hw = {
+		.clk = &uart4_fck,
+	},
+	.ops		= &clkhwops_wait,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP3630_EN_UART4_SHIFT,
+	.clkdm_name	= "per_clkdm",
+};
+
+DEFINE_STRUCT_CLK(uart4_fck, uart3_fck_parent_names, aes2_ick_ops);
+
+static struct clk uart4_fck_am35xx;
+
+static struct clk_hw_omap uart4_fck_am35xx_hw = {
+	.hw = {
+		.clk = &uart4_fck_am35xx,
+	},
+	.ops		= &clkhwops_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+	.enable_bit	= AM35XX_EN_UART4_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(uart4_fck_am35xx, fshostusb_fck_parent_names, aes2_ick_ops);
+
+static struct clk uart4_ick;
+
+static struct clk_hw_omap uart4_ick_hw = {
+	.hw = {
+		.clk = &uart4_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP3630_EN_UART4_SHIFT,
+	.clkdm_name	= "per_clkdm",
+};
+
+DEFINE_STRUCT_CLK(uart4_ick, gpio2_ick_parent_names, aes2_ick_ops);
+
+static struct clk uart4_ick_am35xx;
+
+static struct clk_hw_omap uart4_ick_am35xx_hw = {
+	.hw = {
+		.clk = &uart4_ick_am35xx,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+	.enable_bit	= AM35XX_EN_UART4_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(uart4_ick_am35xx, aes2_ick_parent_names, aes2_ick_ops);
+
+static const struct clksel_rate div2_rates[] = {
+	{ .div = 1, .val = 1, .flags = RATE_IN_3XXX },
+	{ .div = 2, .val = 2, .flags = RATE_IN_3XXX },
+	{ .div = 0 }
+};
+
+static const struct clksel usb_l4_clksel[] = {
+	{ .parent = &l4_ick, .rates = div2_rates },
+	{ .parent = NULL },
+};
+
+static const char *usb_l4_ick_parent_names[] = {
+	"l4_ick",
+};
+
+DEFINE_CLK_OMAP_MUX_GATE(usb_l4_ick, "core_l4_clkdm", usb_l4_clksel,
+			 OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL),
+			 OMAP3430ES1_CLKSEL_FSHOSTUSB_MASK,
+			 OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+			 OMAP3430ES1_EN_FSHOSTUSB_SHIFT,
+			 &clkhwops_iclk_wait, usb_l4_ick_parent_names,
+			 ssi_ssr_fck_3430es1_ops);
+
+static struct clk usbhost_120m_fck;
+
+static const char *usbhost_120m_fck_parent_names[] = {
+	"dpll5_m2_ck",
+};
+
+static struct clk_hw_omap usbhost_120m_fck_hw = {
+	.hw = {
+		.clk = &usbhost_120m_fck,
+	},
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430ES2_USBHOST_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP3430ES2_EN_USBHOST2_SHIFT,
+	.clkdm_name	= "usbhost_clkdm",
+};
+
+DEFINE_STRUCT_CLK(usbhost_120m_fck, usbhost_120m_fck_parent_names,
+		  aes2_ick_ops);
+
+static struct clk usbhost_48m_fck;
+
+static struct clk_hw_omap usbhost_48m_fck_hw = {
+	.hw = {
+		.clk = &usbhost_48m_fck,
+	},
+	.ops		= &clkhwops_omap3430es2_dss_usbhost_wait,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430ES2_USBHOST_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP3430ES2_EN_USBHOST1_SHIFT,
+	.clkdm_name	= "usbhost_clkdm",
+};
+
+DEFINE_STRUCT_CLK(usbhost_48m_fck, core_48m_fck_parent_names, aes2_ick_ops);
+
+static struct clk usbhost_ick;
+
+static struct clk_hw_omap usbhost_ick_hw = {
+	.hw = {
+		.clk = &usbhost_ick,
+	},
+	.ops		= &clkhwops_omap3430es2_iclk_dss_usbhost_wait,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430ES2_USBHOST_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP3430ES2_EN_USBHOST_SHIFT,
+	.clkdm_name	= "usbhost_clkdm",
+};
+
+DEFINE_STRUCT_CLK(usbhost_ick, security_l4_ick2_parent_names, aes2_ick_ops);
+
+static struct clk usbtll_fck;
+
+static struct clk_hw_omap usbtll_fck_hw = {
+	.hw = {
+		.clk = &usbtll_fck,
+	},
+	.ops		= &clkhwops_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP3430ES2_CM_FCLKEN3),
+	.enable_bit	= OMAP3430ES2_EN_USBTLL_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(usbtll_fck, usbhost_120m_fck_parent_names, aes2_ick_ops);
+
+static struct clk usbtll_ick;
+
+static struct clk_hw_omap usbtll_ick_hw = {
+	.hw = {
+		.clk = &usbtll_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN3),
+	.enable_bit	= OMAP3430ES2_EN_USBTLL_SHIFT,
+	.clkdm_name	= "core_l4_clkdm",
+};
+
+DEFINE_STRUCT_CLK(usbtll_ick, aes2_ick_parent_names, aes2_ick_ops);
+
+static const struct clksel_rate usim_96m_rates[] = {
+	{ .div = 2, .val = 3, .flags = RATE_IN_3XXX },
+	{ .div = 4, .val = 4, .flags = RATE_IN_3XXX },
+	{ .div = 8, .val = 5, .flags = RATE_IN_3XXX },
+	{ .div = 10, .val = 6, .flags = RATE_IN_3XXX },
+	{ .div = 0 }
+};
+
+static const struct clksel_rate usim_120m_rates[] = {
+	{ .div = 4, .val = 7, .flags = RATE_IN_3XXX },
+	{ .div = 8, .val = 8, .flags = RATE_IN_3XXX },
+	{ .div = 16, .val = 9, .flags = RATE_IN_3XXX },
+	{ .div = 20, .val = 10, .flags = RATE_IN_3XXX },
+	{ .div = 0 }
+};
+
+static const struct clksel usim_clksel[] = {
+	{ .parent = &omap_96m_fck, .rates = usim_96m_rates },
+	{ .parent = &dpll5_m2_ck, .rates = usim_120m_rates },
+	{ .parent = &sys_ck, .rates = div2_rates },
+	{ .parent = NULL },
+};
+
+static const char *usim_fck_parent_names[] = {
+	"omap_96m_fck", "dpll5_m2_ck", "sys_ck",
+};
+
+static struct clk usim_fck;
+
+static const struct clk_ops usim_fck_ops = {
+	.enable		= &omap2_dflt_clk_enable,
+	.disable	= &omap2_dflt_clk_disable,
+	.is_enabled	= &omap2_dflt_clk_is_enabled,
+	.recalc_rate	= &omap2_clksel_recalc,
+	.get_parent	= &omap2_clksel_find_parent_index,
+	.set_parent	= &omap2_clksel_set_parent,
+};
+
+DEFINE_CLK_OMAP_MUX_GATE(usim_fck, NULL, usim_clksel,
+			 OMAP_CM_REGADDR(WKUP_MOD, CM_CLKSEL),
+			 OMAP3430ES2_CLKSEL_USIMOCP_MASK,
+			 OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN),
+			 OMAP3430ES2_EN_USIMOCP_SHIFT, &clkhwops_wait,
+			 usim_fck_parent_names, usim_fck_ops);
+
+static struct clk usim_ick;
+
+static struct clk_hw_omap usim_ick_hw = {
+	.hw = {
+		.clk = &usim_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP3430ES2_EN_USIMOCP_SHIFT,
+	.clkdm_name	= "wkup_clkdm",
+};
+
+DEFINE_STRUCT_CLK(usim_ick, gpio1_ick_parent_names, aes2_ick_ops);
+
+static struct clk vpfe_fck;
+
+static const char *vpfe_fck_parent_names[] = {
+	"pclk_ck",
+};
+
+static struct clk_hw_omap vpfe_fck_hw = {
+	.hw = {
+		.clk = &vpfe_fck,
+	},
+	.enable_reg	= OMAP343X_CTRL_REGADDR(AM35XX_CONTROL_IPSS_CLK_CTRL),
+	.enable_bit	= AM35XX_VPFE_FCLK_SHIFT,
+};
+
+DEFINE_STRUCT_CLK(vpfe_fck, vpfe_fck_parent_names, aes1_ick_ops);
+
+static struct clk vpfe_ick;
+
+static struct clk_hw_omap vpfe_ick_hw = {
+	.hw = {
+		.clk = &vpfe_ick,
+	},
+	.ops		= &clkhwops_am35xx_ipss_module_wait,
+	.enable_reg	= OMAP343X_CTRL_REGADDR(AM35XX_CONTROL_IPSS_CLK_CTRL),
+	.enable_bit	= AM35XX_VPFE_VBUSP_CLK_SHIFT,
+	.clkdm_name	= "core_l3_clkdm",
+};
+
+DEFINE_STRUCT_CLK(vpfe_ick, emac_ick_parent_names, aes2_ick_ops);
+
+static struct clk wdt1_fck;
+
+DEFINE_STRUCT_CLK_HW_OMAP(wdt1_fck, "wkup_clkdm");
+DEFINE_STRUCT_CLK(wdt1_fck, gpt12_fck_parent_names, core_l4_ick_ops);
+
+static struct clk wdt1_ick;
+
+static struct clk_hw_omap wdt1_ick_hw = {
+	.hw = {
+		.clk = &wdt1_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP3430_EN_WDT1_SHIFT,
+	.clkdm_name	= "wkup_clkdm",
+};
+
+DEFINE_STRUCT_CLK(wdt1_ick, gpio1_ick_parent_names, aes2_ick_ops);
+
+static struct clk wdt2_fck;
+
+static struct clk_hw_omap wdt2_fck_hw = {
+	.hw = {
+		.clk = &wdt2_fck,
+	},
+	.ops		= &clkhwops_wait,
+	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP3430_EN_WDT2_SHIFT,
+	.clkdm_name	= "wkup_clkdm",
+};
+
+DEFINE_STRUCT_CLK(wdt2_fck, gpio1_dbck_parent_names, aes2_ick_ops);
+
+static struct clk wdt2_ick;
+
+static struct clk_hw_omap wdt2_ick_hw = {
+	.hw = {
+		.clk = &wdt2_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP3430_EN_WDT2_SHIFT,
+	.clkdm_name	= "wkup_clkdm",
+};
+
+DEFINE_STRUCT_CLK(wdt2_ick, gpio1_ick_parent_names, aes2_ick_ops);
+
+static struct clk wdt3_fck;
+
+static struct clk_hw_omap wdt3_fck_hw = {
+	.hw = {
+		.clk = &wdt3_fck,
+	},
+	.ops		= &clkhwops_wait,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
+	.enable_bit	= OMAP3430_EN_WDT3_SHIFT,
+	.clkdm_name	= "per_clkdm",
+};
+
+DEFINE_STRUCT_CLK(wdt3_fck, gpio2_dbck_parent_names, aes2_ick_ops);
+
+static struct clk wdt3_ick;
+
+static struct clk_hw_omap wdt3_ick_hw = {
+	.hw = {
+		.clk = &wdt3_ick,
+	},
+	.ops		= &clkhwops_iclk_wait,
+	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
+	.enable_bit	= OMAP3430_EN_WDT3_SHIFT,
+	.clkdm_name	= "per_clkdm",
+};
+
+DEFINE_STRUCT_CLK(wdt3_ick, gpio2_ick_parent_names, aes2_ick_ops);
+
+/*
+ * clkdev
+ */
+static struct omap_clk omap3xxx_clks[] = {
+	CLK(NULL,	"apb_pclk",	&dummy_apb_pclk,	CK_3XXX),
+	CLK(NULL,	"omap_32k_fck",	&omap_32k_fck,	CK_3XXX),
+	CLK(NULL,	"virt_12m_ck",	&virt_12m_ck,	CK_3XXX),
+	CLK(NULL,	"virt_13m_ck",	&virt_13m_ck,	CK_3XXX),
+	CLK(NULL,	"virt_16_8m_ck", &virt_16_8m_ck, CK_3430ES2PLUS | CK_AM35XX  | CK_36XX),
+	CLK(NULL,	"virt_19200000_ck", &virt_19200000_ck, CK_3XXX),
+	CLK(NULL,	"virt_26000000_ck", &virt_26000000_ck, CK_3XXX),
+	CLK(NULL,	"virt_38_4m_ck", &virt_38_4m_ck, CK_3XXX),
+	CLK(NULL,	"osc_sys_ck",	&osc_sys_ck,	CK_3XXX),
+	CLK("twl",	"fck",		&osc_sys_ck,	CK_3XXX),
+	CLK(NULL,	"sys_ck",	&sys_ck,	CK_3XXX),
+	CLK(NULL,	"sys_altclk",	&sys_altclk,	CK_3XXX),
+	CLK(NULL,	"mcbsp_clks",	&mcbsp_clks,	CK_3XXX),
+	CLK(NULL,	"sys_clkout1",	&sys_clkout1,	CK_3XXX),
+	CLK(NULL,	"dpll1_ck",	&dpll1_ck,	CK_3XXX),
+	CLK(NULL,	"dpll1_x2_ck",	&dpll1_x2_ck,	CK_3XXX),
+	CLK(NULL,	"dpll1_x2m2_ck", &dpll1_x2m2_ck, CK_3XXX),
+	CLK(NULL,	"dpll2_ck",	&dpll2_ck,	CK_34XX | CK_36XX),
+	CLK(NULL,	"dpll2_m2_ck",	&dpll2_m2_ck,	CK_34XX | CK_36XX),
+	CLK(NULL,	"dpll3_ck",	&dpll3_ck,	CK_3XXX),
+	CLK(NULL,	"core_ck",	&core_ck,	CK_3XXX),
+	CLK(NULL,	"dpll3_x2_ck",	&dpll3_x2_ck,	CK_3XXX),
+	CLK(NULL,	"dpll3_m2_ck",	&dpll3_m2_ck,	CK_3XXX),
+	CLK(NULL,	"dpll3_m2x2_ck", &dpll3_m2x2_ck, CK_3XXX),
+	CLK(NULL,	"dpll3_m3_ck",	&dpll3_m3_ck,	CK_3XXX),
+	CLK(NULL,	"dpll3_m3x2_ck", &dpll3_m3x2_ck, CK_3XXX),
+	CLK("etb",	"emu_core_alwon_ck", &emu_core_alwon_ck, CK_3XXX),
+	CLK(NULL,	"dpll4_ck",	&dpll4_ck,	CK_3XXX),
+	CLK(NULL,	"dpll4_x2_ck",	&dpll4_x2_ck,	CK_3XXX),
+	CLK(NULL,	"omap_192m_alwon_fck", &omap_192m_alwon_fck, CK_36XX),
+	CLK(NULL,	"omap_96m_alwon_fck", &omap_96m_alwon_fck, CK_3XXX),
+	CLK(NULL,	"omap_96m_fck",	&omap_96m_fck,	CK_3XXX),
+	CLK(NULL,	"cm_96m_fck",	&cm_96m_fck,	CK_3XXX),
+	CLK(NULL,	"omap_54m_fck",	&omap_54m_fck,	CK_3XXX),
+	CLK(NULL,	"omap_48m_fck",	&omap_48m_fck,	CK_3XXX),
+	CLK(NULL,	"omap_12m_fck",	&omap_12m_fck,	CK_3XXX),
+	CLK(NULL,	"dpll4_m2_ck",	&dpll4_m2_ck,	CK_3XXX),
+	CLK(NULL,	"dpll4_m2x2_ck", &dpll4_m2x2_ck, CK_3XXX),
+	CLK(NULL,	"dpll4_m3_ck",	&dpll4_m3_ck,	CK_3XXX),
+	CLK(NULL,	"dpll4_m3x2_ck", &dpll4_m3x2_ck, CK_3XXX),
+	CLK(NULL,	"dpll4_m4_ck",	&dpll4_m4_ck,	CK_3XXX),
+	CLK(NULL,	"dpll4_m4x2_ck", &dpll4_m4x2_ck, CK_3XXX),
+	CLK(NULL,	"dpll4_m5_ck",	&dpll4_m5_ck,	CK_3XXX),
+	CLK(NULL,	"dpll4_m5x2_ck", &dpll4_m5x2_ck, CK_3XXX),
+	CLK(NULL,	"dpll4_m6_ck",	&dpll4_m6_ck,	CK_3XXX),
+	CLK(NULL,	"dpll4_m6x2_ck", &dpll4_m6x2_ck, CK_3XXX),
+	CLK("etb",	"emu_per_alwon_ck", &emu_per_alwon_ck, CK_3XXX),
+	CLK(NULL,	"dpll5_ck",	&dpll5_ck,	CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
+	CLK(NULL,	"dpll5_m2_ck",	&dpll5_m2_ck,	CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
+	CLK(NULL,	"clkout2_src_ck", &clkout2_src_ck, CK_3XXX),
+	CLK(NULL,	"sys_clkout2",	&sys_clkout2,	CK_3XXX),
+	CLK(NULL,	"corex2_fck",	&corex2_fck,	CK_3XXX),
+	CLK(NULL,	"dpll1_fck",	&dpll1_fck,	CK_3XXX),
+	CLK(NULL,	"mpu_ck",	&mpu_ck,	CK_3XXX),
+	CLK(NULL,	"arm_fck",	&arm_fck,	CK_3XXX),
+	CLK("etb",	"emu_mpu_alwon_ck", &emu_mpu_alwon_ck, CK_3XXX),
+	CLK(NULL,	"dpll2_fck",	&dpll2_fck,	CK_34XX | CK_36XX),
+	CLK(NULL,	"iva2_ck",	&iva2_ck,	CK_34XX | CK_36XX),
+	CLK(NULL,	"l3_ick",	&l3_ick,	CK_3XXX),
+	CLK(NULL,	"l4_ick",	&l4_ick,	CK_3XXX),
+	CLK(NULL,	"rm_ick",	&rm_ick,	CK_3XXX),
+	CLK(NULL,	"gfx_l3_ck",	&gfx_l3_ck,	CK_3430ES1),
+	CLK(NULL,	"gfx_l3_fck",	&gfx_l3_fck,	CK_3430ES1),
+	CLK(NULL,	"gfx_l3_ick",	&gfx_l3_ick,	CK_3430ES1),
+	CLK(NULL,	"gfx_cg1_ck",	&gfx_cg1_ck,	CK_3430ES1),
+	CLK(NULL,	"gfx_cg2_ck",	&gfx_cg2_ck,	CK_3430ES1),
+	CLK(NULL,	"sgx_fck",	&sgx_fck,	CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
+	CLK(NULL,	"sgx_ick",	&sgx_ick,	CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
+	CLK(NULL,	"d2d_26m_fck",	&d2d_26m_fck,	CK_3430ES1),
+	CLK(NULL,	"modem_fck",	&modem_fck,	CK_34XX | CK_36XX),
+	CLK(NULL,	"sad2d_ick",	&sad2d_ick,	CK_34XX | CK_36XX),
+	CLK(NULL,	"mad2d_ick",	&mad2d_ick,	CK_34XX | CK_36XX),
+	CLK(NULL,	"gpt10_fck",	&gpt10_fck,	CK_3XXX),
+	CLK(NULL,	"gpt11_fck",	&gpt11_fck,	CK_3XXX),
+	CLK(NULL,	"cpefuse_fck",	&cpefuse_fck,	CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
+	CLK(NULL,	"ts_fck",	&ts_fck,	CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
+	CLK(NULL,	"usbtll_fck",	&usbtll_fck,	CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
+	CLK("usbhs_omap",	"usbtll_fck",	&usbtll_fck,	CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
+	CLK("usbhs_tll",	"usbtll_fck",	&usbtll_fck,	CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
+	CLK(NULL,	"core_96m_fck",	&core_96m_fck,	CK_3XXX),
+	CLK(NULL,	"mmchs3_fck",	&mmchs3_fck,	CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
+	CLK(NULL,	"mmchs2_fck",	&mmchs2_fck,	CK_3XXX),
+	CLK(NULL,	"mspro_fck",	&mspro_fck,	CK_34XX | CK_36XX),
+	CLK(NULL,	"mmchs1_fck",	&mmchs1_fck,	CK_3XXX),
+	CLK(NULL,	"i2c3_fck",	&i2c3_fck,	CK_3XXX),
+	CLK(NULL,	"i2c2_fck",	&i2c2_fck,	CK_3XXX),
+	CLK(NULL,	"i2c1_fck",	&i2c1_fck,	CK_3XXX),
+	CLK(NULL,	"mcbsp5_fck",	&mcbsp5_fck,	CK_3XXX),
+	CLK(NULL,	"mcbsp1_fck",	&mcbsp1_fck,	CK_3XXX),
+	CLK(NULL,	"core_48m_fck",	&core_48m_fck,	CK_3XXX),
+	CLK(NULL,	"mcspi4_fck",	&mcspi4_fck,	CK_3XXX),
+	CLK(NULL,	"mcspi3_fck",	&mcspi3_fck,	CK_3XXX),
+	CLK(NULL,	"mcspi2_fck",	&mcspi2_fck,	CK_3XXX),
+	CLK(NULL,	"mcspi1_fck",	&mcspi1_fck,	CK_3XXX),
+	CLK(NULL,	"uart2_fck",	&uart2_fck,	CK_3XXX),
+	CLK(NULL,	"uart1_fck",	&uart1_fck,	CK_3XXX),
+	CLK(NULL,	"fshostusb_fck", &fshostusb_fck, CK_3430ES1),
+	CLK(NULL,	"core_12m_fck",	&core_12m_fck,	CK_3XXX),
+	CLK("omap_hdq.0",	"fck",	&hdq_fck,	CK_3XXX),
+	CLK(NULL,	"hdq_fck",	&hdq_fck,	CK_3XXX),
+	CLK(NULL,	"ssi_ssr_fck",	&ssi_ssr_fck_3430es1,	CK_3430ES1),
+	CLK(NULL,	"ssi_ssr_fck",	&ssi_ssr_fck_3430es2,	CK_3430ES2PLUS | CK_36XX),
+	CLK(NULL,	"ssi_sst_fck",	&ssi_sst_fck_3430es1,	CK_3430ES1),
+	CLK(NULL,	"ssi_sst_fck",	&ssi_sst_fck_3430es2,	CK_3430ES2PLUS | CK_36XX),
+	CLK(NULL,	"core_l3_ick",	&core_l3_ick,	CK_3XXX),
+	CLK("musb-omap2430",	"ick",	&hsotgusb_ick_3430es1,	CK_3430ES1),
+	CLK("musb-omap2430",	"ick",	&hsotgusb_ick_3430es2,	CK_3430ES2PLUS | CK_36XX),
+	CLK(NULL,	"hsotgusb_ick",	&hsotgusb_ick_3430es1,	CK_3430ES1),
+	CLK(NULL,	"hsotgusb_ick",	&hsotgusb_ick_3430es2,	CK_3430ES2PLUS | CK_36XX),
+	CLK(NULL,	"sdrc_ick",	&sdrc_ick,	CK_3XXX),
+	CLK(NULL,	"gpmc_fck",	&gpmc_fck,	CK_3XXX),
+	CLK(NULL,	"security_l3_ick", &security_l3_ick, CK_34XX | CK_36XX),
+	CLK(NULL,	"pka_ick",	&pka_ick,	CK_34XX | CK_36XX),
+	CLK(NULL,	"core_l4_ick",	&core_l4_ick,	CK_3XXX),
+	CLK(NULL,	"usbtll_ick",	&usbtll_ick,	CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
+	CLK("usbhs_omap",	"usbtll_ick",	&usbtll_ick,	CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
+	CLK("usbhs_tll",	"usbtll_ick",	&usbtll_ick,	CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
+	CLK("omap_hsmmc.2",	"ick",	&mmchs3_ick,	CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
+	CLK(NULL,	"mmchs3_ick",	&mmchs3_ick,	CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
+	CLK(NULL,	"icr_ick",	&icr_ick,	CK_34XX | CK_36XX),
+	CLK("omap-aes",	"ick",	&aes2_ick,	CK_34XX | CK_36XX),
+	CLK("omap-sham",	"ick",	&sha12_ick,	CK_34XX | CK_36XX),
+	CLK(NULL,	"des2_ick",	&des2_ick,	CK_34XX | CK_36XX),
+	CLK("omap_hsmmc.1",	"ick",	&mmchs2_ick,	CK_3XXX),
+	CLK("omap_hsmmc.0",	"ick",	&mmchs1_ick,	CK_3XXX),
+	CLK(NULL,	"mmchs2_ick",	&mmchs2_ick,	CK_3XXX),
+	CLK(NULL,	"mmchs1_ick",	&mmchs1_ick,	CK_3XXX),
+	CLK(NULL,	"mspro_ick",	&mspro_ick,	CK_34XX | CK_36XX),
+	CLK("omap_hdq.0", "ick",	&hdq_ick,	CK_3XXX),
+	CLK(NULL,	"hdq_ick",	&hdq_ick,	CK_3XXX),
+	CLK("omap2_mcspi.4", "ick",	&mcspi4_ick,	CK_3XXX),
+	CLK("omap2_mcspi.3", "ick",	&mcspi3_ick,	CK_3XXX),
+	CLK("omap2_mcspi.2", "ick",	&mcspi2_ick,	CK_3XXX),
+	CLK("omap2_mcspi.1", "ick",	&mcspi1_ick,	CK_3XXX),
+	CLK(NULL,	"mcspi4_ick",	&mcspi4_ick,	CK_3XXX),
+	CLK(NULL,	"mcspi3_ick",	&mcspi3_ick,	CK_3XXX),
+	CLK(NULL,	"mcspi2_ick",	&mcspi2_ick,	CK_3XXX),
+	CLK(NULL,	"mcspi1_ick",	&mcspi1_ick,	CK_3XXX),
+	CLK("omap_i2c.3", "ick",	&i2c3_ick,	CK_3XXX),
+	CLK("omap_i2c.2", "ick",	&i2c2_ick,	CK_3XXX),
+	CLK("omap_i2c.1", "ick",	&i2c1_ick,	CK_3XXX),
+	CLK(NULL,	"i2c3_ick",	&i2c3_ick,	CK_3XXX),
+	CLK(NULL,	"i2c2_ick",	&i2c2_ick,	CK_3XXX),
+	CLK(NULL,	"i2c1_ick",	&i2c1_ick,	CK_3XXX),
+	CLK(NULL,	"uart2_ick",	&uart2_ick,	CK_3XXX),
+	CLK(NULL,	"uart1_ick",	&uart1_ick,	CK_3XXX),
+	CLK(NULL,	"gpt11_ick",	&gpt11_ick,	CK_3XXX),
+	CLK(NULL,	"gpt10_ick",	&gpt10_ick,	CK_3XXX),
+	CLK("omap-mcbsp.5", "ick",	&mcbsp5_ick,	CK_3XXX),
+	CLK("omap-mcbsp.1", "ick",	&mcbsp1_ick,	CK_3XXX),
+	CLK(NULL,	"mcbsp5_ick",	&mcbsp5_ick,	CK_3XXX),
+	CLK(NULL,	"mcbsp1_ick",	&mcbsp1_ick,	CK_3XXX),
+	CLK(NULL,	"fac_ick",	&fac_ick,	CK_3430ES1),
+	CLK(NULL,	"mailboxes_ick", &mailboxes_ick, CK_34XX | CK_36XX),
+	CLK(NULL,	"omapctrl_ick",	&omapctrl_ick,	CK_3XXX),
+	CLK(NULL,	"ssi_l4_ick",	&ssi_l4_ick,	CK_34XX | CK_36XX),
+	CLK(NULL,	"ssi_ick",	&ssi_ick_3430es1,	CK_3430ES1),
+	CLK(NULL,	"ssi_ick",	&ssi_ick_3430es2,	CK_3430ES2PLUS | CK_36XX),
+	CLK(NULL,	"usb_l4_ick",	&usb_l4_ick,	CK_3430ES1),
+	CLK(NULL,	"security_l4_ick2", &security_l4_ick2, CK_34XX | CK_36XX),
+	CLK(NULL,	"aes1_ick",	&aes1_ick,	CK_34XX | CK_36XX),
+	CLK("omap_rng",	"ick",		&rng_ick,	CK_34XX | CK_36XX),
+	CLK(NULL,	"sha11_ick",	&sha11_ick,	CK_34XX | CK_36XX),
+	CLK(NULL,	"des1_ick",	&des1_ick,	CK_34XX | CK_36XX),
+	CLK(NULL,	"dss1_alwon_fck",		&dss1_alwon_fck_3430es1, CK_3430ES1),
+	CLK(NULL,	"dss1_alwon_fck",		&dss1_alwon_fck_3430es2, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
+	CLK(NULL,	"dss_tv_fck",	&dss_tv_fck,	CK_3XXX),
+	CLK(NULL,	"dss_96m_fck",	&dss_96m_fck,	CK_3XXX),
+	CLK(NULL,	"dss2_alwon_fck",	&dss2_alwon_fck, CK_3XXX),
+	CLK("omapdss_dss",	"ick",		&dss_ick_3430es1,	CK_3430ES1),
+	CLK(NULL,	"dss_ick",		&dss_ick_3430es1,	CK_3430ES1),
+	CLK("omapdss_dss",	"ick",		&dss_ick_3430es2,	CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
+	CLK(NULL,	"dss_ick",		&dss_ick_3430es2,	CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
+	CLK(NULL,	"cam_mclk",	&cam_mclk,	CK_34XX | CK_36XX),
+	CLK(NULL,	"cam_ick",	&cam_ick,	CK_34XX | CK_36XX),
+	CLK(NULL,	"csi2_96m_fck",	&csi2_96m_fck,	CK_34XX | CK_36XX),
+	CLK(NULL,	"usbhost_120m_fck", &usbhost_120m_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
+	CLK(NULL,	"usbhost_48m_fck", &usbhost_48m_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
+	CLK(NULL,	"usbhost_ick",	&usbhost_ick,	CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
+	CLK("usbhs_omap",	"usbhost_ick",	&usbhost_ick,	CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
+	CLK(NULL,	"utmi_p1_gfclk",	&dummy_ck,	CK_3XXX),
+	CLK(NULL,	"utmi_p2_gfclk",	&dummy_ck,	CK_3XXX),
+	CLK(NULL,	"xclk60mhsp1_ck",	&dummy_ck,	CK_3XXX),
+	CLK(NULL,	"xclk60mhsp2_ck",	&dummy_ck,	CK_3XXX),
+	CLK(NULL,	"usb_host_hs_utmi_p1_clk",	&dummy_ck,	CK_3XXX),
+	CLK(NULL,	"usb_host_hs_utmi_p2_clk",	&dummy_ck,	CK_3XXX),
+	CLK("usbhs_omap",	"usb_tll_hs_usb_ch0_clk",	&dummy_ck,	CK_3XXX),
+	CLK("usbhs_omap",	"usb_tll_hs_usb_ch1_clk",	&dummy_ck,	CK_3XXX),
+	CLK("usbhs_tll",	"usb_tll_hs_usb_ch0_clk",	&dummy_ck,	CK_3XXX),
+	CLK("usbhs_tll",	"usb_tll_hs_usb_ch1_clk",	&dummy_ck,	CK_3XXX),
+	CLK(NULL,	"init_60m_fclk",	&dummy_ck,	CK_3XXX),
+	CLK(NULL,	"usim_fck",	&usim_fck,	CK_3430ES2PLUS | CK_36XX),
+	CLK(NULL,	"gpt1_fck",	&gpt1_fck,	CK_3XXX),
+	CLK(NULL,	"wkup_32k_fck",	&wkup_32k_fck,	CK_3XXX),
+	CLK(NULL,	"gpio1_dbck",	&gpio1_dbck,	CK_3XXX),
+	CLK(NULL,	"wdt2_fck",		&wdt2_fck,	CK_3XXX),
+	CLK(NULL,	"wkup_l4_ick",	&wkup_l4_ick,	CK_34XX | CK_36XX),
+	CLK(NULL,	"usim_ick",	&usim_ick,	CK_3430ES2PLUS | CK_36XX),
+	CLK("omap_wdt",	"ick",		&wdt2_ick,	CK_3XXX),
+	CLK(NULL,	"wdt2_ick",	&wdt2_ick,	CK_3XXX),
+	CLK(NULL,	"wdt1_ick",	&wdt1_ick,	CK_3XXX),
+	CLK(NULL,	"gpio1_ick",	&gpio1_ick,	CK_3XXX),
+	CLK(NULL,	"omap_32ksync_ick", &omap_32ksync_ick, CK_3XXX),
+	CLK(NULL,	"gpt12_ick",	&gpt12_ick,	CK_3XXX),
+	CLK(NULL,	"gpt1_ick",	&gpt1_ick,	CK_3XXX),
+	CLK(NULL,	"per_96m_fck",	&per_96m_fck,	CK_3XXX),
+	CLK(NULL,	"per_48m_fck",	&per_48m_fck,	CK_3XXX),
+	CLK(NULL,	"uart3_fck",	&uart3_fck,	CK_3XXX),
+	CLK(NULL,	"uart4_fck",	&uart4_fck,	CK_36XX),
+	CLK(NULL,	"uart4_fck",	&uart4_fck_am35xx, CK_AM35XX),
+	CLK(NULL,	"gpt2_fck",	&gpt2_fck,	CK_3XXX),
+	CLK(NULL,	"gpt3_fck",	&gpt3_fck,	CK_3XXX),
+	CLK(NULL,	"gpt4_fck",	&gpt4_fck,	CK_3XXX),
+	CLK(NULL,	"gpt5_fck",	&gpt5_fck,	CK_3XXX),
+	CLK(NULL,	"gpt6_fck",	&gpt6_fck,	CK_3XXX),
+	CLK(NULL,	"gpt7_fck",	&gpt7_fck,	CK_3XXX),
+	CLK(NULL,	"gpt8_fck",	&gpt8_fck,	CK_3XXX),
+	CLK(NULL,	"gpt9_fck",	&gpt9_fck,	CK_3XXX),
+	CLK(NULL,	"per_32k_alwon_fck", &per_32k_alwon_fck, CK_3XXX),
+	CLK(NULL,	"gpio6_dbck",	&gpio6_dbck,	CK_3XXX),
+	CLK(NULL,	"gpio5_dbck",	&gpio5_dbck,	CK_3XXX),
+	CLK(NULL,	"gpio4_dbck",	&gpio4_dbck,	CK_3XXX),
+	CLK(NULL,	"gpio3_dbck",	&gpio3_dbck,	CK_3XXX),
+	CLK(NULL,	"gpio2_dbck",	&gpio2_dbck,	CK_3XXX),
+	CLK(NULL,	"wdt3_fck",	&wdt3_fck,	CK_3XXX),
+	CLK(NULL,	"per_l4_ick",	&per_l4_ick,	CK_3XXX),
+	CLK(NULL,	"gpio6_ick",	&gpio6_ick,	CK_3XXX),
+	CLK(NULL,	"gpio5_ick",	&gpio5_ick,	CK_3XXX),
+	CLK(NULL,	"gpio4_ick",	&gpio4_ick,	CK_3XXX),
+	CLK(NULL,	"gpio3_ick",	&gpio3_ick,	CK_3XXX),
+	CLK(NULL,	"gpio2_ick",	&gpio2_ick,	CK_3XXX),
+	CLK(NULL,	"wdt3_ick",	&wdt3_ick,	CK_3XXX),
+	CLK(NULL,	"uart3_ick",	&uart3_ick,	CK_3XXX),
+	CLK(NULL,	"uart4_ick",	&uart4_ick,	CK_36XX),
+	CLK(NULL,	"gpt9_ick",	&gpt9_ick,	CK_3XXX),
+	CLK(NULL,	"gpt8_ick",	&gpt8_ick,	CK_3XXX),
+	CLK(NULL,	"gpt7_ick",	&gpt7_ick,	CK_3XXX),
+	CLK(NULL,	"gpt6_ick",	&gpt6_ick,	CK_3XXX),
+	CLK(NULL,	"gpt5_ick",	&gpt5_ick,	CK_3XXX),
+	CLK(NULL,	"gpt4_ick",	&gpt4_ick,	CK_3XXX),
+	CLK(NULL,	"gpt3_ick",	&gpt3_ick,	CK_3XXX),
+	CLK(NULL,	"gpt2_ick",	&gpt2_ick,	CK_3XXX),
+	CLK("omap-mcbsp.2", "ick",	&mcbsp2_ick,	CK_3XXX),
+	CLK("omap-mcbsp.3", "ick",	&mcbsp3_ick,	CK_3XXX),
+	CLK("omap-mcbsp.4", "ick",	&mcbsp4_ick,	CK_3XXX),
+	CLK(NULL,	"mcbsp4_ick",	&mcbsp2_ick,	CK_3XXX),
+	CLK(NULL,	"mcbsp3_ick",	&mcbsp3_ick,	CK_3XXX),
+	CLK(NULL,	"mcbsp2_ick",	&mcbsp4_ick,	CK_3XXX),
+	CLK(NULL,	"mcbsp2_fck",	&mcbsp2_fck,	CK_3XXX),
+	CLK(NULL,	"mcbsp3_fck",	&mcbsp3_fck,	CK_3XXX),
+	CLK(NULL,	"mcbsp4_fck",	&mcbsp4_fck,	CK_3XXX),
+	CLK("etb",	"emu_src_ck",	&emu_src_ck,	CK_3XXX),
+	CLK(NULL,	"emu_src_ck",	&emu_src_ck,	CK_3XXX),
+	CLK(NULL,	"pclk_fck",	&pclk_fck,	CK_3XXX),
+	CLK(NULL,	"pclkx2_fck",	&pclkx2_fck,	CK_3XXX),
+	CLK(NULL,	"atclk_fck",	&atclk_fck,	CK_3XXX),
+	CLK(NULL,	"traceclk_src_fck", &traceclk_src_fck, CK_3XXX),
+	CLK(NULL,	"traceclk_fck",	&traceclk_fck,	CK_3XXX),
+	CLK(NULL,	"sr1_fck",	&sr1_fck,	CK_34XX | CK_36XX),
+	CLK(NULL,	"sr2_fck",	&sr2_fck,	CK_34XX | CK_36XX),
+	CLK(NULL,	"sr_l4_ick",	&sr_l4_ick,	CK_34XX | CK_36XX),
+	CLK(NULL,	"secure_32k_fck", &secure_32k_fck, CK_3XXX),
+	CLK(NULL,	"gpt12_fck",	&gpt12_fck,	CK_3XXX),
+	CLK(NULL,	"wdt1_fck",	&wdt1_fck,	CK_3XXX),
+	CLK(NULL,	"ipss_ick",	&ipss_ick,	CK_AM35XX),
+	CLK(NULL,	"rmii_ck",	&rmii_ck,	CK_AM35XX),
+	CLK(NULL,	"pclk_ck",	&pclk_ck,	CK_AM35XX),
+	CLK(NULL,	"emac_ick",	&emac_ick,	CK_AM35XX),
+	CLK(NULL,	"emac_fck",	&emac_fck,	CK_AM35XX),
+	CLK("davinci_emac.0",	NULL,	&emac_ick,	CK_AM35XX),
+	CLK("davinci_mdio.0",	NULL,	&emac_fck,	CK_AM35XX),
+	CLK("vpfe-capture",	"master",	&vpfe_ick,	CK_AM35XX),
+	CLK("vpfe-capture",	"slave",	&vpfe_fck,	CK_AM35XX),
+	CLK(NULL,	"hsotgusb_ick",		&hsotgusb_ick_am35xx,	CK_AM35XX),
+	CLK(NULL,	"hsotgusb_fck",		&hsotgusb_fck_am35xx,	CK_AM35XX),
+	CLK(NULL,	"hecc_ck",	&hecc_ck,	CK_AM35XX),
+	CLK(NULL,	"uart4_ick",	&uart4_ick_am35xx,	CK_AM35XX),
+	CLK(NULL,	"timer_32k_ck",	&omap_32k_fck,  CK_3XXX),
+	CLK(NULL,	"timer_sys_ck",	&sys_ck,	CK_3XXX),
+	CLK(NULL,	"cpufreq_ck",	&dpll1_ck,	CK_3XXX),
+};
+
+static const char *enable_init_clks[] = {
+	"sdrc_ick",
+	"gpmc_fck",
+	"omapctrl_ick",
+};
+
+int __init omap3xxx_clk_init(void)
+{
+	struct omap_clk *c;
+	u32 cpu_clkflg = 0;
+
+	/*
+	 * 3505 must be tested before 3517, since 3517 returns true
+	 * for both AM3517 chips and AM3517 family chips, which
+	 * includes 3505.  Unfortunately there's no obvious family
+	 * test for 3517/3505 :-(
+	 */
+	if (soc_is_am35xx()) {
+		cpu_mask = RATE_IN_34XX;
+		cpu_clkflg = CK_AM35XX;
+	} else if (cpu_is_omap3630()) {
+		cpu_mask = (RATE_IN_34XX | RATE_IN_36XX);
+		cpu_clkflg = CK_36XX;
+	} else if (cpu_is_ti816x()) {
+		cpu_mask = RATE_IN_TI816X;
+		cpu_clkflg = CK_TI816X;
+	} else if (soc_is_am33xx()) {
+		cpu_mask = RATE_IN_AM33XX;
+	} else if (cpu_is_ti814x()) {
+		cpu_mask = RATE_IN_TI814X;
+	} else if (cpu_is_omap34xx()) {
+		if (omap_rev() == OMAP3430_REV_ES1_0) {
+			cpu_mask = RATE_IN_3430ES1;
+			cpu_clkflg = CK_3430ES1;
+		} else {
+			/*
+			 * Assume that anything that we haven't matched yet
+			 * has 3430ES2-type clocks.
+			 */
+			cpu_mask = RATE_IN_3430ES2PLUS;
+			cpu_clkflg = CK_3430ES2PLUS;
+		}
+	} else {
+		WARN(1, "clock: could not identify OMAP3 variant\n");
+	}
+
+	if (omap3_has_192mhz_clk())
+		omap_96m_alwon_fck = omap_96m_alwon_fck_3630;
+
+	if (cpu_is_omap3630()) {
+		dpll3_m3x2_ck = dpll3_m3x2_ck_3630;
+		dpll4_m2x2_ck = dpll4_m2x2_ck_3630;
+		dpll4_m3x2_ck = dpll4_m3x2_ck_3630;
+		dpll4_m4x2_ck = dpll4_m4x2_ck_3630;
+		dpll4_m5x2_ck = dpll4_m5x2_ck_3630;
+		dpll4_m6x2_ck = dpll4_m6x2_ck_3630;
+	}
+
+	/*
+	 * XXX This type of dynamic rewriting of the clock tree is
+	 * deprecated and should be revised soon.
+	 */
+	if (cpu_is_omap3630())
+		dpll4_dd = dpll4_dd_3630;
+	else
+		dpll4_dd = dpll4_dd_34xx;
+
+	for (c = omap3xxx_clks; c < omap3xxx_clks + ARRAY_SIZE(omap3xxx_clks);
+	     c++)
+		if (c->cpu & cpu_clkflg) {
+			clkdev_add(&c->lk);
+			if (!__clk_init(NULL, c->lk.clk))
+				omap2_init_clk_hw_omap_clocks(c->lk.clk);
+		}
+
+	omap2_clk_disable_autoidle_all();
+
+	omap2_clk_enable_init_clocks(enable_init_clks,
+				     ARRAY_SIZE(enable_init_clks));
+
+	pr_info("Clocking rate (Crystal/Core/MPU): %ld.%01ld/%ld/%ld MHz\n",
+		(clk_get_rate(&osc_sys_ck) / 1000000),
+		(clk_get_rate(&osc_sys_ck) / 100000) % 10,
+		(clk_get_rate(&core_ck) / 1000000),
+		(clk_get_rate(&arm_fck) / 1000000));
+
+	/*
+	 * Lock DPLL5 -- here only until other device init code can
+	 * handle this
+	 */
+	if (!cpu_is_ti81xx() && (omap_rev() >= OMAP3430_REV_ES2_0))
+		omap3_clk_lock_dpll5();
+
+	/* Avoid sleeping during omap3_core_dpll_m2_set_rate() */
+	sdrc_ick_p = clk_get(NULL, "sdrc_ick");
+	arm_fck_p = clk_get(NULL, "arm_fck");
+
+	return 0;
+}
diff --git a/arch/arm/mach-omap2/cclock44xx_data.c b/arch/arm/mach-omap2/cclock44xx_data.c
new file mode 100644
index 0000000..aa56c3e
--- /dev/null
+++ b/arch/arm/mach-omap2/cclock44xx_data.c
@@ -0,0 +1,1987 @@
+/*
+ * OMAP4 Clock data
+ *
+ * Copyright (C) 2009-2012 Texas Instruments, Inc.
+ * Copyright (C) 2009-2010 Nokia Corporation
+ *
+ * Paul Walmsley (paul@pwsan.com)
+ * Rajendra Nayak (rnayak@ti.com)
+ * Benoit Cousson (b-cousson@ti.com)
+ * Mike Turquette (mturquette@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.
+ *
+ * XXX Some of the ES1 clocks have been removed/changed; once support
+ * is added for discriminating clocks by ES level, these should be added back
+ * in.
+ */
+
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/clk-private.h>
+#include <linux/clkdev.h>
+#include <linux/io.h>
+
+#include "soc.h"
+#include "iomap.h"
+#include "clock.h"
+#include "clock44xx.h"
+#include "cm1_44xx.h"
+#include "cm2_44xx.h"
+#include "cm-regbits-44xx.h"
+#include "prm44xx.h"
+#include "prm-regbits-44xx.h"
+#include "control.h"
+#include "scrm44xx.h"
+
+/* OMAP4 modulemode control */
+#define OMAP4430_MODULEMODE_HWCTRL_SHIFT		0
+#define OMAP4430_MODULEMODE_SWCTRL_SHIFT		1
+
+/* Root clocks */
+
+DEFINE_CLK_FIXED_RATE(extalt_clkin_ck, CLK_IS_ROOT, 59000000, 0x0);
+
+DEFINE_CLK_FIXED_RATE(pad_clks_src_ck, CLK_IS_ROOT, 12000000, 0x0);
+
+DEFINE_CLK_GATE(pad_clks_ck, "pad_clks_src_ck", &pad_clks_src_ck, 0x0,
+		OMAP4430_CM_CLKSEL_ABE, OMAP4430_PAD_CLKS_GATE_SHIFT,
+		0x0, NULL);
+
+DEFINE_CLK_FIXED_RATE(pad_slimbus_core_clks_ck, CLK_IS_ROOT, 12000000, 0x0);
+
+DEFINE_CLK_FIXED_RATE(secure_32k_clk_src_ck, CLK_IS_ROOT, 32768, 0x0);
+
+DEFINE_CLK_FIXED_RATE(slimbus_src_clk, CLK_IS_ROOT, 12000000, 0x0);
+
+DEFINE_CLK_GATE(slimbus_clk, "slimbus_src_clk", &slimbus_src_clk, 0x0,
+		OMAP4430_CM_CLKSEL_ABE, OMAP4430_SLIMBUS_CLK_GATE_SHIFT,
+		0x0, NULL);
+
+DEFINE_CLK_FIXED_RATE(sys_32k_ck, CLK_IS_ROOT, 32768, 0x0);
+
+DEFINE_CLK_FIXED_RATE(virt_12000000_ck, CLK_IS_ROOT, 12000000, 0x0);
+
+DEFINE_CLK_FIXED_RATE(virt_13000000_ck, CLK_IS_ROOT, 13000000, 0x0);
+
+DEFINE_CLK_FIXED_RATE(virt_16800000_ck, CLK_IS_ROOT, 16800000, 0x0);
+
+DEFINE_CLK_FIXED_RATE(virt_19200000_ck, CLK_IS_ROOT, 19200000, 0x0);
+
+DEFINE_CLK_FIXED_RATE(virt_26000000_ck, CLK_IS_ROOT, 26000000, 0x0);
+
+DEFINE_CLK_FIXED_RATE(virt_27000000_ck, CLK_IS_ROOT, 27000000, 0x0);
+
+DEFINE_CLK_FIXED_RATE(virt_38400000_ck, CLK_IS_ROOT, 38400000, 0x0);
+
+static const char *sys_clkin_ck_parents[] = {
+	"virt_12000000_ck", "virt_13000000_ck", "virt_16800000_ck",
+	"virt_19200000_ck", "virt_26000000_ck", "virt_27000000_ck",
+	"virt_38400000_ck",
+};
+
+DEFINE_CLK_MUX(sys_clkin_ck, sys_clkin_ck_parents, NULL, 0x0,
+	       OMAP4430_CM_SYS_CLKSEL, OMAP4430_SYS_CLKSEL_SHIFT,
+	       OMAP4430_SYS_CLKSEL_WIDTH, CLK_MUX_INDEX_ONE, NULL);
+
+DEFINE_CLK_FIXED_RATE(tie_low_clock_ck, CLK_IS_ROOT, 0, 0x0);
+
+DEFINE_CLK_FIXED_RATE(utmi_phy_clkout_ck, CLK_IS_ROOT, 60000000, 0x0);
+
+DEFINE_CLK_FIXED_RATE(xclk60mhsp1_ck, CLK_IS_ROOT, 60000000, 0x0);
+
+DEFINE_CLK_FIXED_RATE(xclk60mhsp2_ck, CLK_IS_ROOT, 60000000, 0x0);
+
+DEFINE_CLK_FIXED_RATE(xclk60motg_ck, CLK_IS_ROOT, 60000000, 0x0);
+
+/* Module clocks and DPLL outputs */
+
+static const char *abe_dpll_bypass_clk_mux_ck_parents[] = {
+	"sys_clkin_ck", "sys_32k_ck",
+};
+
+DEFINE_CLK_MUX(abe_dpll_bypass_clk_mux_ck, abe_dpll_bypass_clk_mux_ck_parents,
+	       NULL, 0x0, OMAP4430_CM_L4_WKUP_CLKSEL, OMAP4430_CLKSEL_SHIFT,
+	       OMAP4430_CLKSEL_WIDTH, 0x0, NULL);
+
+DEFINE_CLK_MUX(abe_dpll_refclk_mux_ck, abe_dpll_bypass_clk_mux_ck_parents, NULL,
+	       0x0, OMAP4430_CM_ABE_PLL_REF_CLKSEL, OMAP4430_CLKSEL_0_0_SHIFT,
+	       OMAP4430_CLKSEL_0_0_WIDTH, 0x0, NULL);
+
+/* DPLL_ABE */
+static struct dpll_data dpll_abe_dd = {
+	.mult_div1_reg	= OMAP4430_CM_CLKSEL_DPLL_ABE,
+	.clk_bypass	= &abe_dpll_bypass_clk_mux_ck,
+	.clk_ref	= &abe_dpll_refclk_mux_ck,
+	.control_reg	= OMAP4430_CM_CLKMODE_DPLL_ABE,
+	.modes		= (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
+	.autoidle_reg	= OMAP4430_CM_AUTOIDLE_DPLL_ABE,
+	.idlest_reg	= OMAP4430_CM_IDLEST_DPLL_ABE,
+	.mult_mask	= OMAP4430_DPLL_MULT_MASK,
+	.div1_mask	= OMAP4430_DPLL_DIV_MASK,
+	.enable_mask	= OMAP4430_DPLL_EN_MASK,
+	.autoidle_mask	= OMAP4430_AUTO_DPLL_MODE_MASK,
+	.idlest_mask	= OMAP4430_ST_DPLL_CLK_MASK,
+	.max_multiplier	= 2047,
+	.max_divider	= 128,
+	.min_divider	= 1,
+};
+
+
+static const char *dpll_abe_ck_parents[] = {
+	"abe_dpll_refclk_mux_ck",
+};
+
+static struct clk dpll_abe_ck;
+
+static const struct clk_ops dpll_abe_ck_ops = {
+	.enable		= &omap3_noncore_dpll_enable,
+	.disable	= &omap3_noncore_dpll_disable,
+	.recalc_rate	= &omap4_dpll_regm4xen_recalc,
+	.round_rate	= &omap4_dpll_regm4xen_round_rate,
+	.set_rate	= &omap3_noncore_dpll_set_rate,
+	.get_parent	= &omap2_init_dpll_parent,
+};
+
+static struct clk_hw_omap dpll_abe_ck_hw = {
+	.hw = {
+		.clk = &dpll_abe_ck,
+	},
+	.dpll_data	= &dpll_abe_dd,
+	.ops		= &clkhwops_omap3_dpll,
+};
+
+DEFINE_STRUCT_CLK(dpll_abe_ck, dpll_abe_ck_parents, dpll_abe_ck_ops);
+
+static const char *dpll_abe_x2_ck_parents[] = {
+	"dpll_abe_ck",
+};
+
+static struct clk dpll_abe_x2_ck;
+
+static const struct clk_ops dpll_abe_x2_ck_ops = {
+	.recalc_rate	= &omap3_clkoutx2_recalc,
+};
+
+static struct clk_hw_omap dpll_abe_x2_ck_hw = {
+	.hw = {
+		.clk = &dpll_abe_x2_ck,
+	},
+	.flags		= CLOCK_CLKOUTX2,
+	.clksel_reg	= OMAP4430_CM_DIV_M2_DPLL_ABE,
+	.ops		= &clkhwops_omap4_dpllmx,
+};
+
+DEFINE_STRUCT_CLK(dpll_abe_x2_ck, dpll_abe_x2_ck_parents, dpll_abe_x2_ck_ops);
+
+static const struct clk_ops omap_hsdivider_ops = {
+	.set_rate	= &omap2_clksel_set_rate,
+	.recalc_rate	= &omap2_clksel_recalc,
+	.round_rate	= &omap2_clksel_round_rate,
+};
+
+DEFINE_CLK_OMAP_HSDIVIDER(dpll_abe_m2x2_ck, "dpll_abe_x2_ck", &dpll_abe_x2_ck,
+			  0x0, OMAP4430_CM_DIV_M2_DPLL_ABE,
+			  OMAP4430_DPLL_CLKOUT_DIV_MASK);
+
+DEFINE_CLK_FIXED_FACTOR(abe_24m_fclk, "dpll_abe_m2x2_ck", &dpll_abe_m2x2_ck,
+			0x0, 1, 8);
+
+DEFINE_CLK_DIVIDER(abe_clk, "dpll_abe_m2x2_ck", &dpll_abe_m2x2_ck, 0x0,
+		   OMAP4430_CM_CLKSEL_ABE, OMAP4430_CLKSEL_OPP_SHIFT,
+		   OMAP4430_CLKSEL_OPP_WIDTH, CLK_DIVIDER_POWER_OF_TWO, NULL);
+
+DEFINE_CLK_DIVIDER(aess_fclk, "abe_clk", &abe_clk, 0x0,
+		   OMAP4430_CM1_ABE_AESS_CLKCTRL,
+		   OMAP4430_CLKSEL_AESS_FCLK_SHIFT,
+		   OMAP4430_CLKSEL_AESS_FCLK_WIDTH,
+		   0x0, NULL);
+
+DEFINE_CLK_OMAP_HSDIVIDER(dpll_abe_m3x2_ck, "dpll_abe_x2_ck", &dpll_abe_x2_ck,
+			  0x0, OMAP4430_CM_DIV_M3_DPLL_ABE,
+			  OMAP4430_DPLL_CLKOUTHIF_DIV_MASK);
+
+static const char *core_hsd_byp_clk_mux_ck_parents[] = {
+	"sys_clkin_ck", "dpll_abe_m3x2_ck",
+};
+
+DEFINE_CLK_MUX(core_hsd_byp_clk_mux_ck, core_hsd_byp_clk_mux_ck_parents, NULL,
+	       0x0, OMAP4430_CM_CLKSEL_DPLL_CORE,
+	       OMAP4430_DPLL_BYP_CLKSEL_SHIFT, OMAP4430_DPLL_BYP_CLKSEL_WIDTH,
+	       0x0, NULL);
+
+/* DPLL_CORE */
+static struct dpll_data dpll_core_dd = {
+	.mult_div1_reg	= OMAP4430_CM_CLKSEL_DPLL_CORE,
+	.clk_bypass	= &core_hsd_byp_clk_mux_ck,
+	.clk_ref	= &sys_clkin_ck,
+	.control_reg	= OMAP4430_CM_CLKMODE_DPLL_CORE,
+	.modes		= (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
+	.autoidle_reg	= OMAP4430_CM_AUTOIDLE_DPLL_CORE,
+	.idlest_reg	= OMAP4430_CM_IDLEST_DPLL_CORE,
+	.mult_mask	= OMAP4430_DPLL_MULT_MASK,
+	.div1_mask	= OMAP4430_DPLL_DIV_MASK,
+	.enable_mask	= OMAP4430_DPLL_EN_MASK,
+	.autoidle_mask	= OMAP4430_AUTO_DPLL_MODE_MASK,
+	.idlest_mask	= OMAP4430_ST_DPLL_CLK_MASK,
+	.max_multiplier	= 2047,
+	.max_divider	= 128,
+	.min_divider	= 1,
+};
+
+
+static const char *dpll_core_ck_parents[] = {
+	"sys_clkin_ck",
+};
+
+static struct clk dpll_core_ck;
+
+static const struct clk_ops dpll_core_ck_ops = {
+	.recalc_rate	= &omap3_dpll_recalc,
+	.get_parent	= &omap2_init_dpll_parent,
+};
+
+static struct clk_hw_omap dpll_core_ck_hw = {
+	.hw = {
+		.clk = &dpll_core_ck,
+	},
+	.dpll_data	= &dpll_core_dd,
+	.ops		= &clkhwops_omap3_dpll,
+};
+
+DEFINE_STRUCT_CLK(dpll_core_ck, dpll_core_ck_parents, dpll_core_ck_ops);
+
+static const char *dpll_core_x2_ck_parents[] = {
+	"dpll_core_ck",
+};
+
+static struct clk dpll_core_x2_ck;
+
+static struct clk_hw_omap dpll_core_x2_ck_hw = {
+	.hw = {
+		.clk = &dpll_core_x2_ck,
+	},
+};
+
+DEFINE_STRUCT_CLK(dpll_core_x2_ck, dpll_core_x2_ck_parents, dpll_abe_x2_ck_ops);
+
+DEFINE_CLK_OMAP_HSDIVIDER(dpll_core_m6x2_ck, "dpll_core_x2_ck",
+			  &dpll_core_x2_ck, 0x0, OMAP4430_CM_DIV_M6_DPLL_CORE,
+			  OMAP4430_HSDIVIDER_CLKOUT3_DIV_MASK);
+
+DEFINE_CLK_OMAP_HSDIVIDER(dpll_core_m2_ck, "dpll_core_ck", &dpll_core_ck, 0x0,
+			  OMAP4430_CM_DIV_M2_DPLL_CORE,
+			  OMAP4430_DPLL_CLKOUT_DIV_MASK);
+
+DEFINE_CLK_FIXED_FACTOR(ddrphy_ck, "dpll_core_m2_ck", &dpll_core_m2_ck, 0x0, 1,
+			2);
+
+DEFINE_CLK_OMAP_HSDIVIDER(dpll_core_m5x2_ck, "dpll_core_x2_ck",
+			  &dpll_core_x2_ck, 0x0, OMAP4430_CM_DIV_M5_DPLL_CORE,
+			  OMAP4430_HSDIVIDER_CLKOUT2_DIV_MASK);
+
+DEFINE_CLK_DIVIDER(div_core_ck, "dpll_core_m5x2_ck", &dpll_core_m5x2_ck, 0x0,
+		   OMAP4430_CM_CLKSEL_CORE, OMAP4430_CLKSEL_CORE_SHIFT,
+		   OMAP4430_CLKSEL_CORE_WIDTH, 0x0, NULL);
+
+DEFINE_CLK_OMAP_HSDIVIDER(div_iva_hs_clk, "dpll_core_m5x2_ck",
+			  &dpll_core_m5x2_ck, 0x0, OMAP4430_CM_BYPCLK_DPLL_IVA,
+			  OMAP4430_CLKSEL_0_1_MASK);
+
+DEFINE_CLK_DIVIDER(div_mpu_hs_clk, "dpll_core_m5x2_ck", &dpll_core_m5x2_ck,
+		   0x0, OMAP4430_CM_BYPCLK_DPLL_MPU, OMAP4430_CLKSEL_0_1_SHIFT,
+		   OMAP4430_CLKSEL_0_1_WIDTH, CLK_DIVIDER_POWER_OF_TWO, NULL);
+
+DEFINE_CLK_OMAP_HSDIVIDER(dpll_core_m4x2_ck, "dpll_core_x2_ck",
+			  &dpll_core_x2_ck, 0x0, OMAP4430_CM_DIV_M4_DPLL_CORE,
+			  OMAP4430_HSDIVIDER_CLKOUT1_DIV_MASK);
+
+DEFINE_CLK_FIXED_FACTOR(dll_clk_div_ck, "dpll_core_m4x2_ck", &dpll_core_m4x2_ck,
+			0x0, 1, 2);
+
+DEFINE_CLK_DIVIDER(dpll_abe_m2_ck, "dpll_abe_ck", &dpll_abe_ck, 0x0,
+		   OMAP4430_CM_DIV_M2_DPLL_ABE, OMAP4430_DPLL_CLKOUT_DIV_SHIFT,
+		   OMAP4430_DPLL_CLKOUT_DIV_WIDTH, CLK_DIVIDER_ONE_BASED, NULL);
+
+static const struct clk_ops dmic_fck_ops = {
+	.enable		= &omap2_dflt_clk_enable,
+	.disable	= &omap2_dflt_clk_disable,
+	.is_enabled	= &omap2_dflt_clk_is_enabled,
+	.recalc_rate	= &omap2_clksel_recalc,
+	.get_parent	= &omap2_clksel_find_parent_index,
+	.set_parent	= &omap2_clksel_set_parent,
+	.init		= &omap2_init_clk_clkdm,
+};
+
+static const char *dpll_core_m3x2_ck_parents[] = {
+	"dpll_core_x2_ck",
+};
+
+static const struct clksel dpll_core_m3x2_div[] = {
+	{ .parent = &dpll_core_x2_ck, .rates = div31_1to31_rates },
+	{ .parent = NULL },
+};
+
+/* XXX Missing round_rate, set_rate in ops */
+DEFINE_CLK_OMAP_MUX_GATE(dpll_core_m3x2_ck, NULL, dpll_core_m3x2_div,
+			 OMAP4430_CM_DIV_M3_DPLL_CORE,
+			 OMAP4430_DPLL_CLKOUTHIF_DIV_MASK,
+			 OMAP4430_CM_DIV_M3_DPLL_CORE,
+			 OMAP4430_DPLL_CLKOUTHIF_GATE_CTRL_SHIFT, NULL,
+			 dpll_core_m3x2_ck_parents, dmic_fck_ops);
+
+DEFINE_CLK_OMAP_HSDIVIDER(dpll_core_m7x2_ck, "dpll_core_x2_ck",
+			  &dpll_core_x2_ck, 0x0, OMAP4430_CM_DIV_M7_DPLL_CORE,
+			  OMAP4430_HSDIVIDER_CLKOUT4_DIV_MASK);
+
+static const char *iva_hsd_byp_clk_mux_ck_parents[] = {
+	"sys_clkin_ck", "div_iva_hs_clk",
+};
+
+DEFINE_CLK_MUX(iva_hsd_byp_clk_mux_ck, iva_hsd_byp_clk_mux_ck_parents, NULL,
+	       0x0, OMAP4430_CM_CLKSEL_DPLL_IVA, OMAP4430_DPLL_BYP_CLKSEL_SHIFT,
+	       OMAP4430_DPLL_BYP_CLKSEL_WIDTH, 0x0, NULL);
+
+/* DPLL_IVA */
+static struct dpll_data dpll_iva_dd = {
+	.mult_div1_reg	= OMAP4430_CM_CLKSEL_DPLL_IVA,
+	.clk_bypass	= &iva_hsd_byp_clk_mux_ck,
+	.clk_ref	= &sys_clkin_ck,
+	.control_reg	= OMAP4430_CM_CLKMODE_DPLL_IVA,
+	.modes		= (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
+	.autoidle_reg	= OMAP4430_CM_AUTOIDLE_DPLL_IVA,
+	.idlest_reg	= OMAP4430_CM_IDLEST_DPLL_IVA,
+	.mult_mask	= OMAP4430_DPLL_MULT_MASK,
+	.div1_mask	= OMAP4430_DPLL_DIV_MASK,
+	.enable_mask	= OMAP4430_DPLL_EN_MASK,
+	.autoidle_mask	= OMAP4430_AUTO_DPLL_MODE_MASK,
+	.idlest_mask	= OMAP4430_ST_DPLL_CLK_MASK,
+	.max_multiplier	= 2047,
+	.max_divider	= 128,
+	.min_divider	= 1,
+};
+
+static struct clk dpll_iva_ck;
+
+static struct clk_hw_omap dpll_iva_ck_hw = {
+	.hw = {
+		.clk = &dpll_iva_ck,
+	},
+	.dpll_data	= &dpll_iva_dd,
+	.ops		= &clkhwops_omap3_dpll,
+};
+
+DEFINE_STRUCT_CLK(dpll_iva_ck, dpll_core_ck_parents, dpll_abe_ck_ops);
+
+static const char *dpll_iva_x2_ck_parents[] = {
+	"dpll_iva_ck",
+};
+
+static struct clk dpll_iva_x2_ck;
+
+static struct clk_hw_omap dpll_iva_x2_ck_hw = {
+	.hw = {
+		.clk = &dpll_iva_x2_ck,
+	},
+};
+
+DEFINE_STRUCT_CLK(dpll_iva_x2_ck, dpll_iva_x2_ck_parents, dpll_abe_x2_ck_ops);
+
+DEFINE_CLK_OMAP_HSDIVIDER(dpll_iva_m4x2_ck, "dpll_iva_x2_ck", &dpll_iva_x2_ck,
+			  0x0, OMAP4430_CM_DIV_M4_DPLL_IVA,
+			  OMAP4430_HSDIVIDER_CLKOUT1_DIV_MASK);
+
+DEFINE_CLK_OMAP_HSDIVIDER(dpll_iva_m5x2_ck, "dpll_iva_x2_ck", &dpll_iva_x2_ck,
+			  0x0, OMAP4430_CM_DIV_M5_DPLL_IVA,
+			  OMAP4430_HSDIVIDER_CLKOUT2_DIV_MASK);
+
+/* DPLL_MPU */
+static struct dpll_data dpll_mpu_dd = {
+	.mult_div1_reg	= OMAP4430_CM_CLKSEL_DPLL_MPU,
+	.clk_bypass	= &div_mpu_hs_clk,
+	.clk_ref	= &sys_clkin_ck,
+	.control_reg	= OMAP4430_CM_CLKMODE_DPLL_MPU,
+	.modes		= (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
+	.autoidle_reg	= OMAP4430_CM_AUTOIDLE_DPLL_MPU,
+	.idlest_reg	= OMAP4430_CM_IDLEST_DPLL_MPU,
+	.mult_mask	= OMAP4430_DPLL_MULT_MASK,
+	.div1_mask	= OMAP4430_DPLL_DIV_MASK,
+	.enable_mask	= OMAP4430_DPLL_EN_MASK,
+	.autoidle_mask	= OMAP4430_AUTO_DPLL_MODE_MASK,
+	.idlest_mask	= OMAP4430_ST_DPLL_CLK_MASK,
+	.max_multiplier	= 2047,
+	.max_divider	= 128,
+	.min_divider	= 1,
+};
+
+static struct clk dpll_mpu_ck;
+
+static struct clk_hw_omap dpll_mpu_ck_hw = {
+	.hw = {
+		.clk = &dpll_mpu_ck,
+	},
+	.dpll_data	= &dpll_mpu_dd,
+	.ops		= &clkhwops_omap3_dpll,
+};
+
+DEFINE_STRUCT_CLK(dpll_mpu_ck, dpll_core_ck_parents, dpll_abe_ck_ops);
+
+DEFINE_CLK_FIXED_FACTOR(mpu_periphclk, "dpll_mpu_ck", &dpll_mpu_ck, 0x0, 1, 2);
+
+DEFINE_CLK_OMAP_HSDIVIDER(dpll_mpu_m2_ck, "dpll_mpu_ck", &dpll_mpu_ck, 0x0,
+			  OMAP4430_CM_DIV_M2_DPLL_MPU,
+			  OMAP4430_DPLL_CLKOUT_DIV_MASK);
+
+DEFINE_CLK_FIXED_FACTOR(per_hs_clk_div_ck, "dpll_abe_m3x2_ck",
+			&dpll_abe_m3x2_ck, 0x0, 1, 2);
+
+static const char *per_hsd_byp_clk_mux_ck_parents[] = {
+	"sys_clkin_ck", "per_hs_clk_div_ck",
+};
+
+DEFINE_CLK_MUX(per_hsd_byp_clk_mux_ck, per_hsd_byp_clk_mux_ck_parents, NULL,
+	       0x0, OMAP4430_CM_CLKSEL_DPLL_PER, OMAP4430_DPLL_BYP_CLKSEL_SHIFT,
+	       OMAP4430_DPLL_BYP_CLKSEL_WIDTH, 0x0, NULL);
+
+/* DPLL_PER */
+static struct dpll_data dpll_per_dd = {
+	.mult_div1_reg	= OMAP4430_CM_CLKSEL_DPLL_PER,
+	.clk_bypass	= &per_hsd_byp_clk_mux_ck,
+	.clk_ref	= &sys_clkin_ck,
+	.control_reg	= OMAP4430_CM_CLKMODE_DPLL_PER,
+	.modes		= (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
+	.autoidle_reg	= OMAP4430_CM_AUTOIDLE_DPLL_PER,
+	.idlest_reg	= OMAP4430_CM_IDLEST_DPLL_PER,
+	.mult_mask	= OMAP4430_DPLL_MULT_MASK,
+	.div1_mask	= OMAP4430_DPLL_DIV_MASK,
+	.enable_mask	= OMAP4430_DPLL_EN_MASK,
+	.autoidle_mask	= OMAP4430_AUTO_DPLL_MODE_MASK,
+	.idlest_mask	= OMAP4430_ST_DPLL_CLK_MASK,
+	.max_multiplier	= 2047,
+	.max_divider	= 128,
+	.min_divider	= 1,
+};
+
+
+static struct clk dpll_per_ck;
+
+static struct clk_hw_omap dpll_per_ck_hw = {
+	.hw = {
+		.clk = &dpll_per_ck,
+	},
+	.dpll_data	= &dpll_per_dd,
+	.ops		= &clkhwops_omap3_dpll,
+};
+
+DEFINE_STRUCT_CLK(dpll_per_ck, dpll_core_ck_parents, dpll_abe_ck_ops);
+
+DEFINE_CLK_DIVIDER(dpll_per_m2_ck, "dpll_per_ck", &dpll_per_ck, 0x0,
+		   OMAP4430_CM_DIV_M2_DPLL_PER, OMAP4430_DPLL_CLKOUT_DIV_SHIFT,
+		   OMAP4430_DPLL_CLKOUT_DIV_WIDTH, CLK_DIVIDER_ONE_BASED, NULL);
+
+static const char *dpll_per_x2_ck_parents[] = {
+	"dpll_per_ck",
+};
+
+static struct clk dpll_per_x2_ck;
+
+static struct clk_hw_omap dpll_per_x2_ck_hw = {
+	.hw = {
+		.clk = &dpll_per_x2_ck,
+	},
+	.flags		= CLOCK_CLKOUTX2,
+	.clksel_reg	= OMAP4430_CM_DIV_M2_DPLL_PER,
+	.ops		= &clkhwops_omap4_dpllmx,
+};
+
+DEFINE_STRUCT_CLK(dpll_per_x2_ck, dpll_per_x2_ck_parents, dpll_abe_x2_ck_ops);
+
+DEFINE_CLK_OMAP_HSDIVIDER(dpll_per_m2x2_ck, "dpll_per_x2_ck", &dpll_per_x2_ck,
+			  0x0, OMAP4430_CM_DIV_M2_DPLL_PER,
+			  OMAP4430_DPLL_CLKOUT_DIV_MASK);
+
+static const char *dpll_per_m3x2_ck_parents[] = {
+	"dpll_per_x2_ck",
+};
+
+static const struct clksel dpll_per_m3x2_div[] = {
+	{ .parent = &dpll_per_x2_ck, .rates = div31_1to31_rates },
+	{ .parent = NULL },
+};
+
+/* XXX Missing round_rate, set_rate in ops */
+DEFINE_CLK_OMAP_MUX_GATE(dpll_per_m3x2_ck, NULL, dpll_per_m3x2_div,
+			 OMAP4430_CM_DIV_M3_DPLL_PER,
+			 OMAP4430_DPLL_CLKOUTHIF_DIV_MASK,
+			 OMAP4430_CM_DIV_M3_DPLL_PER,
+			 OMAP4430_DPLL_CLKOUTHIF_GATE_CTRL_SHIFT, NULL,
+			 dpll_per_m3x2_ck_parents, dmic_fck_ops);
+
+DEFINE_CLK_OMAP_HSDIVIDER(dpll_per_m4x2_ck, "dpll_per_x2_ck", &dpll_per_x2_ck,
+			  0x0, OMAP4430_CM_DIV_M4_DPLL_PER,
+			  OMAP4430_HSDIVIDER_CLKOUT1_DIV_MASK);
+
+DEFINE_CLK_OMAP_HSDIVIDER(dpll_per_m5x2_ck, "dpll_per_x2_ck", &dpll_per_x2_ck,
+			  0x0, OMAP4430_CM_DIV_M5_DPLL_PER,
+			  OMAP4430_HSDIVIDER_CLKOUT2_DIV_MASK);
+
+DEFINE_CLK_OMAP_HSDIVIDER(dpll_per_m6x2_ck, "dpll_per_x2_ck", &dpll_per_x2_ck,
+			  0x0, OMAP4430_CM_DIV_M6_DPLL_PER,
+			  OMAP4430_HSDIVIDER_CLKOUT3_DIV_MASK);
+
+DEFINE_CLK_OMAP_HSDIVIDER(dpll_per_m7x2_ck, "dpll_per_x2_ck", &dpll_per_x2_ck,
+			  0x0, OMAP4430_CM_DIV_M7_DPLL_PER,
+			  OMAP4430_HSDIVIDER_CLKOUT4_DIV_MASK);
+
+DEFINE_CLK_FIXED_FACTOR(usb_hs_clk_div_ck, "dpll_abe_m3x2_ck",
+			&dpll_abe_m3x2_ck, 0x0, 1, 3);
+
+/* DPLL_USB */
+static struct dpll_data dpll_usb_dd = {
+	.mult_div1_reg	= OMAP4430_CM_CLKSEL_DPLL_USB,
+	.clk_bypass	= &usb_hs_clk_div_ck,
+	.flags		= DPLL_J_TYPE,
+	.clk_ref	= &sys_clkin_ck,
+	.control_reg	= OMAP4430_CM_CLKMODE_DPLL_USB,
+	.modes		= (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
+	.autoidle_reg	= OMAP4430_CM_AUTOIDLE_DPLL_USB,
+	.idlest_reg	= OMAP4430_CM_IDLEST_DPLL_USB,
+	.mult_mask	= OMAP4430_DPLL_MULT_USB_MASK,
+	.div1_mask	= OMAP4430_DPLL_DIV_0_7_MASK,
+	.enable_mask	= OMAP4430_DPLL_EN_MASK,
+	.autoidle_mask	= OMAP4430_AUTO_DPLL_MODE_MASK,
+	.idlest_mask	= OMAP4430_ST_DPLL_CLK_MASK,
+	.sddiv_mask	= OMAP4430_DPLL_SD_DIV_MASK,
+	.max_multiplier	= 4095,
+	.max_divider	= 256,
+	.min_divider	= 1,
+};
+
+static struct clk dpll_usb_ck;
+
+static struct clk_hw_omap dpll_usb_ck_hw = {
+	.hw = {
+		.clk = &dpll_usb_ck,
+	},
+	.dpll_data	= &dpll_usb_dd,
+	.ops		= &clkhwops_omap3_dpll,
+};
+
+DEFINE_STRUCT_CLK(dpll_usb_ck, dpll_core_ck_parents, dpll_abe_ck_ops);
+
+static const char *dpll_usb_clkdcoldo_ck_parents[] = {
+	"dpll_usb_ck",
+};
+
+static struct clk dpll_usb_clkdcoldo_ck;
+
+static const struct clk_ops dpll_usb_clkdcoldo_ck_ops = {
+};
+
+static struct clk_hw_omap dpll_usb_clkdcoldo_ck_hw = {
+	.hw = {
+		.clk = &dpll_usb_clkdcoldo_ck,
+	},
+	.clksel_reg	= OMAP4430_CM_CLKDCOLDO_DPLL_USB,
+	.ops		= &clkhwops_omap4_dpllmx,
+};
+
+DEFINE_STRUCT_CLK(dpll_usb_clkdcoldo_ck, dpll_usb_clkdcoldo_ck_parents,
+		  dpll_usb_clkdcoldo_ck_ops);
+
+DEFINE_CLK_OMAP_HSDIVIDER(dpll_usb_m2_ck, "dpll_usb_ck", &dpll_usb_ck, 0x0,
+			  OMAP4430_CM_DIV_M2_DPLL_USB,
+			  OMAP4430_DPLL_CLKOUT_DIV_0_6_MASK);
+
+static const char *ducati_clk_mux_ck_parents[] = {
+	"div_core_ck", "dpll_per_m6x2_ck",
+};
+
+DEFINE_CLK_MUX(ducati_clk_mux_ck, ducati_clk_mux_ck_parents, NULL, 0x0,
+	       OMAP4430_CM_CLKSEL_DUCATI_ISS_ROOT, OMAP4430_CLKSEL_0_0_SHIFT,
+	       OMAP4430_CLKSEL_0_0_WIDTH, 0x0, NULL);
+
+DEFINE_CLK_FIXED_FACTOR(func_12m_fclk, "dpll_per_m2x2_ck", &dpll_per_m2x2_ck,
+			0x0, 1, 16);
+
+DEFINE_CLK_FIXED_FACTOR(func_24m_clk, "dpll_per_m2_ck", &dpll_per_m2_ck, 0x0,
+			1, 4);
+
+DEFINE_CLK_FIXED_FACTOR(func_24mc_fclk, "dpll_per_m2x2_ck", &dpll_per_m2x2_ck,
+			0x0, 1, 8);
+
+static const struct clk_div_table func_48m_fclk_rates[] = {
+	{ .div = 4, .val = 0 },
+	{ .div = 8, .val = 1 },
+	{ .div = 0 },
+};
+DEFINE_CLK_DIVIDER_TABLE(func_48m_fclk, "dpll_per_m2x2_ck", &dpll_per_m2x2_ck,
+			 0x0, OMAP4430_CM_SCALE_FCLK, OMAP4430_SCALE_FCLK_SHIFT,
+			 OMAP4430_SCALE_FCLK_WIDTH, 0x0, func_48m_fclk_rates,
+			 NULL);
+
+DEFINE_CLK_FIXED_FACTOR(func_48mc_fclk,	"dpll_per_m2x2_ck", &dpll_per_m2x2_ck,
+			0x0, 1, 4);
+
+static const struct clk_div_table func_64m_fclk_rates[] = {
+	{ .div = 2, .val = 0 },
+	{ .div = 4, .val = 1 },
+	{ .div = 0 },
+};
+DEFINE_CLK_DIVIDER_TABLE(func_64m_fclk, "dpll_per_m4x2_ck", &dpll_per_m4x2_ck,
+			 0x0, OMAP4430_CM_SCALE_FCLK, OMAP4430_SCALE_FCLK_SHIFT,
+			 OMAP4430_SCALE_FCLK_WIDTH, 0x0, func_64m_fclk_rates,
+			 NULL);
+
+static const struct clk_div_table func_96m_fclk_rates[] = {
+	{ .div = 2, .val = 0 },
+	{ .div = 4, .val = 1 },
+	{ .div = 0 },
+};
+DEFINE_CLK_DIVIDER_TABLE(func_96m_fclk, "dpll_per_m2x2_ck", &dpll_per_m2x2_ck,
+			 0x0, OMAP4430_CM_SCALE_FCLK, OMAP4430_SCALE_FCLK_SHIFT,
+			 OMAP4430_SCALE_FCLK_WIDTH, 0x0, func_96m_fclk_rates,
+			 NULL);
+
+static const struct clk_div_table init_60m_fclk_rates[] = {
+	{ .div = 1, .val = 0 },
+	{ .div = 8, .val = 1 },
+	{ .div = 0 },
+};
+DEFINE_CLK_DIVIDER_TABLE(init_60m_fclk, "dpll_usb_m2_ck", &dpll_usb_m2_ck,
+			 0x0, OMAP4430_CM_CLKSEL_USB_60MHZ,
+			 OMAP4430_CLKSEL_0_0_SHIFT, OMAP4430_CLKSEL_0_0_WIDTH,
+			 0x0, init_60m_fclk_rates, NULL);
+
+DEFINE_CLK_DIVIDER(l3_div_ck, "div_core_ck", &div_core_ck, 0x0,
+		   OMAP4430_CM_CLKSEL_CORE, OMAP4430_CLKSEL_L3_SHIFT,
+		   OMAP4430_CLKSEL_L3_WIDTH, 0x0, NULL);
+
+DEFINE_CLK_DIVIDER(l4_div_ck, "l3_div_ck", &l3_div_ck, 0x0,
+		   OMAP4430_CM_CLKSEL_CORE, OMAP4430_CLKSEL_L4_SHIFT,
+		   OMAP4430_CLKSEL_L4_WIDTH, 0x0, NULL);
+
+DEFINE_CLK_FIXED_FACTOR(lp_clk_div_ck, "dpll_abe_m2x2_ck", &dpll_abe_m2x2_ck,
+			0x0, 1, 16);
+
+static const char *l4_wkup_clk_mux_ck_parents[] = {
+	"sys_clkin_ck", "lp_clk_div_ck",
+};
+
+DEFINE_CLK_MUX(l4_wkup_clk_mux_ck, l4_wkup_clk_mux_ck_parents, NULL, 0x0,
+	       OMAP4430_CM_L4_WKUP_CLKSEL, OMAP4430_CLKSEL_0_0_SHIFT,
+	       OMAP4430_CLKSEL_0_0_WIDTH, 0x0, NULL);
+
+static const struct clk_div_table ocp_abe_iclk_rates[] = {
+	{ .div = 2, .val = 0 },
+	{ .div = 1, .val = 1 },
+	{ .div = 0 },
+};
+DEFINE_CLK_DIVIDER_TABLE(ocp_abe_iclk, "aess_fclk", &aess_fclk, 0x0,
+			 OMAP4430_CM1_ABE_AESS_CLKCTRL,
+			 OMAP4430_CLKSEL_AESS_FCLK_SHIFT,
+			 OMAP4430_CLKSEL_AESS_FCLK_WIDTH,
+			 0x0, ocp_abe_iclk_rates, NULL);
+
+DEFINE_CLK_FIXED_FACTOR(per_abe_24m_fclk, "dpll_abe_m2_ck", &dpll_abe_m2_ck,
+			0x0, 1, 4);
+
+DEFINE_CLK_DIVIDER(per_abe_nc_fclk, "dpll_abe_m2_ck", &dpll_abe_m2_ck, 0x0,
+		   OMAP4430_CM_SCALE_FCLK, OMAP4430_SCALE_FCLK_SHIFT,
+		   OMAP4430_SCALE_FCLK_WIDTH, 0x0, NULL);
+
+DEFINE_CLK_DIVIDER(syc_clk_div_ck, "sys_clkin_ck", &sys_clkin_ck, 0x0,
+		   OMAP4430_CM_ABE_DSS_SYS_CLKSEL, OMAP4430_CLKSEL_0_0_SHIFT,
+		   OMAP4430_CLKSEL_0_0_WIDTH, 0x0, NULL);
+
+static struct clk dbgclk_mux_ck;
+DEFINE_STRUCT_CLK_HW_OMAP(dbgclk_mux_ck, NULL);
+DEFINE_STRUCT_CLK(dbgclk_mux_ck, dpll_core_ck_parents,
+		  dpll_usb_clkdcoldo_ck_ops);
+
+/* Leaf clocks controlled by modules */
+
+DEFINE_CLK_GATE(aes1_fck, "l3_div_ck", &l3_div_ck, 0x0,
+		OMAP4430_CM_L4SEC_AES1_CLKCTRL,
+		OMAP4430_MODULEMODE_SWCTRL_SHIFT, 0x0, NULL);
+
+DEFINE_CLK_GATE(aes2_fck, "l3_div_ck", &l3_div_ck, 0x0,
+		OMAP4430_CM_L4SEC_AES2_CLKCTRL,
+		OMAP4430_MODULEMODE_SWCTRL_SHIFT, 0x0, NULL);
+
+DEFINE_CLK_GATE(aess_fck, "aess_fclk", &aess_fclk, 0x0,
+		OMAP4430_CM1_ABE_AESS_CLKCTRL, OMAP4430_MODULEMODE_SWCTRL_SHIFT,
+		0x0, NULL);
+
+DEFINE_CLK_GATE(bandgap_fclk, "sys_32k_ck", &sys_32k_ck, 0x0,
+		OMAP4430_CM_WKUP_BANDGAP_CLKCTRL,
+		OMAP4430_OPTFCLKEN_BGAP_32K_SHIFT, 0x0, NULL);
+
+static const struct clk_div_table div_ts_ck_rates[] = {
+	{ .div = 8, .val = 0 },
+	{ .div = 16, .val = 1 },
+	{ .div = 32, .val = 2 },
+	{ .div = 0 },
+};
+DEFINE_CLK_DIVIDER_TABLE(div_ts_ck, "l4_wkup_clk_mux_ck", &l4_wkup_clk_mux_ck,
+			 0x0, OMAP4430_CM_WKUP_BANDGAP_CLKCTRL,
+			 OMAP4430_CLKSEL_24_25_SHIFT,
+			 OMAP4430_CLKSEL_24_25_WIDTH, 0x0, div_ts_ck_rates,
+			 NULL);
+
+DEFINE_CLK_GATE(bandgap_ts_fclk, "div_ts_ck", &div_ts_ck, 0x0,
+		OMAP4430_CM_WKUP_BANDGAP_CLKCTRL,
+		OMAP4460_OPTFCLKEN_TS_FCLK_SHIFT,
+		0x0, NULL);
+
+DEFINE_CLK_GATE(des3des_fck, "l4_div_ck", &l4_div_ck, 0x0,
+		OMAP4430_CM_L4SEC_DES3DES_CLKCTRL,
+		OMAP4430_MODULEMODE_SWCTRL_SHIFT,
+		0x0, NULL);
+
+static const char *dmic_sync_mux_ck_parents[] = {
+	"abe_24m_fclk", "syc_clk_div_ck", "func_24m_clk",
+};
+
+DEFINE_CLK_MUX(dmic_sync_mux_ck, dmic_sync_mux_ck_parents, NULL,
+	       0x0, OMAP4430_CM1_ABE_DMIC_CLKCTRL,
+	       OMAP4430_CLKSEL_INTERNAL_SOURCE_SHIFT,
+	       OMAP4430_CLKSEL_INTERNAL_SOURCE_WIDTH, 0x0, NULL);
+
+static const struct clksel func_dmic_abe_gfclk_sel[] = {
+	{ .parent = &dmic_sync_mux_ck, .rates = div_1_0_rates },
+	{ .parent = &pad_clks_ck, .rates = div_1_1_rates },
+	{ .parent = &slimbus_clk, .rates = div_1_2_rates },
+	{ .parent = NULL },
+};
+
+static const char *dmic_fck_parents[] = {
+	"dmic_sync_mux_ck", "pad_clks_ck", "slimbus_clk",
+};
+
+/* Merged func_dmic_abe_gfclk into dmic */
+static struct clk dmic_fck;
+
+DEFINE_CLK_OMAP_MUX_GATE(dmic_fck, "abe_clkdm", func_dmic_abe_gfclk_sel,
+			 OMAP4430_CM1_ABE_DMIC_CLKCTRL,
+			 OMAP4430_CLKSEL_SOURCE_MASK,
+			 OMAP4430_CM1_ABE_DMIC_CLKCTRL,
+			 OMAP4430_MODULEMODE_SWCTRL_SHIFT, NULL,
+			 dmic_fck_parents, dmic_fck_ops);
+
+DEFINE_CLK_GATE(dsp_fck, "dpll_iva_m4x2_ck", &dpll_iva_m4x2_ck, 0x0,
+		OMAP4430_CM_TESLA_TESLA_CLKCTRL,
+		OMAP4430_MODULEMODE_HWCTRL_SHIFT, 0x0, NULL);
+
+DEFINE_CLK_GATE(dss_sys_clk, "syc_clk_div_ck", &syc_clk_div_ck, 0x0,
+		OMAP4430_CM_DSS_DSS_CLKCTRL,
+		OMAP4430_OPTFCLKEN_SYS_CLK_SHIFT, 0x0, NULL);
+
+DEFINE_CLK_GATE(dss_tv_clk, "extalt_clkin_ck", &extalt_clkin_ck, 0x0,
+		OMAP4430_CM_DSS_DSS_CLKCTRL,
+		OMAP4430_OPTFCLKEN_TV_CLK_SHIFT, 0x0, NULL);
+
+DEFINE_CLK_GATE(dss_dss_clk, "dpll_per_m5x2_ck", &dpll_per_m5x2_ck, 0x0,
+		OMAP4430_CM_DSS_DSS_CLKCTRL, OMAP4430_OPTFCLKEN_DSSCLK_SHIFT,
+		0x0, NULL);
+
+DEFINE_CLK_GATE(dss_48mhz_clk, "func_48mc_fclk", &func_48mc_fclk, 0x0,
+		OMAP4430_CM_DSS_DSS_CLKCTRL, OMAP4430_OPTFCLKEN_48MHZ_CLK_SHIFT,
+		0x0, NULL);
+
+DEFINE_CLK_GATE(dss_fck, "l3_div_ck", &l3_div_ck, 0x0,
+		OMAP4430_CM_DSS_DSS_CLKCTRL, OMAP4430_MODULEMODE_SWCTRL_SHIFT,
+		0x0, NULL);
+
+DEFINE_CLK_GATE(efuse_ctrl_cust_fck, "sys_clkin_ck", &sys_clkin_ck, 0x0,
+		OMAP4430_CM_CEFUSE_CEFUSE_CLKCTRL,
+		OMAP4430_MODULEMODE_SWCTRL_SHIFT, 0x0, NULL);
+
+DEFINE_CLK_GATE(emif1_fck, "ddrphy_ck", &ddrphy_ck, 0x0,
+		OMAP4430_CM_MEMIF_EMIF_1_CLKCTRL,
+		OMAP4430_MODULEMODE_HWCTRL_SHIFT, 0x0, NULL);
+
+DEFINE_CLK_GATE(emif2_fck, "ddrphy_ck", &ddrphy_ck, 0x0,
+		OMAP4430_CM_MEMIF_EMIF_2_CLKCTRL,
+		OMAP4430_MODULEMODE_HWCTRL_SHIFT, 0x0, NULL);
+
+DEFINE_CLK_DIVIDER(fdif_fck, "dpll_per_m4x2_ck", &dpll_per_m4x2_ck, 0x0,
+		   OMAP4430_CM_CAM_FDIF_CLKCTRL, OMAP4430_CLKSEL_FCLK_SHIFT,
+		   OMAP4430_CLKSEL_FCLK_WIDTH, CLK_DIVIDER_POWER_OF_TWO, NULL);
+
+DEFINE_CLK_GATE(fpka_fck, "l4_div_ck", &l4_div_ck, 0x0,
+		OMAP4430_CM_L4SEC_PKAEIP29_CLKCTRL,
+		OMAP4430_MODULEMODE_SWCTRL_SHIFT, 0x0, NULL);
+
+DEFINE_CLK_GATE(gpio1_dbclk, "sys_32k_ck", &sys_32k_ck, 0x0,
+		OMAP4430_CM_WKUP_GPIO1_CLKCTRL,
+		OMAP4430_OPTFCLKEN_DBCLK_SHIFT,	0x0, NULL);
+
+DEFINE_CLK_GATE(gpio1_ick, "l4_wkup_clk_mux_ck", &l4_wkup_clk_mux_ck, 0x0,
+		OMAP4430_CM_WKUP_GPIO1_CLKCTRL,
+		OMAP4430_MODULEMODE_HWCTRL_SHIFT, 0x0, NULL);
+
+DEFINE_CLK_GATE(gpio2_dbclk, "sys_32k_ck", &sys_32k_ck, 0x0,
+		OMAP4430_CM_L4PER_GPIO2_CLKCTRL, OMAP4430_OPTFCLKEN_DBCLK_SHIFT,
+		0x0, NULL);
+
+DEFINE_CLK_GATE(gpio2_ick, "l4_div_ck", &l4_div_ck, 0x0,
+		OMAP4430_CM_L4PER_GPIO2_CLKCTRL,
+		OMAP4430_MODULEMODE_HWCTRL_SHIFT, 0x0, NULL);
+
+DEFINE_CLK_GATE(gpio3_dbclk, "sys_32k_ck", &sys_32k_ck, 0x0,
+		OMAP4430_CM_L4PER_GPIO3_CLKCTRL,
+		OMAP4430_OPTFCLKEN_DBCLK_SHIFT, 0x0, NULL);
+
+DEFINE_CLK_GATE(gpio3_ick, "l4_div_ck", &l4_div_ck, 0x0,
+		OMAP4430_CM_L4PER_GPIO3_CLKCTRL,
+		OMAP4430_MODULEMODE_HWCTRL_SHIFT, 0x0, NULL);
+
+DEFINE_CLK_GATE(gpio4_dbclk, "sys_32k_ck", &sys_32k_ck, 0x0,
+		OMAP4430_CM_L4PER_GPIO4_CLKCTRL, OMAP4430_OPTFCLKEN_DBCLK_SHIFT,
+		0x0, NULL);
+
+DEFINE_CLK_GATE(gpio4_ick, "l4_div_ck", &l4_div_ck, 0x0,
+		OMAP4430_CM_L4PER_GPIO4_CLKCTRL,
+		OMAP4430_MODULEMODE_HWCTRL_SHIFT, 0x0, NULL);
+
+DEFINE_CLK_GATE(gpio5_dbclk, "sys_32k_ck", &sys_32k_ck, 0x0,
+		OMAP4430_CM_L4PER_GPIO5_CLKCTRL, OMAP4430_OPTFCLKEN_DBCLK_SHIFT,
+		0x0, NULL);
+
+DEFINE_CLK_GATE(gpio5_ick, "l4_div_ck", &l4_div_ck, 0x0,
+		OMAP4430_CM_L4PER_GPIO5_CLKCTRL,
+		OMAP4430_MODULEMODE_HWCTRL_SHIFT, 0x0, NULL);
+
+DEFINE_CLK_GATE(gpio6_dbclk, "sys_32k_ck", &sys_32k_ck, 0x0,
+		OMAP4430_CM_L4PER_GPIO6_CLKCTRL, OMAP4430_OPTFCLKEN_DBCLK_SHIFT,
+		0x0, NULL);
+
+DEFINE_CLK_GATE(gpio6_ick, "l4_div_ck", &l4_div_ck, 0x0,
+		OMAP4430_CM_L4PER_GPIO6_CLKCTRL,
+		OMAP4430_MODULEMODE_HWCTRL_SHIFT, 0x0, NULL);
+
+DEFINE_CLK_GATE(gpmc_ick, "l3_div_ck", &l3_div_ck, 0x0,
+		OMAP4430_CM_L3_2_GPMC_CLKCTRL, OMAP4430_MODULEMODE_HWCTRL_SHIFT,
+		0x0, NULL);
+
+static const struct clksel sgx_clk_mux_sel[] = {
+	{ .parent = &dpll_core_m7x2_ck, .rates = div_1_0_rates },
+	{ .parent = &dpll_per_m7x2_ck, .rates = div_1_1_rates },
+	{ .parent = NULL },
+};
+
+static const char *gpu_fck_parents[] = {
+	"dpll_core_m7x2_ck", "dpll_per_m7x2_ck",
+};
+
+/* Merged sgx_clk_mux into gpu */
+DEFINE_CLK_OMAP_MUX_GATE(gpu_fck, "l3_gfx_clkdm", sgx_clk_mux_sel,
+			 OMAP4430_CM_GFX_GFX_CLKCTRL,
+			 OMAP4430_CLKSEL_SGX_FCLK_MASK,
+			 OMAP4430_CM_GFX_GFX_CLKCTRL,
+			 OMAP4430_MODULEMODE_SWCTRL_SHIFT, NULL,
+			 gpu_fck_parents, dmic_fck_ops);
+
+DEFINE_CLK_GATE(hdq1w_fck, "func_12m_fclk", &func_12m_fclk, 0x0,
+		OMAP4430_CM_L4PER_HDQ1W_CLKCTRL,
+		OMAP4430_MODULEMODE_SWCTRL_SHIFT, 0x0, NULL);
+
+DEFINE_CLK_DIVIDER(hsi_fck, "dpll_per_m2x2_ck", &dpll_per_m2x2_ck, 0x0,
+		   OMAP4430_CM_L3INIT_HSI_CLKCTRL, OMAP4430_CLKSEL_24_25_SHIFT,
+		   OMAP4430_CLKSEL_24_25_WIDTH, CLK_DIVIDER_POWER_OF_TWO,
+		   NULL);
+
+DEFINE_CLK_GATE(i2c1_fck, "func_96m_fclk", &func_96m_fclk, 0x0,
+		OMAP4430_CM_L4PER_I2C1_CLKCTRL,
+		OMAP4430_MODULEMODE_SWCTRL_SHIFT, 0x0, NULL);
+
+DEFINE_CLK_GATE(i2c2_fck, "func_96m_fclk", &func_96m_fclk, 0x0,
+		OMAP4430_CM_L4PER_I2C2_CLKCTRL,
+		OMAP4430_MODULEMODE_SWCTRL_SHIFT, 0x0, NULL);
+
+DEFINE_CLK_GATE(i2c3_fck, "func_96m_fclk", &func_96m_fclk, 0x0,
+		OMAP4430_CM_L4PER_I2C3_CLKCTRL,
+		OMAP4430_MODULEMODE_SWCTRL_SHIFT, 0x0, NULL);
+
+DEFINE_CLK_GATE(i2c4_fck, "func_96m_fclk", &func_96m_fclk, 0x0,
+		OMAP4430_CM_L4PER_I2C4_CLKCTRL,
+		OMAP4430_MODULEMODE_SWCTRL_SHIFT, 0x0, NULL);
+
+DEFINE_CLK_GATE(ipu_fck, "ducati_clk_mux_ck", &ducati_clk_mux_ck, 0x0,
+		OMAP4430_CM_DUCATI_DUCATI_CLKCTRL,
+		OMAP4430_MODULEMODE_HWCTRL_SHIFT, 0x0, NULL);
+
+DEFINE_CLK_GATE(iss_ctrlclk, "func_96m_fclk", &func_96m_fclk, 0x0,
+		OMAP4430_CM_CAM_ISS_CLKCTRL, OMAP4430_OPTFCLKEN_CTRLCLK_SHIFT,
+		0x0, NULL);
+
+DEFINE_CLK_GATE(iss_fck, "ducati_clk_mux_ck", &ducati_clk_mux_ck, 0x0,
+		OMAP4430_CM_CAM_ISS_CLKCTRL, OMAP4430_MODULEMODE_SWCTRL_SHIFT,
+		0x0, NULL);
+
+DEFINE_CLK_GATE(iva_fck, "dpll_iva_m5x2_ck", &dpll_iva_m5x2_ck, 0x0,
+		OMAP4430_CM_IVAHD_IVAHD_CLKCTRL,
+		OMAP4430_MODULEMODE_HWCTRL_SHIFT, 0x0, NULL);
+
+DEFINE_CLK_GATE(kbd_fck, "sys_32k_ck", &sys_32k_ck, 0x0,
+		OMAP4430_CM_WKUP_KEYBOARD_CLKCTRL,
+		OMAP4430_MODULEMODE_SWCTRL_SHIFT, 0x0, NULL);
+
+static struct clk l3_instr_ick;
+
+static const char *l3_instr_ick_parent_names[] = {
+	"l3_div_ck",
+};
+
+static const struct clk_ops l3_instr_ick_ops = {
+	.enable		= &omap2_dflt_clk_enable,
+	.disable	= &omap2_dflt_clk_disable,
+	.is_enabled	= &omap2_dflt_clk_is_enabled,
+	.init		= &omap2_init_clk_clkdm,
+};
+
+static struct clk_hw_omap l3_instr_ick_hw = {
+	.hw = {
+		.clk = &l3_instr_ick,
+	},
+	.enable_reg	= OMAP4430_CM_L3INSTR_L3_INSTR_CLKCTRL,
+	.enable_bit	= OMAP4430_MODULEMODE_HWCTRL_SHIFT,
+	.clkdm_name	= "l3_instr_clkdm",
+};
+
+DEFINE_STRUCT_CLK(l3_instr_ick, l3_instr_ick_parent_names, l3_instr_ick_ops);
+
+static struct clk l3_main_3_ick;
+static struct clk_hw_omap l3_main_3_ick_hw = {
+	.hw = {
+		.clk = &l3_main_3_ick,
+	},
+	.enable_reg	= OMAP4430_CM_L3INSTR_L3_3_CLKCTRL,
+	.enable_bit	= OMAP4430_MODULEMODE_HWCTRL_SHIFT,
+	.clkdm_name	= "l3_instr_clkdm",
+};
+
+DEFINE_STRUCT_CLK(l3_main_3_ick, l3_instr_ick_parent_names, l3_instr_ick_ops);
+
+DEFINE_CLK_MUX(mcasp_sync_mux_ck, dmic_sync_mux_ck_parents, NULL, 0x0,
+	       OMAP4430_CM1_ABE_MCASP_CLKCTRL,
+	       OMAP4430_CLKSEL_INTERNAL_SOURCE_SHIFT,
+	       OMAP4430_CLKSEL_INTERNAL_SOURCE_WIDTH, 0x0, NULL);
+
+static const struct clksel func_mcasp_abe_gfclk_sel[] = {
+	{ .parent = &mcasp_sync_mux_ck, .rates = div_1_0_rates },
+	{ .parent = &pad_clks_ck, .rates = div_1_1_rates },
+	{ .parent = &slimbus_clk, .rates = div_1_2_rates },
+	{ .parent = NULL },
+};
+
+static const char *mcasp_fck_parents[] = {
+	"mcasp_sync_mux_ck", "pad_clks_ck", "slimbus_clk",
+};
+
+/* Merged func_mcasp_abe_gfclk into mcasp */
+DEFINE_CLK_OMAP_MUX_GATE(mcasp_fck, "abe_clkdm", func_mcasp_abe_gfclk_sel,
+			 OMAP4430_CM1_ABE_MCASP_CLKCTRL,
+			 OMAP4430_CLKSEL_SOURCE_MASK,
+			 OMAP4430_CM1_ABE_MCASP_CLKCTRL,
+			 OMAP4430_MODULEMODE_SWCTRL_SHIFT, NULL,
+			 mcasp_fck_parents, dmic_fck_ops);
+
+DEFINE_CLK_MUX(mcbsp1_sync_mux_ck, dmic_sync_mux_ck_parents, NULL, 0x0,
+	       OMAP4430_CM1_ABE_MCBSP1_CLKCTRL,
+	       OMAP4430_CLKSEL_INTERNAL_SOURCE_SHIFT,
+	       OMAP4430_CLKSEL_INTERNAL_SOURCE_WIDTH, 0x0, NULL);
+
+static const struct clksel func_mcbsp1_gfclk_sel[] = {
+	{ .parent = &mcbsp1_sync_mux_ck, .rates = div_1_0_rates },
+	{ .parent = &pad_clks_ck, .rates = div_1_1_rates },
+	{ .parent = &slimbus_clk, .rates = div_1_2_rates },
+	{ .parent = NULL },
+};
+
+static const char *mcbsp1_fck_parents[] = {
+	"mcbsp1_sync_mux_ck", "pad_clks_ck", "slimbus_clk",
+};
+
+/* Merged func_mcbsp1_gfclk into mcbsp1 */
+DEFINE_CLK_OMAP_MUX_GATE(mcbsp1_fck, "abe_clkdm", func_mcbsp1_gfclk_sel,
+			 OMAP4430_CM1_ABE_MCBSP1_CLKCTRL,
+			 OMAP4430_CLKSEL_SOURCE_MASK,
+			 OMAP4430_CM1_ABE_MCBSP1_CLKCTRL,
+			 OMAP4430_MODULEMODE_SWCTRL_SHIFT, NULL,
+			 mcbsp1_fck_parents, dmic_fck_ops);
+
+DEFINE_CLK_MUX(mcbsp2_sync_mux_ck, dmic_sync_mux_ck_parents, NULL, 0x0,
+	       OMAP4430_CM1_ABE_MCBSP2_CLKCTRL,
+	       OMAP4430_CLKSEL_INTERNAL_SOURCE_SHIFT,
+	       OMAP4430_CLKSEL_INTERNAL_SOURCE_WIDTH, 0x0, NULL);
+
+static const struct clksel func_mcbsp2_gfclk_sel[] = {
+	{ .parent = &mcbsp2_sync_mux_ck, .rates = div_1_0_rates },
+	{ .parent = &pad_clks_ck, .rates = div_1_1_rates },
+	{ .parent = &slimbus_clk, .rates = div_1_2_rates },
+	{ .parent = NULL },
+};
+
+static const char *mcbsp2_fck_parents[] = {
+	"mcbsp2_sync_mux_ck", "pad_clks_ck", "slimbus_clk",
+};
+
+/* Merged func_mcbsp2_gfclk into mcbsp2 */
+DEFINE_CLK_OMAP_MUX_GATE(mcbsp2_fck, "abe_clkdm", func_mcbsp2_gfclk_sel,
+			 OMAP4430_CM1_ABE_MCBSP2_CLKCTRL,
+			 OMAP4430_CLKSEL_SOURCE_MASK,
+			 OMAP4430_CM1_ABE_MCBSP2_CLKCTRL,
+			 OMAP4430_MODULEMODE_SWCTRL_SHIFT, NULL,
+			 mcbsp2_fck_parents, dmic_fck_ops);
+
+DEFINE_CLK_MUX(mcbsp3_sync_mux_ck, dmic_sync_mux_ck_parents, NULL, 0x0,
+	       OMAP4430_CM1_ABE_MCBSP3_CLKCTRL,
+	       OMAP4430_CLKSEL_INTERNAL_SOURCE_SHIFT,
+	       OMAP4430_CLKSEL_INTERNAL_SOURCE_WIDTH, 0x0, NULL);
+
+static const struct clksel func_mcbsp3_gfclk_sel[] = {
+	{ .parent = &mcbsp3_sync_mux_ck, .rates = div_1_0_rates },
+	{ .parent = &pad_clks_ck, .rates = div_1_1_rates },
+	{ .parent = &slimbus_clk, .rates = div_1_2_rates },
+	{ .parent = NULL },
+};
+
+static const char *mcbsp3_fck_parents[] = {
+	"mcbsp3_sync_mux_ck", "pad_clks_ck", "slimbus_clk",
+};
+
+/* Merged func_mcbsp3_gfclk into mcbsp3 */
+DEFINE_CLK_OMAP_MUX_GATE(mcbsp3_fck, "abe_clkdm", func_mcbsp3_gfclk_sel,
+			 OMAP4430_CM1_ABE_MCBSP3_CLKCTRL,
+			 OMAP4430_CLKSEL_SOURCE_MASK,
+			 OMAP4430_CM1_ABE_MCBSP3_CLKCTRL,
+			 OMAP4430_MODULEMODE_SWCTRL_SHIFT, NULL,
+			 mcbsp3_fck_parents, dmic_fck_ops);
+
+static const char *mcbsp4_sync_mux_ck_parents[] = {
+	"func_96m_fclk", "per_abe_nc_fclk",
+};
+
+DEFINE_CLK_MUX(mcbsp4_sync_mux_ck, mcbsp4_sync_mux_ck_parents, NULL, 0x0,
+	       OMAP4430_CM_L4PER_MCBSP4_CLKCTRL,
+	       OMAP4430_CLKSEL_INTERNAL_SOURCE_SHIFT,
+	       OMAP4430_CLKSEL_INTERNAL_SOURCE_WIDTH, 0x0, NULL);
+
+static const struct clksel per_mcbsp4_gfclk_sel[] = {
+	{ .parent = &mcbsp4_sync_mux_ck, .rates = div_1_0_rates },
+	{ .parent = &pad_clks_ck, .rates = div_1_1_rates },
+	{ .parent = NULL },
+};
+
+static const char *mcbsp4_fck_parents[] = {
+	"mcbsp4_sync_mux_ck", "pad_clks_ck",
+};
+
+/* Merged per_mcbsp4_gfclk into mcbsp4 */
+DEFINE_CLK_OMAP_MUX_GATE(mcbsp4_fck, "l4_per_clkdm", per_mcbsp4_gfclk_sel,
+			 OMAP4430_CM_L4PER_MCBSP4_CLKCTRL,
+			 OMAP4430_CLKSEL_SOURCE_24_24_MASK,
+			 OMAP4430_CM_L4PER_MCBSP4_CLKCTRL,
+			 OMAP4430_MODULEMODE_SWCTRL_SHIFT, NULL,
+			 mcbsp4_fck_parents, dmic_fck_ops);
+
+DEFINE_CLK_GATE(mcpdm_fck, "pad_clks_ck", &pad_clks_ck, 0x0,
+		OMAP4430_CM1_ABE_PDM_CLKCTRL, OMAP4430_MODULEMODE_SWCTRL_SHIFT,
+		0x0, NULL);
+
+DEFINE_CLK_GATE(mcspi1_fck, "func_48m_fclk", &func_48m_fclk, 0x0,
+		OMAP4430_CM_L4PER_MCSPI1_CLKCTRL,
+		OMAP4430_MODULEMODE_SWCTRL_SHIFT, 0x0, NULL);
+
+DEFINE_CLK_GATE(mcspi2_fck, "func_48m_fclk", &func_48m_fclk, 0x0,
+		OMAP4430_CM_L4PER_MCSPI2_CLKCTRL,
+		OMAP4430_MODULEMODE_SWCTRL_SHIFT, 0x0, NULL);
+
+DEFINE_CLK_GATE(mcspi3_fck, "func_48m_fclk", &func_48m_fclk, 0x0,
+		OMAP4430_CM_L4PER_MCSPI3_CLKCTRL,
+		OMAP4430_MODULEMODE_SWCTRL_SHIFT, 0x0, NULL);
+
+DEFINE_CLK_GATE(mcspi4_fck, "func_48m_fclk", &func_48m_fclk, 0x0,
+		OMAP4430_CM_L4PER_MCSPI4_CLKCTRL,
+		OMAP4430_MODULEMODE_SWCTRL_SHIFT, 0x0, NULL);
+
+static const struct clksel hsmmc1_fclk_sel[] = {
+	{ .parent = &func_64m_fclk, .rates = div_1_0_rates },
+	{ .parent = &func_96m_fclk, .rates = div_1_1_rates },
+	{ .parent = NULL },
+};
+
+static const char *mmc1_fck_parents[] = {
+	"func_64m_fclk", "func_96m_fclk",
+};
+
+/* Merged hsmmc1_fclk into mmc1 */
+DEFINE_CLK_OMAP_MUX_GATE(mmc1_fck, "l3_init_clkdm", hsmmc1_fclk_sel,
+			 OMAP4430_CM_L3INIT_MMC1_CLKCTRL, OMAP4430_CLKSEL_MASK,
+			 OMAP4430_CM_L3INIT_MMC1_CLKCTRL,
+			 OMAP4430_MODULEMODE_SWCTRL_SHIFT, NULL,
+			 mmc1_fck_parents, dmic_fck_ops);
+
+/* Merged hsmmc2_fclk into mmc2 */
+DEFINE_CLK_OMAP_MUX_GATE(mmc2_fck, "l3_init_clkdm", hsmmc1_fclk_sel,
+			 OMAP4430_CM_L3INIT_MMC2_CLKCTRL, OMAP4430_CLKSEL_MASK,
+			 OMAP4430_CM_L3INIT_MMC2_CLKCTRL,
+			 OMAP4430_MODULEMODE_SWCTRL_SHIFT, NULL,
+			 mmc1_fck_parents, dmic_fck_ops);
+
+DEFINE_CLK_GATE(mmc3_fck, "func_48m_fclk", &func_48m_fclk, 0x0,
+		OMAP4430_CM_L4PER_MMCSD3_CLKCTRL,
+		OMAP4430_MODULEMODE_SWCTRL_SHIFT, 0x0, NULL);
+
+DEFINE_CLK_GATE(mmc4_fck, "func_48m_fclk", &func_48m_fclk, 0x0,
+		OMAP4430_CM_L4PER_MMCSD4_CLKCTRL,
+		OMAP4430_MODULEMODE_SWCTRL_SHIFT, 0x0, NULL);
+
+DEFINE_CLK_GATE(mmc5_fck, "func_48m_fclk", &func_48m_fclk, 0x0,
+		OMAP4430_CM_L4PER_MMCSD5_CLKCTRL,
+		OMAP4430_MODULEMODE_SWCTRL_SHIFT, 0x0, NULL);
+
+DEFINE_CLK_GATE(ocp2scp_usb_phy_phy_48m, "func_48m_fclk", &func_48m_fclk, 0x0,
+		OMAP4430_CM_L3INIT_USBPHYOCP2SCP_CLKCTRL,
+		OMAP4430_OPTFCLKEN_PHY_48M_SHIFT, 0x0, NULL);
+
+DEFINE_CLK_GATE(ocp2scp_usb_phy_ick, "l4_div_ck", &l4_div_ck, 0x0,
+		OMAP4430_CM_L3INIT_USBPHYOCP2SCP_CLKCTRL,
+		OMAP4430_MODULEMODE_HWCTRL_SHIFT, 0x0, NULL);
+
+static struct clk ocp_wp_noc_ick;
+
+static struct clk_hw_omap ocp_wp_noc_ick_hw = {
+	.hw = {
+		.clk = &ocp_wp_noc_ick,
+	},
+	.enable_reg	= OMAP4430_CM_L3INSTR_OCP_WP1_CLKCTRL,
+	.enable_bit	= OMAP4430_MODULEMODE_HWCTRL_SHIFT,
+	.clkdm_name	= "l3_instr_clkdm",
+};
+
+DEFINE_STRUCT_CLK(ocp_wp_noc_ick, l3_instr_ick_parent_names, l3_instr_ick_ops);
+
+DEFINE_CLK_GATE(rng_ick, "l4_div_ck", &l4_div_ck, 0x0,
+		OMAP4430_CM_L4SEC_RNG_CLKCTRL, OMAP4430_MODULEMODE_HWCTRL_SHIFT,
+		0x0, NULL);
+
+DEFINE_CLK_GATE(sha2md5_fck, "l3_div_ck", &l3_div_ck, 0x0,
+		OMAP4430_CM_L4SEC_SHA2MD51_CLKCTRL,
+		OMAP4430_MODULEMODE_SWCTRL_SHIFT, 0x0, NULL);
+
+DEFINE_CLK_GATE(sl2if_ick, "dpll_iva_m5x2_ck", &dpll_iva_m5x2_ck, 0x0,
+		OMAP4430_CM_IVAHD_SL2_CLKCTRL, OMAP4430_MODULEMODE_HWCTRL_SHIFT,
+		0x0, NULL);
+
+DEFINE_CLK_GATE(slimbus1_fclk_1, "func_24m_clk", &func_24m_clk, 0x0,
+		OMAP4430_CM1_ABE_SLIMBUS_CLKCTRL,
+		OMAP4430_OPTFCLKEN_FCLK1_SHIFT, 0x0, NULL);
+
+DEFINE_CLK_GATE(slimbus1_fclk_0, "abe_24m_fclk", &abe_24m_fclk, 0x0,
+		OMAP4430_CM1_ABE_SLIMBUS_CLKCTRL,
+		OMAP4430_OPTFCLKEN_FCLK0_SHIFT, 0x0, NULL);
+
+DEFINE_CLK_GATE(slimbus1_fclk_2, "pad_clks_ck", &pad_clks_ck, 0x0,
+		OMAP4430_CM1_ABE_SLIMBUS_CLKCTRL,
+		OMAP4430_OPTFCLKEN_FCLK2_SHIFT, 0x0, NULL);
+
+DEFINE_CLK_GATE(slimbus1_slimbus_clk, "slimbus_clk", &slimbus_clk, 0x0,
+		OMAP4430_CM1_ABE_SLIMBUS_CLKCTRL,
+		OMAP4430_OPTFCLKEN_SLIMBUS_CLK_11_11_SHIFT, 0x0, NULL);
+
+DEFINE_CLK_GATE(slimbus1_fck, "ocp_abe_iclk", &ocp_abe_iclk, 0x0,
+		OMAP4430_CM1_ABE_SLIMBUS_CLKCTRL,
+		OMAP4430_MODULEMODE_SWCTRL_SHIFT, 0x0, NULL);
+
+DEFINE_CLK_GATE(slimbus2_fclk_1, "per_abe_24m_fclk", &per_abe_24m_fclk, 0x0,
+		OMAP4430_CM_L4PER_SLIMBUS2_CLKCTRL,
+		OMAP4430_OPTFCLKEN_PERABE24M_GFCLK_SHIFT, 0x0, NULL);
+
+DEFINE_CLK_GATE(slimbus2_fclk_0, "func_24mc_fclk", &func_24mc_fclk, 0x0,
+		OMAP4430_CM_L4PER_SLIMBUS2_CLKCTRL,
+		OMAP4430_OPTFCLKEN_PER24MC_GFCLK_SHIFT, 0x0, NULL);
+
+DEFINE_CLK_GATE(slimbus2_slimbus_clk, "pad_slimbus_core_clks_ck",
+		&pad_slimbus_core_clks_ck, 0x0,
+		OMAP4430_CM_L4PER_SLIMBUS2_CLKCTRL,
+		OMAP4430_OPTFCLKEN_SLIMBUS_CLK_SHIFT, 0x0, NULL);
+
+DEFINE_CLK_GATE(slimbus2_fck, "l4_div_ck", &l4_div_ck, 0x0,
+		OMAP4430_CM_L4PER_SLIMBUS2_CLKCTRL,
+		OMAP4430_MODULEMODE_SWCTRL_SHIFT, 0x0, NULL);
+
+DEFINE_CLK_GATE(smartreflex_core_fck, "l4_wkup_clk_mux_ck", &l4_wkup_clk_mux_ck,
+		0x0, OMAP4430_CM_ALWON_SR_CORE_CLKCTRL,
+		OMAP4430_MODULEMODE_SWCTRL_SHIFT, 0x0, NULL);
+
+DEFINE_CLK_GATE(smartreflex_iva_fck, "l4_wkup_clk_mux_ck", &l4_wkup_clk_mux_ck,
+		0x0, OMAP4430_CM_ALWON_SR_IVA_CLKCTRL,
+		OMAP4430_MODULEMODE_SWCTRL_SHIFT, 0x0, NULL);
+
+DEFINE_CLK_GATE(smartreflex_mpu_fck, "l4_wkup_clk_mux_ck", &l4_wkup_clk_mux_ck,
+		0x0, OMAP4430_CM_ALWON_SR_MPU_CLKCTRL,
+		OMAP4430_MODULEMODE_SWCTRL_SHIFT, 0x0, NULL);
+
+static const struct clksel dmt1_clk_mux_sel[] = {
+	{ .parent = &sys_clkin_ck, .rates = div_1_0_rates },
+	{ .parent = &sys_32k_ck, .rates = div_1_1_rates },
+	{ .parent = NULL },
+};
+
+/* Merged dmt1_clk_mux into timer1 */
+DEFINE_CLK_OMAP_MUX_GATE(timer1_fck, "l4_wkup_clkdm", dmt1_clk_mux_sel,
+			 OMAP4430_CM_WKUP_TIMER1_CLKCTRL, OMAP4430_CLKSEL_MASK,
+			 OMAP4430_CM_WKUP_TIMER1_CLKCTRL,
+			 OMAP4430_MODULEMODE_SWCTRL_SHIFT, NULL,
+			 abe_dpll_bypass_clk_mux_ck_parents, dmic_fck_ops);
+
+/* Merged cm2_dm10_mux into timer10 */
+DEFINE_CLK_OMAP_MUX_GATE(timer10_fck, "l4_per_clkdm", dmt1_clk_mux_sel,
+			 OMAP4430_CM_L4PER_DMTIMER10_CLKCTRL,
+			 OMAP4430_CLKSEL_MASK,
+			 OMAP4430_CM_L4PER_DMTIMER10_CLKCTRL,
+			 OMAP4430_MODULEMODE_SWCTRL_SHIFT, NULL,
+			 abe_dpll_bypass_clk_mux_ck_parents, dmic_fck_ops);
+
+/* Merged cm2_dm11_mux into timer11 */
+DEFINE_CLK_OMAP_MUX_GATE(timer11_fck, "l4_per_clkdm", dmt1_clk_mux_sel,
+			 OMAP4430_CM_L4PER_DMTIMER11_CLKCTRL,
+			 OMAP4430_CLKSEL_MASK,
+			 OMAP4430_CM_L4PER_DMTIMER11_CLKCTRL,
+			 OMAP4430_MODULEMODE_SWCTRL_SHIFT, NULL,
+			 abe_dpll_bypass_clk_mux_ck_parents, dmic_fck_ops);
+
+/* Merged cm2_dm2_mux into timer2 */
+DEFINE_CLK_OMAP_MUX_GATE(timer2_fck, "l4_per_clkdm", dmt1_clk_mux_sel,
+			 OMAP4430_CM_L4PER_DMTIMER2_CLKCTRL,
+			 OMAP4430_CLKSEL_MASK,
+			 OMAP4430_CM_L4PER_DMTIMER2_CLKCTRL,
+			 OMAP4430_MODULEMODE_SWCTRL_SHIFT, NULL,
+			 abe_dpll_bypass_clk_mux_ck_parents, dmic_fck_ops);
+
+/* Merged cm2_dm3_mux into timer3 */
+DEFINE_CLK_OMAP_MUX_GATE(timer3_fck, "l4_per_clkdm", dmt1_clk_mux_sel,
+			 OMAP4430_CM_L4PER_DMTIMER3_CLKCTRL,
+			 OMAP4430_CLKSEL_MASK,
+			 OMAP4430_CM_L4PER_DMTIMER3_CLKCTRL,
+			 OMAP4430_MODULEMODE_SWCTRL_SHIFT, NULL,
+			 abe_dpll_bypass_clk_mux_ck_parents, dmic_fck_ops);
+
+/* Merged cm2_dm4_mux into timer4 */
+DEFINE_CLK_OMAP_MUX_GATE(timer4_fck, "l4_per_clkdm", dmt1_clk_mux_sel,
+			 OMAP4430_CM_L4PER_DMTIMER4_CLKCTRL,
+			 OMAP4430_CLKSEL_MASK,
+			 OMAP4430_CM_L4PER_DMTIMER4_CLKCTRL,
+			 OMAP4430_MODULEMODE_SWCTRL_SHIFT, NULL,
+			 abe_dpll_bypass_clk_mux_ck_parents, dmic_fck_ops);
+
+static const struct clksel timer5_sync_mux_sel[] = {
+	{ .parent = &syc_clk_div_ck, .rates = div_1_0_rates },
+	{ .parent = &sys_32k_ck, .rates = div_1_1_rates },
+	{ .parent = NULL },
+};
+
+static const char *timer5_fck_parents[] = {
+	"syc_clk_div_ck", "sys_32k_ck",
+};
+
+/* Merged timer5_sync_mux into timer5 */
+DEFINE_CLK_OMAP_MUX_GATE(timer5_fck, "abe_clkdm", timer5_sync_mux_sel,
+			 OMAP4430_CM1_ABE_TIMER5_CLKCTRL, OMAP4430_CLKSEL_MASK,
+			 OMAP4430_CM1_ABE_TIMER5_CLKCTRL,
+			 OMAP4430_MODULEMODE_SWCTRL_SHIFT, NULL,
+			 timer5_fck_parents, dmic_fck_ops);
+
+/* Merged timer6_sync_mux into timer6 */
+DEFINE_CLK_OMAP_MUX_GATE(timer6_fck, "abe_clkdm", timer5_sync_mux_sel,
+			 OMAP4430_CM1_ABE_TIMER6_CLKCTRL, OMAP4430_CLKSEL_MASK,
+			 OMAP4430_CM1_ABE_TIMER6_CLKCTRL,
+			 OMAP4430_MODULEMODE_SWCTRL_SHIFT, NULL,
+			 timer5_fck_parents, dmic_fck_ops);
+
+/* Merged timer7_sync_mux into timer7 */
+DEFINE_CLK_OMAP_MUX_GATE(timer7_fck, "abe_clkdm", timer5_sync_mux_sel,
+			 OMAP4430_CM1_ABE_TIMER7_CLKCTRL, OMAP4430_CLKSEL_MASK,
+			 OMAP4430_CM1_ABE_TIMER7_CLKCTRL,
+			 OMAP4430_MODULEMODE_SWCTRL_SHIFT, NULL,
+			 timer5_fck_parents, dmic_fck_ops);
+
+/* Merged timer8_sync_mux into timer8 */
+DEFINE_CLK_OMAP_MUX_GATE(timer8_fck, "abe_clkdm", timer5_sync_mux_sel,
+			 OMAP4430_CM1_ABE_TIMER8_CLKCTRL, OMAP4430_CLKSEL_MASK,
+			 OMAP4430_CM1_ABE_TIMER8_CLKCTRL,
+			 OMAP4430_MODULEMODE_SWCTRL_SHIFT, NULL,
+			 timer5_fck_parents, dmic_fck_ops);
+
+/* Merged cm2_dm9_mux into timer9 */
+DEFINE_CLK_OMAP_MUX_GATE(timer9_fck, "l4_per_clkdm", dmt1_clk_mux_sel,
+			 OMAP4430_CM_L4PER_DMTIMER9_CLKCTRL,
+			 OMAP4430_CLKSEL_MASK,
+			 OMAP4430_CM_L4PER_DMTIMER9_CLKCTRL,
+			 OMAP4430_MODULEMODE_SWCTRL_SHIFT, NULL,
+			 abe_dpll_bypass_clk_mux_ck_parents, dmic_fck_ops);
+
+DEFINE_CLK_GATE(uart1_fck, "func_48m_fclk", &func_48m_fclk, 0x0,
+		OMAP4430_CM_L4PER_UART1_CLKCTRL,
+		OMAP4430_MODULEMODE_SWCTRL_SHIFT, 0x0, NULL);
+
+DEFINE_CLK_GATE(uart2_fck, "func_48m_fclk", &func_48m_fclk, 0x0,
+		OMAP4430_CM_L4PER_UART2_CLKCTRL,
+		OMAP4430_MODULEMODE_SWCTRL_SHIFT, 0x0, NULL);
+
+DEFINE_CLK_GATE(uart3_fck, "func_48m_fclk", &func_48m_fclk, 0x0,
+		OMAP4430_CM_L4PER_UART3_CLKCTRL,
+		OMAP4430_MODULEMODE_SWCTRL_SHIFT, 0x0, NULL);
+
+DEFINE_CLK_GATE(uart4_fck, "func_48m_fclk", &func_48m_fclk, 0x0,
+		OMAP4430_CM_L4PER_UART4_CLKCTRL,
+		OMAP4430_MODULEMODE_SWCTRL_SHIFT, 0x0, NULL);
+
+static struct clk usb_host_fs_fck;
+
+static const char *usb_host_fs_fck_parent_names[] = {
+	"func_48mc_fclk",
+};
+
+static const struct clk_ops usb_host_fs_fck_ops = {
+	.enable		= &omap2_dflt_clk_enable,
+	.disable	= &omap2_dflt_clk_disable,
+	.is_enabled	= &omap2_dflt_clk_is_enabled,
+};
+
+static struct clk_hw_omap usb_host_fs_fck_hw = {
+	.hw = {
+		.clk = &usb_host_fs_fck,
+	},
+	.enable_reg	= OMAP4430_CM_L3INIT_USB_HOST_FS_CLKCTRL,
+	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL_SHIFT,
+	.clkdm_name	= "l3_init_clkdm",
+};
+
+DEFINE_STRUCT_CLK(usb_host_fs_fck, usb_host_fs_fck_parent_names,
+		  usb_host_fs_fck_ops);
+
+static const char *utmi_p1_gfclk_parents[] = {
+	"init_60m_fclk", "xclk60mhsp1_ck",
+};
+
+DEFINE_CLK_MUX(utmi_p1_gfclk, utmi_p1_gfclk_parents, NULL, 0x0,
+	       OMAP4430_CM_L3INIT_USB_HOST_CLKCTRL,
+	       OMAP4430_CLKSEL_UTMI_P1_SHIFT, OMAP4430_CLKSEL_UTMI_P1_WIDTH,
+	       0x0, NULL);
+
+DEFINE_CLK_GATE(usb_host_hs_utmi_p1_clk, "utmi_p1_gfclk", &utmi_p1_gfclk, 0x0,
+		OMAP4430_CM_L3INIT_USB_HOST_CLKCTRL,
+		OMAP4430_OPTFCLKEN_UTMI_P1_CLK_SHIFT, 0x0, NULL);
+
+static const char *utmi_p2_gfclk_parents[] = {
+	"init_60m_fclk", "xclk60mhsp2_ck",
+};
+
+DEFINE_CLK_MUX(utmi_p2_gfclk, utmi_p2_gfclk_parents, NULL, 0x0,
+	       OMAP4430_CM_L3INIT_USB_HOST_CLKCTRL,
+	       OMAP4430_CLKSEL_UTMI_P2_SHIFT, OMAP4430_CLKSEL_UTMI_P2_WIDTH,
+	       0x0, NULL);
+
+DEFINE_CLK_GATE(usb_host_hs_utmi_p2_clk, "utmi_p2_gfclk", &utmi_p2_gfclk, 0x0,
+		OMAP4430_CM_L3INIT_USB_HOST_CLKCTRL,
+		OMAP4430_OPTFCLKEN_UTMI_P2_CLK_SHIFT, 0x0, NULL);
+
+DEFINE_CLK_GATE(usb_host_hs_utmi_p3_clk, "init_60m_fclk", &init_60m_fclk, 0x0,
+		OMAP4430_CM_L3INIT_USB_HOST_CLKCTRL,
+		OMAP4430_OPTFCLKEN_UTMI_P3_CLK_SHIFT, 0x0, NULL);
+
+DEFINE_CLK_GATE(usb_host_hs_hsic480m_p1_clk, "dpll_usb_m2_ck",
+		&dpll_usb_m2_ck, 0x0,
+		OMAP4430_CM_L3INIT_USB_HOST_CLKCTRL,
+		OMAP4430_OPTFCLKEN_HSIC480M_P1_CLK_SHIFT, 0x0, NULL);
+
+DEFINE_CLK_GATE(usb_host_hs_hsic60m_p1_clk, "init_60m_fclk",
+		&init_60m_fclk, 0x0,
+		OMAP4430_CM_L3INIT_USB_HOST_CLKCTRL,
+		OMAP4430_OPTFCLKEN_HSIC60M_P1_CLK_SHIFT, 0x0, NULL);
+
+DEFINE_CLK_GATE(usb_host_hs_hsic60m_p2_clk, "init_60m_fclk",
+		&init_60m_fclk, 0x0,
+		OMAP4430_CM_L3INIT_USB_HOST_CLKCTRL,
+		OMAP4430_OPTFCLKEN_HSIC60M_P2_CLK_SHIFT, 0x0, NULL);
+
+DEFINE_CLK_GATE(usb_host_hs_hsic480m_p2_clk, "dpll_usb_m2_ck",
+		&dpll_usb_m2_ck, 0x0,
+		OMAP4430_CM_L3INIT_USB_HOST_CLKCTRL,
+		OMAP4430_OPTFCLKEN_HSIC480M_P2_CLK_SHIFT, 0x0, NULL);
+
+DEFINE_CLK_GATE(usb_host_hs_func48mclk, "func_48mc_fclk", &func_48mc_fclk, 0x0,
+		OMAP4430_CM_L3INIT_USB_HOST_CLKCTRL,
+		OMAP4430_OPTFCLKEN_FUNC48MCLK_SHIFT, 0x0, NULL);
+
+DEFINE_CLK_GATE(usb_host_hs_fck, "init_60m_fclk", &init_60m_fclk, 0x0,
+		OMAP4430_CM_L3INIT_USB_HOST_CLKCTRL,
+		OMAP4430_MODULEMODE_SWCTRL_SHIFT, 0x0, NULL);
+
+static const char *otg_60m_gfclk_parents[] = {
+	"utmi_phy_clkout_ck", "xclk60motg_ck",
+};
+
+DEFINE_CLK_MUX(otg_60m_gfclk, otg_60m_gfclk_parents, NULL, 0x0,
+	       OMAP4430_CM_L3INIT_USB_OTG_CLKCTRL, OMAP4430_CLKSEL_60M_SHIFT,
+	       OMAP4430_CLKSEL_60M_WIDTH, 0x0, NULL);
+
+DEFINE_CLK_GATE(usb_otg_hs_xclk, "otg_60m_gfclk", &otg_60m_gfclk, 0x0,
+		OMAP4430_CM_L3INIT_USB_OTG_CLKCTRL,
+		OMAP4430_OPTFCLKEN_XCLK_SHIFT, 0x0, NULL);
+
+DEFINE_CLK_GATE(usb_otg_hs_ick, "l3_div_ck", &l3_div_ck, 0x0,
+		OMAP4430_CM_L3INIT_USB_OTG_CLKCTRL,
+		OMAP4430_MODULEMODE_HWCTRL_SHIFT, 0x0, NULL);
+
+DEFINE_CLK_GATE(usb_phy_cm_clk32k, "sys_32k_ck", &sys_32k_ck, 0x0,
+		OMAP4430_CM_ALWON_USBPHY_CLKCTRL,
+		OMAP4430_OPTFCLKEN_CLK32K_SHIFT, 0x0, NULL);
+
+DEFINE_CLK_GATE(usb_tll_hs_usb_ch2_clk, "init_60m_fclk", &init_60m_fclk, 0x0,
+		OMAP4430_CM_L3INIT_USB_TLL_CLKCTRL,
+		OMAP4430_OPTFCLKEN_USB_CH2_CLK_SHIFT, 0x0, NULL);
+
+DEFINE_CLK_GATE(usb_tll_hs_usb_ch0_clk, "init_60m_fclk", &init_60m_fclk, 0x0,
+		OMAP4430_CM_L3INIT_USB_TLL_CLKCTRL,
+		OMAP4430_OPTFCLKEN_USB_CH0_CLK_SHIFT, 0x0, NULL);
+
+DEFINE_CLK_GATE(usb_tll_hs_usb_ch1_clk, "init_60m_fclk", &init_60m_fclk, 0x0,
+		OMAP4430_CM_L3INIT_USB_TLL_CLKCTRL,
+		OMAP4430_OPTFCLKEN_USB_CH1_CLK_SHIFT, 0x0, NULL);
+
+DEFINE_CLK_GATE(usb_tll_hs_ick, "l4_div_ck", &l4_div_ck, 0x0,
+		OMAP4430_CM_L3INIT_USB_TLL_CLKCTRL,
+		OMAP4430_MODULEMODE_HWCTRL_SHIFT, 0x0, NULL);
+
+static const struct clk_div_table usim_ck_rates[] = {
+	{ .div = 14, .val = 0 },
+	{ .div = 18, .val = 1 },
+	{ .div = 0 },
+};
+DEFINE_CLK_DIVIDER_TABLE(usim_ck, "dpll_per_m4x2_ck", &dpll_per_m4x2_ck, 0x0,
+			 OMAP4430_CM_WKUP_USIM_CLKCTRL,
+			 OMAP4430_CLKSEL_DIV_SHIFT, OMAP4430_CLKSEL_DIV_WIDTH,
+			 0x0, usim_ck_rates, NULL);
+
+DEFINE_CLK_GATE(usim_fclk, "usim_ck", &usim_ck, 0x0,
+		OMAP4430_CM_WKUP_USIM_CLKCTRL, OMAP4430_OPTFCLKEN_FCLK_SHIFT,
+		0x0, NULL);
+
+DEFINE_CLK_GATE(usim_fck, "sys_32k_ck", &sys_32k_ck, 0x0,
+		OMAP4430_CM_WKUP_USIM_CLKCTRL, OMAP4430_MODULEMODE_HWCTRL_SHIFT,
+		0x0, NULL);
+
+DEFINE_CLK_GATE(wd_timer2_fck, "sys_32k_ck", &sys_32k_ck, 0x0,
+		OMAP4430_CM_WKUP_WDT2_CLKCTRL, OMAP4430_MODULEMODE_SWCTRL_SHIFT,
+		0x0, NULL);
+
+DEFINE_CLK_GATE(wd_timer3_fck, "sys_32k_ck", &sys_32k_ck, 0x0,
+		OMAP4430_CM1_ABE_WDT3_CLKCTRL, OMAP4430_MODULEMODE_SWCTRL_SHIFT,
+		0x0, NULL);
+
+/* Remaining optional clocks */
+static const char *pmd_stm_clock_mux_ck_parents[] = {
+	"sys_clkin_ck", "dpll_core_m6x2_ck", "tie_low_clock_ck",
+};
+
+DEFINE_CLK_MUX(pmd_stm_clock_mux_ck, pmd_stm_clock_mux_ck_parents, NULL, 0x0,
+	       OMAP4430_CM_EMU_DEBUGSS_CLKCTRL, OMAP4430_PMD_STM_MUX_CTRL_SHIFT,
+	       OMAP4430_PMD_STM_MUX_CTRL_WIDTH, 0x0, NULL);
+
+DEFINE_CLK_MUX(pmd_trace_clk_mux_ck, pmd_stm_clock_mux_ck_parents, NULL, 0x0,
+	       OMAP4430_CM_EMU_DEBUGSS_CLKCTRL,
+	       OMAP4430_PMD_TRACE_MUX_CTRL_SHIFT,
+	       OMAP4430_PMD_TRACE_MUX_CTRL_WIDTH, 0x0, NULL);
+
+DEFINE_CLK_DIVIDER(stm_clk_div_ck, "pmd_stm_clock_mux_ck",
+		   &pmd_stm_clock_mux_ck, 0x0, OMAP4430_CM_EMU_DEBUGSS_CLKCTRL,
+		   OMAP4430_CLKSEL_PMD_STM_CLK_SHIFT,
+		   OMAP4430_CLKSEL_PMD_STM_CLK_WIDTH, CLK_DIVIDER_POWER_OF_TWO,
+		   NULL);
+
+static const char *trace_clk_div_ck_parents[] = {
+	"pmd_trace_clk_mux_ck",
+};
+
+static const struct clksel trace_clk_div_div[] = {
+	{ .parent = &pmd_trace_clk_mux_ck, .rates = div3_1to4_rates },
+	{ .parent = NULL },
+};
+
+static struct clk trace_clk_div_ck;
+
+static const struct clk_ops trace_clk_div_ck_ops = {
+	.recalc_rate	= &omap2_clksel_recalc,
+	.set_rate	= &omap2_clksel_set_rate,
+	.round_rate	= &omap2_clksel_round_rate,
+	.init		= &omap2_init_clk_clkdm,
+	.enable		= &omap2_clkops_enable_clkdm,
+	.disable	= &omap2_clkops_disable_clkdm,
+};
+
+static struct clk_hw_omap trace_clk_div_ck_hw = {
+	.hw = {
+		.clk = &trace_clk_div_ck,
+	},
+	.clkdm_name	= "emu_sys_clkdm",
+	.clksel		= trace_clk_div_div,
+	.clksel_reg	= OMAP4430_CM_EMU_DEBUGSS_CLKCTRL,
+	.clksel_mask	= OMAP4430_CLKSEL_PMD_TRACE_CLK_MASK,
+};
+
+DEFINE_STRUCT_CLK(trace_clk_div_ck, trace_clk_div_ck_parents,
+		  trace_clk_div_ck_ops);
+
+/* SCRM aux clk nodes */
+
+static const struct clksel auxclk_src_sel[] = {
+	{ .parent = &sys_clkin_ck, .rates = div_1_0_rates },
+	{ .parent = &dpll_core_m3x2_ck, .rates = div_1_1_rates },
+	{ .parent = &dpll_per_m3x2_ck, .rates = div_1_2_rates },
+	{ .parent = NULL },
+};
+
+static const char *auxclk_src_ck_parents[] = {
+	"sys_clkin_ck", "dpll_core_m3x2_ck", "dpll_per_m3x2_ck",
+};
+
+static const struct clk_ops auxclk_src_ck_ops = {
+	.enable		= &omap2_dflt_clk_enable,
+	.disable	= &omap2_dflt_clk_disable,
+	.is_enabled	= &omap2_dflt_clk_is_enabled,
+	.recalc_rate	= &omap2_clksel_recalc,
+	.get_parent	= &omap2_clksel_find_parent_index,
+};
+
+DEFINE_CLK_OMAP_MUX_GATE(auxclk0_src_ck, NULL, auxclk_src_sel,
+			 OMAP4_SCRM_AUXCLK0, OMAP4_SRCSELECT_MASK,
+			 OMAP4_SCRM_AUXCLK0, OMAP4_ENABLE_SHIFT, NULL,
+			 auxclk_src_ck_parents, auxclk_src_ck_ops);
+
+DEFINE_CLK_DIVIDER(auxclk0_ck, "auxclk0_src_ck", &auxclk0_src_ck, 0x0,
+		   OMAP4_SCRM_AUXCLK0, OMAP4_CLKDIV_SHIFT, OMAP4_CLKDIV_WIDTH,
+		   0x0, NULL);
+
+DEFINE_CLK_OMAP_MUX_GATE(auxclk1_src_ck, NULL, auxclk_src_sel,
+			 OMAP4_SCRM_AUXCLK1, OMAP4_SRCSELECT_MASK,
+			 OMAP4_SCRM_AUXCLK1, OMAP4_ENABLE_SHIFT, NULL,
+			 auxclk_src_ck_parents, auxclk_src_ck_ops);
+
+DEFINE_CLK_DIVIDER(auxclk1_ck, "auxclk1_src_ck", &auxclk1_src_ck, 0x0,
+		   OMAP4_SCRM_AUXCLK1, OMAP4_CLKDIV_SHIFT, OMAP4_CLKDIV_WIDTH,
+		   0x0, NULL);
+
+DEFINE_CLK_OMAP_MUX_GATE(auxclk2_src_ck, NULL, auxclk_src_sel,
+			 OMAP4_SCRM_AUXCLK2, OMAP4_SRCSELECT_MASK,
+			 OMAP4_SCRM_AUXCLK2, OMAP4_ENABLE_SHIFT, NULL,
+			 auxclk_src_ck_parents, auxclk_src_ck_ops);
+
+DEFINE_CLK_DIVIDER(auxclk2_ck, "auxclk2_src_ck", &auxclk2_src_ck, 0x0,
+		   OMAP4_SCRM_AUXCLK2, OMAP4_CLKDIV_SHIFT, OMAP4_CLKDIV_WIDTH,
+		   0x0, NULL);
+
+DEFINE_CLK_OMAP_MUX_GATE(auxclk3_src_ck, NULL, auxclk_src_sel,
+			 OMAP4_SCRM_AUXCLK3, OMAP4_SRCSELECT_MASK,
+			 OMAP4_SCRM_AUXCLK3, OMAP4_ENABLE_SHIFT, NULL,
+			 auxclk_src_ck_parents, auxclk_src_ck_ops);
+
+DEFINE_CLK_DIVIDER(auxclk3_ck, "auxclk3_src_ck", &auxclk3_src_ck, 0x0,
+		   OMAP4_SCRM_AUXCLK3, OMAP4_CLKDIV_SHIFT, OMAP4_CLKDIV_WIDTH,
+		   0x0, NULL);
+
+DEFINE_CLK_OMAP_MUX_GATE(auxclk4_src_ck, NULL, auxclk_src_sel,
+			 OMAP4_SCRM_AUXCLK4, OMAP4_SRCSELECT_MASK,
+			 OMAP4_SCRM_AUXCLK4, OMAP4_ENABLE_SHIFT, NULL,
+			 auxclk_src_ck_parents, auxclk_src_ck_ops);
+
+DEFINE_CLK_DIVIDER(auxclk4_ck, "auxclk4_src_ck", &auxclk4_src_ck, 0x0,
+		   OMAP4_SCRM_AUXCLK4, OMAP4_CLKDIV_SHIFT, OMAP4_CLKDIV_WIDTH,
+		   0x0, NULL);
+
+DEFINE_CLK_OMAP_MUX_GATE(auxclk5_src_ck, NULL, auxclk_src_sel,
+			 OMAP4_SCRM_AUXCLK5, OMAP4_SRCSELECT_MASK,
+			 OMAP4_SCRM_AUXCLK5, OMAP4_ENABLE_SHIFT, NULL,
+			 auxclk_src_ck_parents, auxclk_src_ck_ops);
+
+DEFINE_CLK_DIVIDER(auxclk5_ck, "auxclk5_src_ck", &auxclk5_src_ck, 0x0,
+		   OMAP4_SCRM_AUXCLK5, OMAP4_CLKDIV_SHIFT, OMAP4_CLKDIV_WIDTH,
+		   0x0, NULL);
+
+static const char *auxclkreq_ck_parents[] = {
+	"auxclk0_ck", "auxclk1_ck", "auxclk2_ck", "auxclk3_ck", "auxclk4_ck",
+	"auxclk5_ck",
+};
+
+DEFINE_CLK_MUX(auxclkreq0_ck, auxclkreq_ck_parents, NULL, 0x0,
+	       OMAP4_SCRM_AUXCLKREQ0, OMAP4_MAPPING_SHIFT, OMAP4_MAPPING_WIDTH,
+	       0x0, NULL);
+
+DEFINE_CLK_MUX(auxclkreq1_ck, auxclkreq_ck_parents, NULL, 0x0,
+	       OMAP4_SCRM_AUXCLKREQ1, OMAP4_MAPPING_SHIFT, OMAP4_MAPPING_WIDTH,
+	       0x0, NULL);
+
+DEFINE_CLK_MUX(auxclkreq2_ck, auxclkreq_ck_parents, NULL, 0x0,
+	       OMAP4_SCRM_AUXCLKREQ2, OMAP4_MAPPING_SHIFT, OMAP4_MAPPING_WIDTH,
+	       0x0, NULL);
+
+DEFINE_CLK_MUX(auxclkreq3_ck, auxclkreq_ck_parents, NULL, 0x0,
+	       OMAP4_SCRM_AUXCLKREQ3, OMAP4_MAPPING_SHIFT, OMAP4_MAPPING_WIDTH,
+	       0x0, NULL);
+
+DEFINE_CLK_MUX(auxclkreq4_ck, auxclkreq_ck_parents, NULL, 0x0,
+	       OMAP4_SCRM_AUXCLKREQ4, OMAP4_MAPPING_SHIFT, OMAP4_MAPPING_WIDTH,
+	       0x0, NULL);
+
+DEFINE_CLK_MUX(auxclkreq5_ck, auxclkreq_ck_parents, NULL, 0x0,
+	       OMAP4_SCRM_AUXCLKREQ5, OMAP4_MAPPING_SHIFT, OMAP4_MAPPING_WIDTH,
+	       0x0, NULL);
+
+/*
+ * clkdev
+ */
+
+static struct omap_clk omap44xx_clks[] = {
+	CLK(NULL,	"extalt_clkin_ck",		&extalt_clkin_ck,	CK_443X),
+	CLK(NULL,	"pad_clks_src_ck",		&pad_clks_src_ck,	CK_443X),
+	CLK(NULL,	"pad_clks_ck",			&pad_clks_ck,	CK_443X),
+	CLK(NULL,	"pad_slimbus_core_clks_ck",	&pad_slimbus_core_clks_ck,	CK_443X),
+	CLK(NULL,	"secure_32k_clk_src_ck",	&secure_32k_clk_src_ck,	CK_443X),
+	CLK(NULL,	"slimbus_src_clk",		&slimbus_src_clk,	CK_443X),
+	CLK(NULL,	"slimbus_clk",			&slimbus_clk,	CK_443X),
+	CLK(NULL,	"sys_32k_ck",			&sys_32k_ck,	CK_443X),
+	CLK(NULL,	"virt_12000000_ck",		&virt_12000000_ck,	CK_443X),
+	CLK(NULL,	"virt_13000000_ck",		&virt_13000000_ck,	CK_443X),
+	CLK(NULL,	"virt_16800000_ck",		&virt_16800000_ck,	CK_443X),
+	CLK(NULL,	"virt_19200000_ck",		&virt_19200000_ck,	CK_443X),
+	CLK(NULL,	"virt_26000000_ck",		&virt_26000000_ck,	CK_443X),
+	CLK(NULL,	"virt_27000000_ck",		&virt_27000000_ck,	CK_443X),
+	CLK(NULL,	"virt_38400000_ck",		&virt_38400000_ck,	CK_443X),
+	CLK(NULL,	"sys_clkin_ck",			&sys_clkin_ck,	CK_443X),
+	CLK(NULL,	"tie_low_clock_ck",		&tie_low_clock_ck,	CK_443X),
+	CLK(NULL,	"utmi_phy_clkout_ck",		&utmi_phy_clkout_ck,	CK_443X),
+	CLK(NULL,	"xclk60mhsp1_ck",		&xclk60mhsp1_ck,	CK_443X),
+	CLK(NULL,	"xclk60mhsp2_ck",		&xclk60mhsp2_ck,	CK_443X),
+	CLK(NULL,	"xclk60motg_ck",		&xclk60motg_ck,	CK_443X),
+	CLK(NULL,	"abe_dpll_bypass_clk_mux_ck",	&abe_dpll_bypass_clk_mux_ck,	CK_443X),
+	CLK(NULL,	"abe_dpll_refclk_mux_ck",	&abe_dpll_refclk_mux_ck,	CK_443X),
+	CLK(NULL,	"dpll_abe_ck",			&dpll_abe_ck,	CK_443X),
+	CLK(NULL,	"dpll_abe_x2_ck",		&dpll_abe_x2_ck,	CK_443X),
+	CLK(NULL,	"dpll_abe_m2x2_ck",		&dpll_abe_m2x2_ck,	CK_443X),
+	CLK(NULL,	"abe_24m_fclk",			&abe_24m_fclk,	CK_443X),
+	CLK(NULL,	"abe_clk",			&abe_clk,	CK_443X),
+	CLK(NULL,	"aess_fclk",			&aess_fclk,	CK_443X),
+	CLK(NULL,	"dpll_abe_m3x2_ck",		&dpll_abe_m3x2_ck,	CK_443X),
+	CLK(NULL,	"core_hsd_byp_clk_mux_ck",	&core_hsd_byp_clk_mux_ck,	CK_443X),
+	CLK(NULL,	"dpll_core_ck",			&dpll_core_ck,	CK_443X),
+	CLK(NULL,	"dpll_core_x2_ck",		&dpll_core_x2_ck,	CK_443X),
+	CLK(NULL,	"dpll_core_m6x2_ck",		&dpll_core_m6x2_ck,	CK_443X),
+	CLK(NULL,	"dbgclk_mux_ck",		&dbgclk_mux_ck,	CK_443X),
+	CLK(NULL,	"dpll_core_m2_ck",		&dpll_core_m2_ck,	CK_443X),
+	CLK(NULL,	"ddrphy_ck",			&ddrphy_ck,	CK_443X),
+	CLK(NULL,	"dpll_core_m5x2_ck",		&dpll_core_m5x2_ck,	CK_443X),
+	CLK(NULL,	"div_core_ck",			&div_core_ck,	CK_443X),
+	CLK(NULL,	"div_iva_hs_clk",		&div_iva_hs_clk,	CK_443X),
+	CLK(NULL,	"div_mpu_hs_clk",		&div_mpu_hs_clk,	CK_443X),
+	CLK(NULL,	"dpll_core_m4x2_ck",		&dpll_core_m4x2_ck,	CK_443X),
+	CLK(NULL,	"dll_clk_div_ck",		&dll_clk_div_ck,	CK_443X),
+	CLK(NULL,	"dpll_abe_m2_ck",		&dpll_abe_m2_ck,	CK_443X),
+	CLK(NULL,	"dpll_core_m3x2_ck",		&dpll_core_m3x2_ck,	CK_443X),
+	CLK(NULL,	"dpll_core_m7x2_ck",		&dpll_core_m7x2_ck,	CK_443X),
+	CLK(NULL,	"iva_hsd_byp_clk_mux_ck",	&iva_hsd_byp_clk_mux_ck,	CK_443X),
+	CLK(NULL,	"dpll_iva_ck",			&dpll_iva_ck,	CK_443X),
+	CLK(NULL,	"dpll_iva_x2_ck",		&dpll_iva_x2_ck,	CK_443X),
+	CLK(NULL,	"dpll_iva_m4x2_ck",		&dpll_iva_m4x2_ck,	CK_443X),
+	CLK(NULL,	"dpll_iva_m5x2_ck",		&dpll_iva_m5x2_ck,	CK_443X),
+	CLK(NULL,	"dpll_mpu_ck",			&dpll_mpu_ck,	CK_443X),
+	CLK(NULL,	"dpll_mpu_m2_ck",		&dpll_mpu_m2_ck,	CK_443X),
+	CLK(NULL,	"per_hs_clk_div_ck",		&per_hs_clk_div_ck,	CK_443X),
+	CLK(NULL,	"per_hsd_byp_clk_mux_ck",	&per_hsd_byp_clk_mux_ck,	CK_443X),
+	CLK(NULL,	"dpll_per_ck",			&dpll_per_ck,	CK_443X),
+	CLK(NULL,	"dpll_per_m2_ck",		&dpll_per_m2_ck,	CK_443X),
+	CLK(NULL,	"dpll_per_x2_ck",		&dpll_per_x2_ck,	CK_443X),
+	CLK(NULL,	"dpll_per_m2x2_ck",		&dpll_per_m2x2_ck,	CK_443X),
+	CLK(NULL,	"dpll_per_m3x2_ck",		&dpll_per_m3x2_ck,	CK_443X),
+	CLK(NULL,	"dpll_per_m4x2_ck",		&dpll_per_m4x2_ck,	CK_443X),
+	CLK(NULL,	"dpll_per_m5x2_ck",		&dpll_per_m5x2_ck,	CK_443X),
+	CLK(NULL,	"dpll_per_m6x2_ck",		&dpll_per_m6x2_ck,	CK_443X),
+	CLK(NULL,	"dpll_per_m7x2_ck",		&dpll_per_m7x2_ck,	CK_443X),
+	CLK(NULL,	"usb_hs_clk_div_ck",		&usb_hs_clk_div_ck,	CK_443X),
+	CLK(NULL,	"dpll_usb_ck",			&dpll_usb_ck,	CK_443X),
+	CLK(NULL,	"dpll_usb_clkdcoldo_ck",	&dpll_usb_clkdcoldo_ck,	CK_443X),
+	CLK(NULL,	"dpll_usb_m2_ck",		&dpll_usb_m2_ck,	CK_443X),
+	CLK(NULL,	"ducati_clk_mux_ck",		&ducati_clk_mux_ck,	CK_443X),
+	CLK(NULL,	"func_12m_fclk",		&func_12m_fclk,	CK_443X),
+	CLK(NULL,	"func_24m_clk",			&func_24m_clk,	CK_443X),
+	CLK(NULL,	"func_24mc_fclk",		&func_24mc_fclk,	CK_443X),
+	CLK(NULL,	"func_48m_fclk",		&func_48m_fclk,	CK_443X),
+	CLK(NULL,	"func_48mc_fclk",		&func_48mc_fclk,	CK_443X),
+	CLK(NULL,	"func_64m_fclk",		&func_64m_fclk,	CK_443X),
+	CLK(NULL,	"func_96m_fclk",		&func_96m_fclk,	CK_443X),
+	CLK(NULL,	"init_60m_fclk",		&init_60m_fclk,	CK_443X),
+	CLK(NULL,	"l3_div_ck",			&l3_div_ck,	CK_443X),
+	CLK(NULL,	"l4_div_ck",			&l4_div_ck,	CK_443X),
+	CLK(NULL,	"lp_clk_div_ck",		&lp_clk_div_ck,	CK_443X),
+	CLK(NULL,	"l4_wkup_clk_mux_ck",		&l4_wkup_clk_mux_ck,	CK_443X),
+	CLK("smp_twd",	NULL,				&mpu_periphclk,	CK_443X),
+	CLK(NULL,	"ocp_abe_iclk",			&ocp_abe_iclk,	CK_443X),
+	CLK(NULL,	"per_abe_24m_fclk",		&per_abe_24m_fclk,	CK_443X),
+	CLK(NULL,	"per_abe_nc_fclk",		&per_abe_nc_fclk,	CK_443X),
+	CLK(NULL,	"syc_clk_div_ck",		&syc_clk_div_ck,	CK_443X),
+	CLK(NULL,	"aes1_fck",			&aes1_fck,	CK_443X),
+	CLK(NULL,	"aes2_fck",			&aes2_fck,	CK_443X),
+	CLK(NULL,	"aess_fck",			&aess_fck,	CK_443X),
+	CLK(NULL,	"bandgap_fclk",			&bandgap_fclk,	CK_443X),
+	CLK(NULL,	"div_ts_ck",			&div_ts_ck,	CK_446X),
+	CLK(NULL,	"bandgap_ts_fclk",		&bandgap_ts_fclk,	CK_446X),
+	CLK(NULL,	"des3des_fck",			&des3des_fck,	CK_443X),
+	CLK(NULL,	"dmic_sync_mux_ck",		&dmic_sync_mux_ck,	CK_443X),
+	CLK(NULL,	"dmic_fck",			&dmic_fck,	CK_443X),
+	CLK(NULL,	"dsp_fck",			&dsp_fck,	CK_443X),
+	CLK(NULL,	"dss_sys_clk",			&dss_sys_clk,	CK_443X),
+	CLK(NULL,	"dss_tv_clk",			&dss_tv_clk,	CK_443X),
+	CLK(NULL,	"dss_dss_clk",			&dss_dss_clk,	CK_443X),
+	CLK(NULL,	"dss_48mhz_clk",		&dss_48mhz_clk,	CK_443X),
+	CLK(NULL,	"dss_fck",			&dss_fck,	CK_443X),
+	CLK("omapdss_dss",	"ick",			&dss_fck,	CK_443X),
+	CLK(NULL,	"efuse_ctrl_cust_fck",		&efuse_ctrl_cust_fck,	CK_443X),
+	CLK(NULL,	"emif1_fck",			&emif1_fck,	CK_443X),
+	CLK(NULL,	"emif2_fck",			&emif2_fck,	CK_443X),
+	CLK(NULL,	"fdif_fck",			&fdif_fck,	CK_443X),
+	CLK(NULL,	"fpka_fck",			&fpka_fck,	CK_443X),
+	CLK(NULL,	"gpio1_dbclk",			&gpio1_dbclk,	CK_443X),
+	CLK(NULL,	"gpio1_ick",			&gpio1_ick,	CK_443X),
+	CLK(NULL,	"gpio2_dbclk",			&gpio2_dbclk,	CK_443X),
+	CLK(NULL,	"gpio2_ick",			&gpio2_ick,	CK_443X),
+	CLK(NULL,	"gpio3_dbclk",			&gpio3_dbclk,	CK_443X),
+	CLK(NULL,	"gpio3_ick",			&gpio3_ick,	CK_443X),
+	CLK(NULL,	"gpio4_dbclk",			&gpio4_dbclk,	CK_443X),
+	CLK(NULL,	"gpio4_ick",			&gpio4_ick,	CK_443X),
+	CLK(NULL,	"gpio5_dbclk",			&gpio5_dbclk,	CK_443X),
+	CLK(NULL,	"gpio5_ick",			&gpio5_ick,	CK_443X),
+	CLK(NULL,	"gpio6_dbclk",			&gpio6_dbclk,	CK_443X),
+	CLK(NULL,	"gpio6_ick",			&gpio6_ick,	CK_443X),
+	CLK(NULL,	"gpmc_ick",			&gpmc_ick,	CK_443X),
+	CLK(NULL,	"gpu_fck",			&gpu_fck,	CK_443X),
+	CLK(NULL,	"hdq1w_fck",			&hdq1w_fck,	CK_443X),
+	CLK(NULL,	"hsi_fck",			&hsi_fck,	CK_443X),
+	CLK(NULL,	"i2c1_fck",			&i2c1_fck,	CK_443X),
+	CLK(NULL,	"i2c2_fck",			&i2c2_fck,	CK_443X),
+	CLK(NULL,	"i2c3_fck",			&i2c3_fck,	CK_443X),
+	CLK(NULL,	"i2c4_fck",			&i2c4_fck,	CK_443X),
+	CLK(NULL,	"ipu_fck",			&ipu_fck,	CK_443X),
+	CLK(NULL,	"iss_ctrlclk",			&iss_ctrlclk,	CK_443X),
+	CLK(NULL,	"iss_fck",			&iss_fck,	CK_443X),
+	CLK(NULL,	"iva_fck",			&iva_fck,	CK_443X),
+	CLK(NULL,	"kbd_fck",			&kbd_fck,	CK_443X),
+	CLK(NULL,	"l3_instr_ick",			&l3_instr_ick,	CK_443X),
+	CLK(NULL,	"l3_main_3_ick",		&l3_main_3_ick,	CK_443X),
+	CLK(NULL,	"mcasp_sync_mux_ck",		&mcasp_sync_mux_ck,	CK_443X),
+	CLK(NULL,	"mcasp_fck",			&mcasp_fck,	CK_443X),
+	CLK(NULL,	"mcbsp1_sync_mux_ck",		&mcbsp1_sync_mux_ck,	CK_443X),
+	CLK(NULL,	"mcbsp1_fck",			&mcbsp1_fck,	CK_443X),
+	CLK(NULL,	"mcbsp2_sync_mux_ck",		&mcbsp2_sync_mux_ck,	CK_443X),
+	CLK(NULL,	"mcbsp2_fck",			&mcbsp2_fck,	CK_443X),
+	CLK(NULL,	"mcbsp3_sync_mux_ck",		&mcbsp3_sync_mux_ck,	CK_443X),
+	CLK(NULL,	"mcbsp3_fck",			&mcbsp3_fck,	CK_443X),
+	CLK(NULL,	"mcbsp4_sync_mux_ck",		&mcbsp4_sync_mux_ck,	CK_443X),
+	CLK(NULL,	"mcbsp4_fck",			&mcbsp4_fck,	CK_443X),
+	CLK(NULL,	"mcpdm_fck",			&mcpdm_fck,	CK_443X),
+	CLK(NULL,	"mcspi1_fck",			&mcspi1_fck,	CK_443X),
+	CLK(NULL,	"mcspi2_fck",			&mcspi2_fck,	CK_443X),
+	CLK(NULL,	"mcspi3_fck",			&mcspi3_fck,	CK_443X),
+	CLK(NULL,	"mcspi4_fck",			&mcspi4_fck,	CK_443X),
+	CLK(NULL,	"mmc1_fck",			&mmc1_fck,	CK_443X),
+	CLK(NULL,	"mmc2_fck",			&mmc2_fck,	CK_443X),
+	CLK(NULL,	"mmc3_fck",			&mmc3_fck,	CK_443X),
+	CLK(NULL,	"mmc4_fck",			&mmc4_fck,	CK_443X),
+	CLK(NULL,	"mmc5_fck",			&mmc5_fck,	CK_443X),
+	CLK(NULL,	"ocp2scp_usb_phy_phy_48m",	&ocp2scp_usb_phy_phy_48m,	CK_443X),
+	CLK(NULL,	"ocp2scp_usb_phy_ick",		&ocp2scp_usb_phy_ick,	CK_443X),
+	CLK(NULL,	"ocp_wp_noc_ick",		&ocp_wp_noc_ick,	CK_443X),
+	CLK(NULL,	"rng_ick",			&rng_ick,	CK_443X),
+	CLK("omap_rng",	"ick",				&rng_ick,	CK_443X),
+	CLK(NULL,	"sha2md5_fck",			&sha2md5_fck,	CK_443X),
+	CLK(NULL,	"sl2if_ick",			&sl2if_ick,	CK_443X),
+	CLK(NULL,	"slimbus1_fclk_1",		&slimbus1_fclk_1,	CK_443X),
+	CLK(NULL,	"slimbus1_fclk_0",		&slimbus1_fclk_0,	CK_443X),
+	CLK(NULL,	"slimbus1_fclk_2",		&slimbus1_fclk_2,	CK_443X),
+	CLK(NULL,	"slimbus1_slimbus_clk",		&slimbus1_slimbus_clk,	CK_443X),
+	CLK(NULL,	"slimbus1_fck",			&slimbus1_fck,	CK_443X),
+	CLK(NULL,	"slimbus2_fclk_1",		&slimbus2_fclk_1,	CK_443X),
+	CLK(NULL,	"slimbus2_fclk_0",		&slimbus2_fclk_0,	CK_443X),
+	CLK(NULL,	"slimbus2_slimbus_clk",		&slimbus2_slimbus_clk,	CK_443X),
+	CLK(NULL,	"slimbus2_fck",			&slimbus2_fck,	CK_443X),
+	CLK(NULL,	"smartreflex_core_fck",		&smartreflex_core_fck,	CK_443X),
+	CLK(NULL,	"smartreflex_iva_fck",		&smartreflex_iva_fck,	CK_443X),
+	CLK(NULL,	"smartreflex_mpu_fck",		&smartreflex_mpu_fck,	CK_443X),
+	CLK(NULL,	"timer1_fck",			&timer1_fck,	CK_443X),
+	CLK(NULL,	"timer10_fck",			&timer10_fck,	CK_443X),
+	CLK(NULL,	"timer11_fck",			&timer11_fck,	CK_443X),
+	CLK(NULL,	"timer2_fck",			&timer2_fck,	CK_443X),
+	CLK(NULL,	"timer3_fck",			&timer3_fck,	CK_443X),
+	CLK(NULL,	"timer4_fck",			&timer4_fck,	CK_443X),
+	CLK(NULL,	"timer5_fck",			&timer5_fck,	CK_443X),
+	CLK(NULL,	"timer6_fck",			&timer6_fck,	CK_443X),
+	CLK(NULL,	"timer7_fck",			&timer7_fck,	CK_443X),
+	CLK(NULL,	"timer8_fck",			&timer8_fck,	CK_443X),
+	CLK(NULL,	"timer9_fck",			&timer9_fck,	CK_443X),
+	CLK(NULL,	"uart1_fck",			&uart1_fck,	CK_443X),
+	CLK(NULL,	"uart2_fck",			&uart2_fck,	CK_443X),
+	CLK(NULL,	"uart3_fck",			&uart3_fck,	CK_443X),
+	CLK(NULL,	"uart4_fck",			&uart4_fck,	CK_443X),
+	CLK(NULL,	"usb_host_fs_fck",		&usb_host_fs_fck,	CK_443X),
+	CLK("usbhs_omap",	"fs_fck",		&usb_host_fs_fck,	CK_443X),
+	CLK(NULL,	"utmi_p1_gfclk",		&utmi_p1_gfclk,	CK_443X),
+	CLK(NULL,	"usb_host_hs_utmi_p1_clk",	&usb_host_hs_utmi_p1_clk,	CK_443X),
+	CLK(NULL,	"utmi_p2_gfclk",		&utmi_p2_gfclk,	CK_443X),
+	CLK(NULL,	"usb_host_hs_utmi_p2_clk",	&usb_host_hs_utmi_p2_clk,	CK_443X),
+	CLK(NULL,	"usb_host_hs_utmi_p3_clk",	&usb_host_hs_utmi_p3_clk,	CK_443X),
+	CLK(NULL,	"usb_host_hs_hsic480m_p1_clk",	&usb_host_hs_hsic480m_p1_clk,	CK_443X),
+	CLK(NULL,	"usb_host_hs_hsic60m_p1_clk",	&usb_host_hs_hsic60m_p1_clk,	CK_443X),
+	CLK(NULL,	"usb_host_hs_hsic60m_p2_clk",	&usb_host_hs_hsic60m_p2_clk,	CK_443X),
+	CLK(NULL,	"usb_host_hs_hsic480m_p2_clk",	&usb_host_hs_hsic480m_p2_clk,	CK_443X),
+	CLK(NULL,	"usb_host_hs_func48mclk",	&usb_host_hs_func48mclk,	CK_443X),
+	CLK(NULL,	"usb_host_hs_fck",		&usb_host_hs_fck,	CK_443X),
+	CLK("usbhs_omap",	"hs_fck",		&usb_host_hs_fck,	CK_443X),
+	CLK(NULL,	"otg_60m_gfclk",		&otg_60m_gfclk,	CK_443X),
+	CLK(NULL,	"usb_otg_hs_xclk",		&usb_otg_hs_xclk,	CK_443X),
+	CLK(NULL,	"usb_otg_hs_ick",		&usb_otg_hs_ick,	CK_443X),
+	CLK("musb-omap2430",	"ick",			&usb_otg_hs_ick,	CK_443X),
+	CLK(NULL,	"usb_phy_cm_clk32k",		&usb_phy_cm_clk32k,	CK_443X),
+	CLK(NULL,	"usb_tll_hs_usb_ch2_clk",	&usb_tll_hs_usb_ch2_clk,	CK_443X),
+	CLK(NULL,	"usb_tll_hs_usb_ch0_clk",	&usb_tll_hs_usb_ch0_clk,	CK_443X),
+	CLK(NULL,	"usb_tll_hs_usb_ch1_clk",	&usb_tll_hs_usb_ch1_clk,	CK_443X),
+	CLK(NULL,	"usb_tll_hs_ick",		&usb_tll_hs_ick,	CK_443X),
+	CLK("usbhs_omap",	"usbtll_ick",		&usb_tll_hs_ick,	CK_443X),
+	CLK("usbhs_tll",	"usbtll_ick",		&usb_tll_hs_ick,	CK_443X),
+	CLK(NULL,	"usim_ck",			&usim_ck,	CK_443X),
+	CLK(NULL,	"usim_fclk",			&usim_fclk,	CK_443X),
+	CLK(NULL,	"usim_fck",			&usim_fck,	CK_443X),
+	CLK(NULL,	"wd_timer2_fck",		&wd_timer2_fck,	CK_443X),
+	CLK(NULL,	"wd_timer3_fck",		&wd_timer3_fck,	CK_443X),
+	CLK(NULL,	"pmd_stm_clock_mux_ck",		&pmd_stm_clock_mux_ck,	CK_443X),
+	CLK(NULL,	"pmd_trace_clk_mux_ck",		&pmd_trace_clk_mux_ck,	CK_443X),
+	CLK(NULL,	"stm_clk_div_ck",		&stm_clk_div_ck,	CK_443X),
+	CLK(NULL,	"trace_clk_div_ck",		&trace_clk_div_ck,	CK_443X),
+	CLK(NULL,	"auxclk0_src_ck",		&auxclk0_src_ck,	CK_443X),
+	CLK(NULL,	"auxclk0_ck",			&auxclk0_ck,	CK_443X),
+	CLK(NULL,	"auxclkreq0_ck",		&auxclkreq0_ck,	CK_443X),
+	CLK(NULL,	"auxclk1_src_ck",		&auxclk1_src_ck,	CK_443X),
+	CLK(NULL,	"auxclk1_ck",			&auxclk1_ck,	CK_443X),
+	CLK(NULL,	"auxclkreq1_ck",		&auxclkreq1_ck,	CK_443X),
+	CLK(NULL,	"auxclk2_src_ck",		&auxclk2_src_ck,	CK_443X),
+	CLK(NULL,	"auxclk2_ck",			&auxclk2_ck,	CK_443X),
+	CLK(NULL,	"auxclkreq2_ck",		&auxclkreq2_ck,	CK_443X),
+	CLK(NULL,	"auxclk3_src_ck",		&auxclk3_src_ck,	CK_443X),
+	CLK(NULL,	"auxclk3_ck",			&auxclk3_ck,	CK_443X),
+	CLK(NULL,	"auxclkreq3_ck",		&auxclkreq3_ck,	CK_443X),
+	CLK(NULL,	"auxclk4_src_ck",		&auxclk4_src_ck,	CK_443X),
+	CLK(NULL,	"auxclk4_ck",			&auxclk4_ck,	CK_443X),
+	CLK(NULL,	"auxclkreq4_ck",		&auxclkreq4_ck,	CK_443X),
+	CLK(NULL,	"auxclk5_src_ck",		&auxclk5_src_ck,	CK_443X),
+	CLK(NULL,	"auxclk5_ck",			&auxclk5_ck,	CK_443X),
+	CLK(NULL,	"auxclkreq5_ck",		&auxclkreq5_ck,	CK_443X),
+	CLK("omap-gpmc",	"fck",			&dummy_ck,	CK_443X),
+	CLK("omap_i2c.1",	"ick",			&dummy_ck,	CK_443X),
+	CLK("omap_i2c.2",	"ick",			&dummy_ck,	CK_443X),
+	CLK("omap_i2c.3",	"ick",			&dummy_ck,	CK_443X),
+	CLK("omap_i2c.4",	"ick",			&dummy_ck,	CK_443X),
+	CLK(NULL,	"mailboxes_ick",		&dummy_ck,	CK_443X),
+	CLK("omap_hsmmc.0",	"ick",			&dummy_ck,	CK_443X),
+	CLK("omap_hsmmc.1",	"ick",			&dummy_ck,	CK_443X),
+	CLK("omap_hsmmc.2",	"ick",			&dummy_ck,	CK_443X),
+	CLK("omap_hsmmc.3",	"ick",			&dummy_ck,	CK_443X),
+	CLK("omap_hsmmc.4",	"ick",			&dummy_ck,	CK_443X),
+	CLK("omap-mcbsp.1",	"ick",			&dummy_ck,	CK_443X),
+	CLK("omap-mcbsp.2",	"ick",			&dummy_ck,	CK_443X),
+	CLK("omap-mcbsp.3",	"ick",			&dummy_ck,	CK_443X),
+	CLK("omap-mcbsp.4",	"ick",			&dummy_ck,	CK_443X),
+	CLK("omap2_mcspi.1",	"ick",			&dummy_ck,	CK_443X),
+	CLK("omap2_mcspi.2",	"ick",			&dummy_ck,	CK_443X),
+	CLK("omap2_mcspi.3",	"ick",			&dummy_ck,	CK_443X),
+	CLK("omap2_mcspi.4",	"ick",			&dummy_ck,	CK_443X),
+	CLK(NULL,	"uart1_ick",			&dummy_ck,	CK_443X),
+	CLK(NULL,	"uart2_ick",			&dummy_ck,	CK_443X),
+	CLK(NULL,	"uart3_ick",			&dummy_ck,	CK_443X),
+	CLK(NULL,	"uart4_ick",			&dummy_ck,	CK_443X),
+	CLK("usbhs_omap",	"usbhost_ick",		&dummy_ck,		CK_443X),
+	CLK("usbhs_omap",	"usbtll_fck",		&dummy_ck,	CK_443X),
+	CLK("usbhs_tll",	"usbtll_fck",		&dummy_ck,	CK_443X),
+	CLK("omap_wdt",	"ick",				&dummy_ck,	CK_443X),
+	CLK(NULL,	"timer_32k_ck",	&sys_32k_ck,	CK_443X),
+	/* TODO: Remove "omap_timer.X" aliases once DT migration is complete */
+	CLK("omap_timer.1",	"timer_sys_ck",	&sys_clkin_ck,	CK_443X),
+	CLK("omap_timer.2",	"timer_sys_ck",	&sys_clkin_ck,	CK_443X),
+	CLK("omap_timer.3",	"timer_sys_ck",	&sys_clkin_ck,	CK_443X),
+	CLK("omap_timer.4",	"timer_sys_ck",	&sys_clkin_ck,	CK_443X),
+	CLK("omap_timer.9",	"timer_sys_ck",	&sys_clkin_ck,	CK_443X),
+	CLK("omap_timer.10",	"timer_sys_ck",	&sys_clkin_ck,	CK_443X),
+	CLK("omap_timer.11",	"timer_sys_ck",	&sys_clkin_ck,	CK_443X),
+	CLK("omap_timer.5",	"timer_sys_ck",	&syc_clk_div_ck,	CK_443X),
+	CLK("omap_timer.6",	"timer_sys_ck",	&syc_clk_div_ck,	CK_443X),
+	CLK("omap_timer.7",	"timer_sys_ck",	&syc_clk_div_ck,	CK_443X),
+	CLK("omap_timer.8",	"timer_sys_ck",	&syc_clk_div_ck,	CK_443X),
+	CLK("4a318000.timer",	"timer_sys_ck",	&sys_clkin_ck,	CK_443X),
+	CLK("48032000.timer",	"timer_sys_ck",	&sys_clkin_ck,	CK_443X),
+	CLK("48034000.timer",	"timer_sys_ck",	&sys_clkin_ck,	CK_443X),
+	CLK("48036000.timer",	"timer_sys_ck",	&sys_clkin_ck,	CK_443X),
+	CLK("4803e000.timer",	"timer_sys_ck",	&sys_clkin_ck,	CK_443X),
+	CLK("48086000.timer",	"timer_sys_ck",	&sys_clkin_ck,	CK_443X),
+	CLK("48088000.timer",	"timer_sys_ck",	&sys_clkin_ck,	CK_443X),
+	CLK("49038000.timer",	"timer_sys_ck",	&syc_clk_div_ck,	CK_443X),
+	CLK("4903a000.timer",	"timer_sys_ck",	&syc_clk_div_ck,	CK_443X),
+	CLK("4903c000.timer",	"timer_sys_ck",	&syc_clk_div_ck,	CK_443X),
+	CLK("4903e000.timer",	"timer_sys_ck",	&syc_clk_div_ck,	CK_443X),
+	CLK(NULL,	"cpufreq_ck",	&dpll_mpu_ck,	CK_443X),
+};
+
+static const char *enable_init_clks[] = {
+	"emif1_fck",
+	"emif2_fck",
+	"gpmc_ick",
+	"l3_instr_ick",
+	"l3_main_3_ick",
+	"ocp_wp_noc_ick",
+};
+
+int __init omap4xxx_clk_init(void)
+{
+	u32 cpu_clkflg;
+	struct omap_clk *c;
+
+	if (cpu_is_omap443x()) {
+		cpu_mask = RATE_IN_4430;
+		cpu_clkflg = CK_443X;
+	} else if (cpu_is_omap446x() || cpu_is_omap447x()) {
+		cpu_mask = RATE_IN_4460 | RATE_IN_4430;
+		cpu_clkflg = CK_446X | CK_443X;
+
+		if (cpu_is_omap447x())
+			pr_warn("WARNING: OMAP4470 clock data incomplete!\n");
+	} else {
+		return 0;
+	}
+
+	for (c = omap44xx_clks; c < omap44xx_clks + ARRAY_SIZE(omap44xx_clks);
+									c++) {
+		if (c->cpu & cpu_clkflg) {
+			clkdev_add(&c->lk);
+			if (!__clk_init(NULL, c->lk.clk))
+				omap2_init_clk_hw_omap_clocks(c->lk.clk);
+		}
+	}
+
+	omap2_clk_disable_autoidle_all();
+
+	omap2_clk_enable_init_clocks(enable_init_clks,
+				     ARRAY_SIZE(enable_init_clks));
+
+	return 0;
+}
diff --git a/arch/arm/mach-omap2/clkt2xxx_apll.c b/arch/arm/mach-omap2/clkt2xxx_apll.c
index 8c5b13e..25b1fee 100644
--- a/arch/arm/mach-omap2/clkt2xxx_apll.c
+++ b/arch/arm/mach-omap2/clkt2xxx_apll.c
@@ -38,62 +38,88 @@
 
 /* Private functions */
 
-static int _apll96_enable(struct clk *clk)
+/**
+ * omap2xxx_clk_apll_locked - is the APLL locked?
+ * @hw: struct clk_hw * of the APLL to check
+ *
+ * If the APLL IP block referred to by @hw indicates that it's locked,
+ * return true; otherwise, return false.
+ */
+static bool omap2xxx_clk_apll_locked(struct clk_hw *hw)
+{
+	struct clk_hw_omap *clk = to_clk_hw_omap(hw);
+	u32 r, apll_mask;
+
+	apll_mask = EN_APLL_LOCKED << clk->enable_bit;
+
+	r = omap2_cm_read_mod_reg(PLL_MOD, CM_CLKEN);
+
+	return ((r & apll_mask) == apll_mask) ? true : false;
+}
+
+int omap2_clk_apll96_enable(struct clk_hw *hw)
 {
 	return omap2xxx_cm_apll96_enable();
 }
 
-static int _apll54_enable(struct clk *clk)
+int omap2_clk_apll54_enable(struct clk_hw *hw)
 {
 	return omap2xxx_cm_apll54_enable();
 }
 
-static void _apll96_allow_idle(struct clk *clk)
+static void _apll96_allow_idle(struct clk_hw_omap *clk)
 {
 	omap2xxx_cm_set_apll96_auto_low_power_stop();
 }
 
-static void _apll96_deny_idle(struct clk *clk)
+static void _apll96_deny_idle(struct clk_hw_omap *clk)
 {
 	omap2xxx_cm_set_apll96_disable_autoidle();
 }
 
-static void _apll54_allow_idle(struct clk *clk)
+static void _apll54_allow_idle(struct clk_hw_omap *clk)
 {
 	omap2xxx_cm_set_apll54_auto_low_power_stop();
 }
 
-static void _apll54_deny_idle(struct clk *clk)
+static void _apll54_deny_idle(struct clk_hw_omap *clk)
 {
 	omap2xxx_cm_set_apll54_disable_autoidle();
 }
 
-static void _apll96_disable(struct clk *clk)
+void omap2_clk_apll96_disable(struct clk_hw *hw)
 {
 	omap2xxx_cm_apll96_disable();
 }
 
-static void _apll54_disable(struct clk *clk)
+void omap2_clk_apll54_disable(struct clk_hw *hw)
 {
 	omap2xxx_cm_apll54_disable();
 }
 
+unsigned long omap2_clk_apll54_recalc(struct clk_hw *hw,
+				      unsigned long parent_rate)
+{
+	return (omap2xxx_clk_apll_locked(hw)) ? 54000000 : 0;
+}
+
+unsigned long omap2_clk_apll96_recalc(struct clk_hw *hw,
+				      unsigned long parent_rate)
+{
+	return (omap2xxx_clk_apll_locked(hw)) ? 96000000 : 0;
+}
+
 /* Public data */
-
-const struct clkops clkops_apll96 = {
-	.enable		= _apll96_enable,
-	.disable	= _apll96_disable,
-	.allow_idle	= _apll96_allow_idle,
-	.deny_idle	= _apll96_deny_idle,
-};
-
-const struct clkops clkops_apll54 = {
-	.enable		= _apll54_enable,
-	.disable	= _apll54_disable,
+const struct clk_hw_omap_ops clkhwops_apll54 = {
 	.allow_idle	= _apll54_allow_idle,
 	.deny_idle	= _apll54_deny_idle,
 };
 
+const struct clk_hw_omap_ops clkhwops_apll96 = {
+	.allow_idle	= _apll96_allow_idle,
+	.deny_idle	= _apll96_deny_idle,
+};
+
 /* Public functions */
 
 u32 omap2xxx_get_apll_clkin(void)
diff --git a/arch/arm/mach-omap2/clkt2xxx_dpll.c b/arch/arm/mach-omap2/clkt2xxx_dpll.c
index 399534c..82572e2 100644
--- a/arch/arm/mach-omap2/clkt2xxx_dpll.c
+++ b/arch/arm/mach-omap2/clkt2xxx_dpll.c
@@ -29,7 +29,7 @@
  * REVISIT: DPLL can optionally enter low-power bypass by writing 0x1
  * instead.  Add some mechanism to optionally enter this mode.
  */
-static void _allow_idle(struct clk *clk)
+static void _allow_idle(struct clk_hw_omap *clk)
 {
 	if (!clk || !clk->dpll_data)
 		return;
@@ -43,7 +43,7 @@
  *
  * Disable DPLL automatic idle control.  No return value.
  */
-static void _deny_idle(struct clk *clk)
+static void _deny_idle(struct clk_hw_omap *clk)
 {
 	if (!clk || !clk->dpll_data)
 		return;
@@ -53,9 +53,7 @@
 
 
 /* Public data */
-
-const struct clkops clkops_omap2xxx_dpll_ops = {
+const struct clk_hw_omap_ops clkhwops_omap2xxx_dpll = {
 	.allow_idle	= _allow_idle,
 	.deny_idle	= _deny_idle,
 };
-
diff --git a/arch/arm/mach-omap2/clkt2xxx_dpllcore.c b/arch/arm/mach-omap2/clkt2xxx_dpllcore.c
index 825e44c..d862010 100644
--- a/arch/arm/mach-omap2/clkt2xxx_dpllcore.c
+++ b/arch/arm/mach-omap2/clkt2xxx_dpllcore.c
@@ -40,7 +40,7 @@
  * (currently defined as "dpll_ck" in the OMAP2xxx clock tree).  Set
  * during dpll_ck init and used later by omap2xxx_clk_get_core_rate().
  */
-static struct clk *dpll_core_ck;
+static struct clk_hw_omap *dpll_core_ck;
 
 /**
  * omap2xxx_clk_get_core_rate - return the CORE_CLK rate
@@ -104,13 +104,16 @@
 
 }
 
-unsigned long omap2_dpllcore_recalc(struct clk *clk)
+unsigned long omap2_dpllcore_recalc(struct clk_hw *hw,
+				    unsigned long parent_rate)
 {
 	return omap2xxx_clk_get_core_rate();
 }
 
-int omap2_reprogram_dpllcore(struct clk *clk, unsigned long rate)
+int omap2_reprogram_dpllcore(struct clk_hw *hw, unsigned long rate,
+			     unsigned long parent_rate)
 {
+	struct clk_hw_omap *clk = to_clk_hw_omap(hw);
 	u32 cur_rate, low, mult, div, valid_rate, done_rate;
 	u32 bypass = 0;
 	struct prcm_config tmpset;
@@ -188,8 +191,8 @@
  * statically defined, this code may need to change to increment some
  * kind of use count on dpll_ck.
  */
-void omap2xxx_clkt_dpllcore_init(struct clk *clk)
+void omap2xxx_clkt_dpllcore_init(struct clk_hw *hw)
 {
 	WARN(dpll_core_ck, "dpll_core_ck already set - should never happen");
-	dpll_core_ck = clk;
+	dpll_core_ck = to_clk_hw_omap(hw);
 }
diff --git a/arch/arm/mach-omap2/clkt2xxx_osc.c b/arch/arm/mach-omap2/clkt2xxx_osc.c
index e177737..19f54d4 100644
--- a/arch/arm/mach-omap2/clkt2xxx_osc.c
+++ b/arch/arm/mach-omap2/clkt2xxx_osc.c
@@ -35,7 +35,7 @@
  * clk_enable/clk_disable()-based usecounting for osc_ck should be
  * replaced with autoidle-based usecounting.
  */
-static int omap2_enable_osc_ck(struct clk *clk)
+int omap2_enable_osc_ck(struct clk_hw *clk)
 {
 	u32 pcc;
 
@@ -53,7 +53,7 @@
  * clk_enable/clk_disable()-based usecounting for osc_ck should be
  * replaced with autoidle-based usecounting.
  */
-static void omap2_disable_osc_ck(struct clk *clk)
+void omap2_disable_osc_ck(struct clk_hw *clk)
 {
 	u32 pcc;
 
@@ -62,13 +62,8 @@
 	__raw_writel(pcc | OMAP_AUTOEXTCLKMODE_MASK, prcm_clksrc_ctrl);
 }
 
-const struct clkops clkops_oscck = {
-	.enable		= omap2_enable_osc_ck,
-	.disable	= omap2_disable_osc_ck,
-};
-
-unsigned long omap2_osc_clk_recalc(struct clk *clk)
+unsigned long omap2_osc_clk_recalc(struct clk_hw *clk,
+				   unsigned long parent_rate)
 {
 	return omap2xxx_get_apll_clkin() * omap2xxx_get_sysclkdiv();
 }
-
diff --git a/arch/arm/mach-omap2/clkt2xxx_sys.c b/arch/arm/mach-omap2/clkt2xxx_sys.c
index 46683b3..f467d07 100644
--- a/arch/arm/mach-omap2/clkt2xxx_sys.c
+++ b/arch/arm/mach-omap2/clkt2xxx_sys.c
@@ -40,9 +40,8 @@
 	return div;
 }
 
-unsigned long omap2xxx_sys_clk_recalc(struct clk *clk)
+unsigned long omap2xxx_sys_clk_recalc(struct clk_hw *clk,
+				      unsigned long parent_rate)
 {
-	return clk->parent->rate / omap2xxx_get_sysclkdiv();
+	return parent_rate / omap2xxx_get_sysclkdiv();
 }
-
-
diff --git a/arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c b/arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c
index 1c2041f..ae2b35e 100644
--- a/arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c
+++ b/arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c
@@ -58,7 +58,8 @@
  *
  * Set virt_prcm_set's rate to the mpu_speed field of the current PRCM set.
  */
-unsigned long omap2_table_mpu_recalc(struct clk *clk)
+unsigned long omap2_table_mpu_recalc(struct clk_hw *clk,
+				     unsigned long parent_rate)
 {
 	return curr_prcm_set->mpu_speed;
 }
@@ -70,7 +71,8 @@
  * Some might argue L3-DDR, others ARM, others IVA. This code is simple and
  * just uses the ARM rates.
  */
-long omap2_round_to_table_rate(struct clk *clk, unsigned long rate)
+long omap2_round_to_table_rate(struct clk_hw *hw, unsigned long rate,
+			       unsigned long *parent_rate)
 {
 	const struct prcm_config *ptr;
 	long highest_rate;
@@ -93,7 +95,8 @@
 }
 
 /* Sets basic clocks based on the specified rate */
-int omap2_select_table_rate(struct clk *clk, unsigned long rate)
+int omap2_select_table_rate(struct clk_hw *hw, unsigned long rate,
+			    unsigned long parent_rate)
 {
 	u32 cur_rate, done_rate, bypass = 0, tmp;
 	const struct prcm_config *prcm;
diff --git a/arch/arm/mach-omap2/clkt34xx_dpll3m2.c b/arch/arm/mach-omap2/clkt34xx_dpll3m2.c
index 6cf298e..eb69acf 100644
--- a/arch/arm/mach-omap2/clkt34xx_dpll3m2.c
+++ b/arch/arm/mach-omap2/clkt34xx_dpll3m2.c
@@ -44,8 +44,10 @@
  * Program the DPLL M2 divider with the rounded target rate.  Returns
  * -EINVAL upon error, or 0 upon success.
  */
-int omap3_core_dpll_m2_set_rate(struct clk *clk, unsigned long rate)
+int omap3_core_dpll_m2_set_rate(struct clk_hw *hw, unsigned long rate,
+					unsigned long parent_rate)
 {
+	struct clk_hw_omap *clk = to_clk_hw_omap(hw);
 	u32 new_div = 0;
 	u32 unlock_dll = 0;
 	u32 c;
@@ -63,7 +65,7 @@
 		return -EINVAL;
 
 	sdrcrate = __clk_get_rate(sdrc_ick_p);
-	clkrate = __clk_get_rate(clk);
+	clkrate = __clk_get_rate(hw->clk);
 	if (rate > clkrate)
 		sdrcrate <<= ((rate / clkrate) >> 1);
 	else
@@ -112,8 +114,6 @@
 				  sdrc_cs0->rfr_ctrl, sdrc_cs0->actim_ctrla,
 				  sdrc_cs0->actim_ctrlb, sdrc_cs0->mr,
 				  0, 0, 0, 0);
-	clk->rate = rate;
-
 	return 0;
 }
 
diff --git a/arch/arm/mach-omap2/clkt_clksel.c b/arch/arm/mach-omap2/clkt_clksel.c
index 53646fa..0ec9f6f 100644
--- a/arch/arm/mach-omap2/clkt_clksel.c
+++ b/arch/arm/mach-omap2/clkt_clksel.c
@@ -41,7 +41,7 @@
 
 #include <linux/kernel.h>
 #include <linux/errno.h>
-#include <linux/clk.h>
+#include <linux/clk-provider.h>
 #include <linux/io.h>
 #include <linux/bug.h>
 
@@ -58,11 +58,14 @@
  * the element associated with the supplied parent clock address.
  * Returns a pointer to the struct clksel on success or NULL on error.
  */
-static const struct clksel *_get_clksel_by_parent(struct clk *clk,
+static const struct clksel *_get_clksel_by_parent(struct clk_hw_omap *clk,
 						  struct clk *src_clk)
 {
 	const struct clksel *clks;
 
+	if (!src_clk)
+		return NULL;
+
 	for (clks = clk->clksel; clks->parent; clks++)
 		if (clks->parent == src_clk)
 			break; /* Found the requested parent */
@@ -70,7 +73,7 @@
 	if (!clks->parent) {
 		/* This indicates a data problem */
 		WARN(1, "clock: %s: could not find parent clock %s in clksel array\n",
-		     __clk_get_name(clk), __clk_get_name(src_clk));
+		     __clk_get_name(clk->hw.clk), __clk_get_name(src_clk));
 		return NULL;
 	}
 
@@ -78,64 +81,6 @@
 }
 
 /**
- * _get_div_and_fieldval() - find the new clksel divisor and field value to use
- * @src_clk: planned new parent struct clk *
- * @clk: struct clk * that is being reparented
- * @field_val: pointer to a u32 to contain the register data for the divisor
- *
- * Given an intended new parent struct clk * @src_clk, and the struct
- * clk * @clk to the clock that is being reparented, find the
- * appropriate rate divisor for the new clock (returned as the return
- * value), and the corresponding register bitfield data to program to
- * reach that divisor (returned in the u32 pointed to by @field_val).
- * Returns 0 on error, or returns the newly-selected divisor upon
- * success (in this latter case, the corresponding register bitfield
- * value is passed back in the variable pointed to by @field_val)
- */
-static u8 _get_div_and_fieldval(struct clk *src_clk, struct clk *clk,
-				u32 *field_val)
-{
-	const struct clksel *clks;
-	const struct clksel_rate *clkr, *max_clkr = NULL;
-	u8 max_div = 0;
-
-	clks = _get_clksel_by_parent(clk, src_clk);
-	if (!clks)
-		return 0;
-
-	/*
-	 * Find the highest divisor (e.g., the one resulting in the
-	 * lowest rate) to use as the default.  This should avoid
-	 * clock rates that are too high for the device.  XXX A better
-	 * solution here would be to try to determine if there is a
-	 * divisor matching the original clock rate before the parent
-	 * switch, and if it cannot be found, to fall back to the
-	 * highest divisor.
-	 */
-	for (clkr = clks->rates; clkr->div; clkr++) {
-		if (!(clkr->flags & cpu_mask))
-			continue;
-
-		if (clkr->div > max_div) {
-			max_div = clkr->div;
-			max_clkr = clkr;
-		}
-	}
-
-	if (max_div == 0) {
-		/* This indicates an error in the clksel data */
-		WARN(1, "clock: %s: could not find divisor for parent %s\n",
-		     __clk_get_name(clk),
-		     __clk_get_name(__clk_get_parent(src_clk)));
-		return 0;
-	}
-
-	*field_val = max_clkr->val;
-
-	return max_div;
-}
-
-/**
  * _write_clksel_reg() - program a clock's clksel register in hardware
  * @clk: struct clk * to program
  * @v: clksel bitfield value to program (with LSB at bit 0)
@@ -148,7 +93,7 @@
  * take into account any time the hardware might take to switch the
  * clock source.
  */
-static void _write_clksel_reg(struct clk *clk, u32 field_val)
+static void _write_clksel_reg(struct clk_hw_omap *clk, u32 field_val)
 {
 	u32 v;
 
@@ -171,13 +116,14 @@
  * before calling.  Returns 0 on error or returns the actual integer divisor
  * upon success.
  */
-static u32 _clksel_to_divisor(struct clk *clk, u32 field_val)
+static u32 _clksel_to_divisor(struct clk_hw_omap *clk, u32 field_val)
 {
 	const struct clksel *clks;
 	const struct clksel_rate *clkr;
 	struct clk *parent;
 
-	parent = __clk_get_parent(clk);
+	parent = __clk_get_parent(clk->hw.clk);
+
 	clks = _get_clksel_by_parent(clk, parent);
 	if (!clks)
 		return 0;
@@ -193,7 +139,8 @@
 	if (!clkr->div) {
 		/* This indicates a data error */
 		WARN(1, "clock: %s: could not find fieldval %d for parent %s\n",
-		     __clk_get_name(clk), field_val, __clk_get_name(parent));
+		     __clk_get_name(clk->hw.clk), field_val,
+		     __clk_get_name(parent));
 		return 0;
 	}
 
@@ -210,7 +157,7 @@
  * register field value _before_ left-shifting (i.e., LSB is at bit
  * 0); or returns 0xFFFFFFFF (~0) upon error.
  */
-static u32 _divisor_to_clksel(struct clk *clk, u32 div)
+static u32 _divisor_to_clksel(struct clk_hw_omap *clk, u32 div)
 {
 	const struct clksel *clks;
 	const struct clksel_rate *clkr;
@@ -219,7 +166,7 @@
 	/* should never happen */
 	WARN_ON(div == 0);
 
-	parent = __clk_get_parent(clk);
+	parent = __clk_get_parent(clk->hw.clk);
 	clks = _get_clksel_by_parent(clk, parent);
 	if (!clks)
 		return ~0;
@@ -234,7 +181,8 @@
 
 	if (!clkr->div) {
 		pr_err("clock: %s: could not find divisor %d for parent %s\n",
-		       __clk_get_name(clk), div, __clk_get_name(parent));
+		       __clk_get_name(clk->hw.clk), div,
+		       __clk_get_name(parent));
 		return ~0;
 	}
 
@@ -249,7 +197,7 @@
  * into the hardware, convert it into the actual divisor value, and
  * return it; or return 0 on error.
  */
-static u32 _read_divisor(struct clk *clk)
+static u32 _read_divisor(struct clk_hw_omap *clk)
 {
 	u32 v;
 
@@ -277,7 +225,8 @@
  *
  * Returns the rounded clock rate or returns 0xffffffff on error.
  */
-u32 omap2_clksel_round_rate_div(struct clk *clk, unsigned long target_rate,
+u32 omap2_clksel_round_rate_div(struct clk_hw_omap *clk,
+						 unsigned long target_rate,
 				u32 *new_div)
 {
 	unsigned long test_rate;
@@ -288,9 +237,9 @@
 	unsigned long parent_rate;
 	const char *clk_name;
 
-	parent = __clk_get_parent(clk);
+	parent = __clk_get_parent(clk->hw.clk);
+	clk_name = __clk_get_name(clk->hw.clk);
 	parent_rate = __clk_get_rate(parent);
-	clk_name = __clk_get_name(clk);
 
 	if (!clk->clksel || !clk->clksel_mask)
 		return ~0;
@@ -341,27 +290,35 @@
  */
 
 /**
- * omap2_init_clksel_parent() - set a clksel clk's parent field from the hdwr
- * @clk: OMAP clock struct ptr to use
+ * omap2_clksel_find_parent_index() - return the array index of the current
+ * hardware parent of @hw
+ * @hw: struct clk_hw * to find the current hardware parent of
  *
- * Given a pointer @clk to a source-selectable struct clk, read the
- * hardware register and determine what its parent is currently set
- * to.  Update @clk's .parent field with the appropriate clk ptr.  No
- * return value.
+ * Given a struct clk_hw pointer @hw to the 'hw' member of a struct
+ * clk_hw_omap record representing a source-selectable hardware clock,
+ * read the hardware register and determine what its parent is
+ * currently set to.  Intended to be called only by the common clock
+ * framework struct clk_hw_ops.get_parent function pointer.  Return
+ * the array index of this parent clock upon success -- there is no
+ * way to return an error, so if we encounter an error, just WARN()
+ * and pretend that we know that we're doing.
  */
-void omap2_init_clksel_parent(struct clk *clk)
+u8 omap2_clksel_find_parent_index(struct clk_hw *hw)
 {
+	struct clk_hw_omap *clk = to_clk_hw_omap(hw);
 	const struct clksel *clks;
 	const struct clksel_rate *clkr;
 	u32 r, found = 0;
 	struct clk *parent;
 	const char *clk_name;
+	int ret = 0, f = 0;
 
-	if (!clk->clksel || !clk->clksel_mask)
-		return;
+	parent = __clk_get_parent(hw->clk);
+	clk_name = __clk_get_name(hw->clk);
 
-	parent = __clk_get_parent(clk);
-	clk_name = __clk_get_name(clk);
+	/* XXX should be able to return an error */
+	WARN((!clk->clksel || !clk->clksel_mask),
+	     "clock: %s: attempt to call on a non-clksel clock", clk_name);
 
 	r = __raw_readl(clk->clksel_reg) & clk->clksel_mask;
 	r >>= __ffs(clk->clksel_mask);
@@ -372,27 +329,21 @@
 				continue;
 
 			if (clkr->val == r) {
-				if (parent != clks->parent) {
-					pr_debug("clock: %s: inited parent to %s (was %s)\n",
-						 clk_name,
-						 __clk_get_name(clks->parent),
-						 ((parent) ?
-						  __clk_get_name(parent) :
-						 "NULL"));
-					clk_reparent(clk, clks->parent);
-				}
 				found = 1;
+				ret = f;
 			}
 		}
+		f++;
 	}
 
 	/* This indicates a data error */
 	WARN(!found, "clock: %s: init parent: could not find regval %0x\n",
 	     clk_name, r);
 
-	return;
+	return ret;
 }
 
+
 /**
  * omap2_clksel_recalc() - function ptr to pass via struct clk .recalc field
  * @clk: struct clk *
@@ -402,21 +353,23 @@
  * function.  Returns the clock's current rate, based on its parent's rate
  * and its current divisor setting in the hardware.
  */
-unsigned long omap2_clksel_recalc(struct clk *clk)
+unsigned long omap2_clksel_recalc(struct clk_hw *hw, unsigned long parent_rate)
 {
 	unsigned long rate;
 	u32 div = 0;
-	struct clk *parent;
+	struct clk_hw_omap *clk = to_clk_hw_omap(hw);
+
+	if (!parent_rate)
+		return 0;
 
 	div = _read_divisor(clk);
-	if (div == 0)
-		return __clk_get_rate(clk);
+	if (!div)
+		rate = parent_rate;
+	else
+		rate = parent_rate / div;
 
-	parent = __clk_get_parent(clk);
-	rate = __clk_get_rate(parent) / div;
-
-	pr_debug("clock: %s: recalc'd rate is %ld (div %d)\n",
-		 __clk_get_name(clk), rate, div);
+	pr_debug("%s: recalc'd %s's rate to %lu (div %d)\n", __func__,
+		 __clk_get_name(hw->clk), rate, div);
 
 	return rate;
 }
@@ -432,8 +385,10 @@
  *
  * Returns the rounded clock rate or returns 0xffffffff on error.
  */
-long omap2_clksel_round_rate(struct clk *clk, unsigned long target_rate)
+long omap2_clksel_round_rate(struct clk_hw *hw, unsigned long target_rate,
+			unsigned long *parent_rate)
 {
+	struct clk_hw_omap *clk = to_clk_hw_omap(hw);
 	u32 new_div;
 
 	return omap2_clksel_round_rate_div(clk, target_rate, &new_div);
@@ -454,8 +409,10 @@
  * is changed, they will all be affected without any notification.
  * Returns -EINVAL upon error, or 0 upon success.
  */
-int omap2_clksel_set_rate(struct clk *clk, unsigned long rate)
+int omap2_clksel_set_rate(struct clk_hw *hw, unsigned long rate,
+				unsigned long parent_rate)
 {
+	struct clk_hw_omap *clk = to_clk_hw_omap(hw);
 	u32 field_val, validrate, new_div = 0;
 
 	if (!clk->clksel || !clk->clksel_mask)
@@ -471,10 +428,8 @@
 
 	_write_clksel_reg(clk, field_val);
 
-	clk->rate = __clk_get_rate(__clk_get_parent(clk)) / new_div;
-
-	pr_debug("clock: %s: set rate to %ld\n", __clk_get_name(clk),
-		 __clk_get_rate(clk));
+	pr_debug("clock: %s: set rate to %ld\n", __clk_get_name(hw->clk),
+		 __clk_get_rate(hw->clk));
 
 	return 0;
 }
@@ -499,32 +454,13 @@
  * affected without any notification.  Returns -EINVAL upon error, or
  * 0 upon success.
  */
-int omap2_clksel_set_parent(struct clk *clk, struct clk *new_parent)
+int omap2_clksel_set_parent(struct clk_hw *hw, u8 field_val)
 {
-	u32 field_val = 0;
-	u32 parent_div;
+	struct clk_hw_omap *clk = to_clk_hw_omap(hw);
 
 	if (!clk->clksel || !clk->clksel_mask)
 		return -EINVAL;
 
-	parent_div = _get_div_and_fieldval(new_parent, clk, &field_val);
-	if (!parent_div)
-		return -EINVAL;
-
 	_write_clksel_reg(clk, field_val);
-
-	clk_reparent(clk, new_parent);
-
-	/* CLKSEL clocks follow their parents' rates, divided by a divisor */
-	clk->rate = __clk_get_rate(new_parent);
-
-	if (parent_div > 0)
-		__clk_get_rate(clk) /= parent_div;
-
-	pr_debug("clock: %s: set parent to %s (new rate %ld)\n",
-		 __clk_get_name(clk),
-		 __clk_get_name(__clk_get_parent(clk)),
-		 __clk_get_rate(clk));
-
 	return 0;
 }
diff --git a/arch/arm/mach-omap2/clkt_dpll.c b/arch/arm/mach-omap2/clkt_dpll.c
index 8463cc3..924c230 100644
--- a/arch/arm/mach-omap2/clkt_dpll.c
+++ b/arch/arm/mach-omap2/clkt_dpll.c
@@ -16,7 +16,7 @@
 
 #include <linux/kernel.h>
 #include <linux/errno.h>
-#include <linux/clk.h>
+#include <linux/clk-provider.h>
 #include <linux/io.h>
 
 #include <asm/div64.h>
@@ -76,7 +76,7 @@
  * (assuming that it is counting N upwards), or -2 if the enclosing loop
  * should skip to the next iteration (again assuming N is increasing).
  */
-static int _dpll_test_fint(struct clk *clk, u8 n)
+static int _dpll_test_fint(struct clk_hw_omap *clk, u8 n)
 {
 	struct dpll_data *dd;
 	long fint, fint_min, fint_max;
@@ -85,7 +85,7 @@
 	dd = clk->dpll_data;
 
 	/* DPLL divider must result in a valid jitter correction val */
-	fint = __clk_get_rate(__clk_get_parent(clk)) / n;
+	fint = __clk_get_rate(__clk_get_parent(clk->hw.clk)) / n;
 
 	if (cpu_is_omap24xx()) {
 		/* Should not be called for OMAP2, so warn if it is called */
@@ -186,15 +186,15 @@
 }
 
 /* Public functions */
-
-void omap2_init_dpll_parent(struct clk *clk)
+u8 omap2_init_dpll_parent(struct clk_hw *hw)
 {
+	struct clk_hw_omap *clk = to_clk_hw_omap(hw);
 	u32 v;
 	struct dpll_data *dd;
 
 	dd = clk->dpll_data;
 	if (!dd)
-		return;
+		return -EINVAL;
 
 	v = __raw_readl(dd->control_reg);
 	v &= dd->enable_mask;
@@ -204,18 +204,18 @@
 	if (cpu_is_omap24xx()) {
 		if (v == OMAP2XXX_EN_DPLL_LPBYPASS ||
 		    v == OMAP2XXX_EN_DPLL_FRBYPASS)
-			clk_reparent(clk, dd->clk_bypass);
+			return 1;
 	} else if (cpu_is_omap34xx()) {
 		if (v == OMAP3XXX_EN_DPLL_LPBYPASS ||
 		    v == OMAP3XXX_EN_DPLL_FRBYPASS)
-			clk_reparent(clk, dd->clk_bypass);
+			return 1;
 	} else if (soc_is_am33xx() || cpu_is_omap44xx()) {
 		if (v == OMAP4XXX_EN_DPLL_LPBYPASS ||
 		    v == OMAP4XXX_EN_DPLL_FRBYPASS ||
 		    v == OMAP4XXX_EN_DPLL_MNBYPASS)
-			clk_reparent(clk, dd->clk_bypass);
+			return 1;
 	}
-	return;
+	return 0;
 }
 
 /**
@@ -232,7 +232,7 @@
  * locked, or the appropriate bypass rate if the DPLL is bypassed, or 0
  * if the clock @clk is not a DPLL.
  */
-u32 omap2_get_dpll_rate(struct clk *clk)
+unsigned long omap2_get_dpll_rate(struct clk_hw_omap *clk)
 {
 	long long dpll_clk;
 	u32 dpll_mult, dpll_div, v;
@@ -288,8 +288,10 @@
  * (expensive) function again.  Returns ~0 if the target rate cannot
  * be rounded, or the rounded rate upon success.
  */
-long omap2_dpll_round_rate(struct clk *clk, unsigned long target_rate)
+long omap2_dpll_round_rate(struct clk_hw *hw, unsigned long target_rate,
+		unsigned long *parent_rate)
 {
+	struct clk_hw_omap *clk = to_clk_hw_omap(hw);
 	int m, n, r, scaled_max_m;
 	unsigned long scaled_rt_rp;
 	unsigned long new_rate = 0;
@@ -303,7 +305,7 @@
 	dd = clk->dpll_data;
 
 	ref_rate = __clk_get_rate(dd->clk_ref);
-	clk_name = __clk_get_name(clk);
+	clk_name = __clk_get_name(hw->clk);
 	pr_debug("clock: %s: starting DPLL round_rate, target rate %ld\n",
 		 clk_name, target_rate);
 
diff --git a/arch/arm/mach-omap2/clkt_iclk.c b/arch/arm/mach-omap2/clkt_iclk.c
index fe774a0..f10eb03 100644
--- a/arch/arm/mach-omap2/clkt_iclk.c
+++ b/arch/arm/mach-omap2/clkt_iclk.c
@@ -11,7 +11,7 @@
 #undef DEBUG
 
 #include <linux/kernel.h>
-#include <linux/clk.h>
+#include <linux/clk-provider.h>
 #include <linux/io.h>
 
 
@@ -23,7 +23,7 @@
 /* Private functions */
 
 /* XXX */
-void omap2_clkt_iclk_allow_idle(struct clk *clk)
+void omap2_clkt_iclk_allow_idle(struct clk_hw_omap *clk)
 {
 	u32 v, r;
 
@@ -35,7 +35,7 @@
 }
 
 /* XXX */
-void omap2_clkt_iclk_deny_idle(struct clk *clk)
+void omap2_clkt_iclk_deny_idle(struct clk_hw_omap *clk)
 {
 	u32 v, r;
 
@@ -48,33 +48,17 @@
 
 /* Public data */
 
-const struct clkops clkops_omap2_iclk_dflt_wait = {
-	.enable		= omap2_dflt_clk_enable,
-	.disable	= omap2_dflt_clk_disable,
-	.find_companion	= omap2_clk_dflt_find_companion,
+const struct clk_hw_omap_ops clkhwops_iclk = {
+	.allow_idle	= omap2_clkt_iclk_allow_idle,
+	.deny_idle	= omap2_clkt_iclk_deny_idle,
+};
+
+const struct clk_hw_omap_ops clkhwops_iclk_wait = {
+	.allow_idle	= omap2_clkt_iclk_allow_idle,
+	.deny_idle	= omap2_clkt_iclk_deny_idle,
 	.find_idlest	= omap2_clk_dflt_find_idlest,
-	.allow_idle	= omap2_clkt_iclk_allow_idle,
-	.deny_idle	= omap2_clkt_iclk_deny_idle,
-};
-
-const struct clkops clkops_omap2_iclk_dflt = {
-	.enable		= omap2_dflt_clk_enable,
-	.disable	= omap2_dflt_clk_disable,
-	.allow_idle	= omap2_clkt_iclk_allow_idle,
-	.deny_idle	= omap2_clkt_iclk_deny_idle,
-};
-
-const struct clkops clkops_omap2_iclk_idle_only = {
-	.allow_idle	= omap2_clkt_iclk_allow_idle,
-	.deny_idle	= omap2_clkt_iclk_deny_idle,
-};
-
-const struct clkops clkops_omap2_mdmclk_dflt_wait = {
-	.enable		= omap2_dflt_clk_enable,
-	.disable	= omap2_dflt_clk_disable,
 	.find_companion	= omap2_clk_dflt_find_companion,
-	.find_idlest	= omap2_clk_dflt_find_idlest,
-	.allow_idle	= omap2_clkt_iclk_allow_idle,
-	.deny_idle	= omap2_clkt_iclk_deny_idle,
 };
 
+
+
diff --git a/arch/arm/mach-omap2/clock.c b/arch/arm/mach-omap2/clock.c
index e381d991..e4ec3a6 100644
--- a/arch/arm/mach-omap2/clock.c
+++ b/arch/arm/mach-omap2/clock.c
@@ -20,7 +20,7 @@
 #include <linux/errno.h>
 #include <linux/err.h>
 #include <linux/delay.h>
-#include <linux/clk.h>
+#include <linux/clk-provider.h>
 #include <linux/io.h>
 #include <linux/bitops.h>
 
@@ -55,9 +55,28 @@
  */
 static bool clkdm_control = true;
 
-static LIST_HEAD(clocks);
-static DEFINE_MUTEX(clocks_mutex);
-static DEFINE_SPINLOCK(clockfw_lock);
+static LIST_HEAD(clk_hw_omap_clocks);
+
+/*
+ * Used for clocks that have the same value as the parent clock,
+ * divided by some factor
+ */
+unsigned long omap_fixed_divisor_recalc(struct clk_hw *hw,
+		unsigned long parent_rate)
+{
+	struct clk_hw_omap *oclk;
+
+	if (!hw) {
+		pr_warn("%s: hw is NULL\n", __func__);
+		return -EINVAL;
+	}
+
+	oclk = to_clk_hw_omap(hw);
+
+	WARN_ON(!oclk->fixed_div);
+
+	return parent_rate / oclk->fixed_div;
+}
 
 /*
  * OMAP2+ specific clock functions
@@ -109,7 +128,7 @@
  * belong in the clock code and will be moved in the medium term to
  * module-dependent code.  No return value.
  */
-static void _omap2_module_wait_ready(struct clk *clk)
+static void _omap2_module_wait_ready(struct clk_hw_omap *clk)
 {
 	void __iomem *companion_reg, *idlest_reg;
 	u8 other_bit, idlest_bit, idlest_val, idlest_reg_id;
@@ -124,12 +143,11 @@
 	}
 
 	clk->ops->find_idlest(clk, &idlest_reg, &idlest_bit, &idlest_val);
-
 	r = cm_split_idlest_reg(idlest_reg, &prcm_mod, &idlest_reg_id);
 	if (r) {
 		/* IDLEST register not in the CM module */
 		_wait_idlest_generic(idlest_reg, (1 << idlest_bit), idlest_val,
-				     clk->name);
+				     __clk_get_name(clk->hw.clk));
 	} else {
 		cm_wait_module_ready(prcm_mod, idlest_reg_id, idlest_bit);
 	};
@@ -145,15 +163,16 @@
  * clockdomain pointer, and save it into the struct clk.  Intended to be
  * called during clk_register().  No return value.
  */
-void omap2_init_clk_clkdm(struct clk *clk)
+void omap2_init_clk_clkdm(struct clk_hw *hw)
 {
+	struct clk_hw_omap *clk = to_clk_hw_omap(hw);
 	struct clockdomain *clkdm;
 	const char *clk_name;
 
 	if (!clk->clkdm_name)
 		return;
 
-	clk_name = __clk_get_name(clk);
+	clk_name = __clk_get_name(hw->clk);
 
 	clkdm = clkdm_lookup(clk->clkdm_name);
 	if (clkdm) {
@@ -200,8 +219,8 @@
  * associate this type of code with per-module data structures to
  * avoid this issue, and remove the casts.  No return value.
  */
-void omap2_clk_dflt_find_companion(struct clk *clk, void __iomem **other_reg,
-				   u8 *other_bit)
+void omap2_clk_dflt_find_companion(struct clk_hw_omap *clk,
+			void __iomem **other_reg, u8 *other_bit)
 {
 	u32 r;
 
@@ -229,8 +248,8 @@
  * register address ID (e.g., that CM_FCLKEN2 corresponds to
  * CM_IDLEST2).  This is not true for all modules.  No return value.
  */
-void omap2_clk_dflt_find_idlest(struct clk *clk, void __iomem **idlest_reg,
-				u8 *idlest_bit, u8 *idlest_val)
+void omap2_clk_dflt_find_idlest(struct clk_hw_omap *clk,
+		void __iomem **idlest_reg, u8 *idlest_bit, u8 *idlest_val)
 {
 	u32 r;
 
@@ -252,16 +271,44 @@
 
 }
 
-int omap2_dflt_clk_enable(struct clk *clk)
+/**
+ * omap2_dflt_clk_enable - enable a clock in the hardware
+ * @hw: struct clk_hw * of the clock to enable
+ *
+ * Enable the clock @hw in the hardware.  We first call into the OMAP
+ * clockdomain code to "enable" the corresponding clockdomain if this
+ * is the first enabled user of the clockdomain.  Then program the
+ * hardware to enable the clock.  Then wait for the IP block that uses
+ * this clock to leave idle (if applicable).  Returns the error value
+ * from clkdm_clk_enable() if it terminated with an error, or -EINVAL
+ * if @hw has a null clock enable_reg, or zero upon success.
+ */
+int omap2_dflt_clk_enable(struct clk_hw *hw)
 {
+	struct clk_hw_omap *clk;
 	u32 v;
+	int ret = 0;
 
-	if (unlikely(clk->enable_reg == NULL)) {
-		pr_err("clock.c: Enable for %s without enable code\n",
-		       clk->name);
-		return 0; /* REVISIT: -EINVAL */
+	clk = to_clk_hw_omap(hw);
+
+	if (clkdm_control && clk->clkdm) {
+		ret = clkdm_clk_enable(clk->clkdm, hw->clk);
+		if (ret) {
+			WARN(1, "%s: could not enable %s's clockdomain %s: %d\n",
+			     __func__, __clk_get_name(hw->clk),
+			     clk->clkdm->name, ret);
+			return ret;
+		}
 	}
 
+	if (unlikely(clk->enable_reg == NULL)) {
+		pr_err("%s: %s missing enable_reg\n", __func__,
+		       __clk_get_name(hw->clk));
+		ret = -EINVAL;
+		goto err;
+	}
+
+	/* FIXME should not have INVERT_ENABLE bit here */
 	v = __raw_readl(clk->enable_reg);
 	if (clk->flags & INVERT_ENABLE)
 		v &= ~(1 << clk->enable_bit);
@@ -270,22 +317,39 @@
 	__raw_writel(v, clk->enable_reg);
 	v = __raw_readl(clk->enable_reg); /* OCP barrier */
 
-	if (clk->ops->find_idlest)
+	if (clk->ops && clk->ops->find_idlest)
 		_omap2_module_wait_ready(clk);
 
 	return 0;
+
+err:
+	if (clkdm_control && clk->clkdm)
+		clkdm_clk_disable(clk->clkdm, hw->clk);
+	return ret;
 }
 
-void omap2_dflt_clk_disable(struct clk *clk)
+/**
+ * omap2_dflt_clk_disable - disable a clock in the hardware
+ * @hw: struct clk_hw * of the clock to disable
+ *
+ * Disable the clock @hw in the hardware, and call into the OMAP
+ * clockdomain code to "disable" the corresponding clockdomain if all
+ * clocks/hwmods in that clockdomain are now disabled.  No return
+ * value.
+ */
+void omap2_dflt_clk_disable(struct clk_hw *hw)
 {
+	struct clk_hw_omap *clk;
 	u32 v;
 
+	clk = to_clk_hw_omap(hw);
 	if (!clk->enable_reg) {
 		/*
-		 * 'Independent' here refers to a clock which is not
+		 * 'independent' here refers to a clock which is not
 		 * controlled by its parent.
 		 */
-		pr_err("clock: clk_disable called on independent clock %s which has no enable_reg\n", clk->name);
+		pr_err("%s: independent clock %s has no enable_reg\n",
+		       __func__, __clk_get_name(hw->clk));
 		return;
 	}
 
@@ -296,191 +360,213 @@
 		v &= ~(1 << clk->enable_bit);
 	__raw_writel(v, clk->enable_reg);
 	/* No OCP barrier needed here since it is a disable operation */
-}
-
-const struct clkops clkops_omap2_dflt_wait = {
-	.enable		= omap2_dflt_clk_enable,
-	.disable	= omap2_dflt_clk_disable,
-	.find_companion	= omap2_clk_dflt_find_companion,
-	.find_idlest	= omap2_clk_dflt_find_idlest,
-};
-
-const struct clkops clkops_omap2_dflt = {
-	.enable		= omap2_dflt_clk_enable,
-	.disable	= omap2_dflt_clk_disable,
-};
-
-/**
- * omap2_clk_disable - disable a clock, if the system is not using it
- * @clk: struct clk * to disable
- *
- * Decrements the usecount on struct clk @clk.  If there are no users
- * left, call the clkops-specific clock disable function to disable it
- * in hardware.  If the clock is part of a clockdomain (which they all
- * should be), request that the clockdomain be disabled.  (It too has
- * a usecount, and so will not be disabled in the hardware until it no
- * longer has any users.)  If the clock has a parent clock (most of
- * them do), then call ourselves, recursing on the parent clock.  This
- * can cause an entire branch of the clock tree to be powered off by
- * simply disabling one clock.  Intended to be called with the clockfw_lock
- * spinlock held.  No return value.
- */
-void omap2_clk_disable(struct clk *clk)
-{
-	if (clk->usecount == 0) {
-		WARN(1, "clock: %s: omap2_clk_disable() called, but usecount already 0?", clk->name);
-		return;
-	}
-
-	pr_debug("clock: %s: decrementing usecount\n", clk->name);
-
-	clk->usecount--;
-
-	if (clk->usecount > 0)
-		return;
-
-	pr_debug("clock: %s: disabling in hardware\n", clk->name);
-
-	if (clk->ops && clk->ops->disable) {
-		trace_clock_disable(clk->name, 0, smp_processor_id());
-		clk->ops->disable(clk);
-	}
 
 	if (clkdm_control && clk->clkdm)
-		clkdm_clk_disable(clk->clkdm, clk);
-
-	if (clk->parent)
-		omap2_clk_disable(clk->parent);
+		clkdm_clk_disable(clk->clkdm, hw->clk);
 }
 
 /**
- * omap2_clk_enable - request that the system enable a clock
- * @clk: struct clk * to enable
+ * omap2_clkops_enable_clkdm - increment usecount on clkdm of @hw
+ * @hw: struct clk_hw * of the clock being enabled
  *
- * Increments the usecount on struct clk @clk.  If there were no users
- * previously, then recurse up the clock tree, enabling all of the
- * clock's parents and all of the parent clockdomains, and finally,
- * enabling @clk's clockdomain, and @clk itself.  Intended to be
- * called with the clockfw_lock spinlock held.  Returns 0 upon success
- * or a negative error code upon failure.
+ * Increment the usecount of the clockdomain of the clock pointed to
+ * by @hw; if the usecount is 1, the clockdomain will be "enabled."
+ * Only needed for clocks that don't use omap2_dflt_clk_enable() as
+ * their enable function pointer.  Passes along the return value of
+ * clkdm_clk_enable(), -EINVAL if @hw is not associated with a
+ * clockdomain, or 0 if clock framework-based clockdomain control is
+ * not implemented.
  */
-int omap2_clk_enable(struct clk *clk)
+int omap2_clkops_enable_clkdm(struct clk_hw *hw)
 {
-	int ret;
+	struct clk_hw_omap *clk;
+	int ret = 0;
 
-	pr_debug("clock: %s: incrementing usecount\n", clk->name);
+	clk = to_clk_hw_omap(hw);
 
-	clk->usecount++;
-
-	if (clk->usecount > 1)
-		return 0;
-
-	pr_debug("clock: %s: enabling in hardware\n", clk->name);
-
-	if (clk->parent) {
-		ret = omap2_clk_enable(clk->parent);
-		if (ret) {
-			WARN(1, "clock: %s: could not enable parent %s: %d\n",
-			     clk->name, clk->parent->name, ret);
-			goto oce_err1;
-		}
-	}
-
-	if (clkdm_control && clk->clkdm) {
-		ret = clkdm_clk_enable(clk->clkdm, clk);
-		if (ret) {
-			WARN(1, "clock: %s: could not enable clockdomain %s: %d\n",
-			     clk->name, clk->clkdm->name, ret);
-			goto oce_err2;
-		}
-	}
-
-	if (clk->ops && clk->ops->enable) {
-		trace_clock_enable(clk->name, 1, smp_processor_id());
-		ret = clk->ops->enable(clk);
-		if (ret) {
-			WARN(1, "clock: %s: could not enable: %d\n",
-			     clk->name, ret);
-			goto oce_err3;
-		}
-	}
-
-	return 0;
-
-oce_err3:
-	if (clkdm_control && clk->clkdm)
-		clkdm_clk_disable(clk->clkdm, clk);
-oce_err2:
-	if (clk->parent)
-		omap2_clk_disable(clk->parent);
-oce_err1:
-	clk->usecount--;
-
-	return ret;
-}
-
-/* Given a clock and a rate apply a clock specific rounding function */
-long omap2_clk_round_rate(struct clk *clk, unsigned long rate)
-{
-	if (clk->round_rate)
-		return clk->round_rate(clk, rate);
-
-	return clk->rate;
-}
-
-/* Set the clock rate for a clock source */
-int omap2_clk_set_rate(struct clk *clk, unsigned long rate)
-{
-	int ret = -EINVAL;
-
-	pr_debug("clock: set_rate for clock %s to rate %ld\n", clk->name, rate);
-
-	/* dpll_ck, core_ck, virt_prcm_set; plus all clksel clocks */
-	if (clk->set_rate) {
-		trace_clock_set_rate(clk->name, rate, smp_processor_id());
-		ret = clk->set_rate(clk, rate);
-	}
-
-	return ret;
-}
-
-int omap2_clk_set_parent(struct clk *clk, struct clk *new_parent)
-{
-	if (!clk->clksel)
+	if (unlikely(!clk->clkdm)) {
+		pr_err("%s: %s: no clkdm set ?!\n", __func__,
+		       __clk_get_name(hw->clk));
 		return -EINVAL;
+	}
 
-	if (clk->parent == new_parent)
+	if (unlikely(clk->enable_reg))
+		pr_err("%s: %s: should use dflt_clk_enable ?!\n", __func__,
+		       __clk_get_name(hw->clk));
+
+	if (!clkdm_control) {
+		pr_err("%s: %s: clkfw-based clockdomain control disabled ?!\n",
+		       __func__, __clk_get_name(hw->clk));
 		return 0;
+	}
 
-	return omap2_clksel_set_parent(clk, new_parent);
+	ret = clkdm_clk_enable(clk->clkdm, hw->clk);
+	WARN(ret, "%s: could not enable %s's clockdomain %s: %d\n",
+	     __func__, __clk_get_name(hw->clk), clk->clkdm->name, ret);
+
+	return ret;
 }
 
+/**
+ * omap2_clkops_disable_clkdm - decrement usecount on clkdm of @hw
+ * @hw: struct clk_hw * of the clock being disabled
+ *
+ * Decrement the usecount of the clockdomain of the clock pointed to
+ * by @hw; if the usecount is 0, the clockdomain will be "disabled."
+ * Only needed for clocks that don't use omap2_dflt_clk_disable() as their
+ * disable function pointer.  No return value.
+ */
+void omap2_clkops_disable_clkdm(struct clk_hw *hw)
+{
+	struct clk_hw_omap *clk;
+
+	clk = to_clk_hw_omap(hw);
+
+	if (unlikely(!clk->clkdm)) {
+		pr_err("%s: %s: no clkdm set ?!\n", __func__,
+		       __clk_get_name(hw->clk));
+		return;
+	}
+
+	if (unlikely(clk->enable_reg))
+		pr_err("%s: %s: should use dflt_clk_disable ?!\n", __func__,
+		       __clk_get_name(hw->clk));
+
+	if (!clkdm_control) {
+		pr_err("%s: %s: clkfw-based clockdomain control disabled ?!\n",
+		       __func__, __clk_get_name(hw->clk));
+		return;
+	}
+
+	clkdm_clk_disable(clk->clkdm, hw->clk);
+}
+
+/**
+ * omap2_dflt_clk_is_enabled - is clock enabled in the hardware?
+ * @hw: struct clk_hw * to check
+ *
+ * Return 1 if the clock represented by @hw is enabled in the
+ * hardware, or 0 otherwise.  Intended for use in the struct
+ * clk_ops.is_enabled function pointer.
+ */
+int omap2_dflt_clk_is_enabled(struct clk_hw *hw)
+{
+	struct clk_hw_omap *clk = to_clk_hw_omap(hw);
+	u32 v;
+
+	v = __raw_readl(clk->enable_reg);
+
+	if (clk->flags & INVERT_ENABLE)
+		v ^= BIT(clk->enable_bit);
+
+	v &= BIT(clk->enable_bit);
+
+	return v ? 1 : 0;
+}
+
+static int __initdata mpurate;
+
 /*
- * OMAP2+ clock reset and init functions
+ * By default we use the rate set by the bootloader.
+ * You can override this with mpurate= cmdline option.
  */
-
-#ifdef CONFIG_OMAP_RESET_CLOCKS
-void omap2_clk_disable_unused(struct clk *clk)
+static int __init omap_clk_setup(char *str)
 {
-	u32 regval32, v;
+	get_option(&str, &mpurate);
 
-	v = (clk->flags & INVERT_ENABLE) ? (1 << clk->enable_bit) : 0;
+	if (!mpurate)
+		return 1;
 
-	regval32 = __raw_readl(clk->enable_reg);
-	if ((regval32 & (1 << clk->enable_bit)) == v)
+	if (mpurate < 1000)
+		mpurate *= 1000000;
+
+	return 1;
+}
+__setup("mpurate=", omap_clk_setup);
+
+/**
+ * omap2_init_clk_hw_omap_clocks - initialize an OMAP clock
+ * @clk: struct clk * to initialize
+ *
+ * Add an OMAP clock @clk to the internal list of OMAP clocks.  Used
+ * temporarily for autoidle handling, until this support can be
+ * integrated into the common clock framework code in some way.  No
+ * return value.
+ */
+void omap2_init_clk_hw_omap_clocks(struct clk *clk)
+{
+	struct clk_hw_omap *c;
+
+	if (__clk_get_flags(clk) & CLK_IS_BASIC)
 		return;
 
-	pr_debug("Disabling unused clock \"%s\"\n", clk->name);
-	if (cpu_is_omap34xx()) {
-		omap2_clk_enable(clk);
-		omap2_clk_disable(clk);
-	} else {
-		clk->ops->disable(clk);
-	}
-	if (clk->clkdm != NULL)
-		pwrdm_state_switch(clk->clkdm->pwrdm.ptr);
+	c = to_clk_hw_omap(__clk_get_hw(clk));
+	list_add(&c->node, &clk_hw_omap_clocks);
 }
-#endif
+
+/**
+ * omap2_clk_enable_autoidle_all - enable autoidle on all OMAP clocks that
+ * support it
+ *
+ * Enable clock autoidle on all OMAP clocks that have allow_idle
+ * function pointers associated with them.  This function is intended
+ * to be temporary until support for this is added to the common clock
+ * code.  Returns 0.
+ */
+int omap2_clk_enable_autoidle_all(void)
+{
+	struct clk_hw_omap *c;
+
+	list_for_each_entry(c, &clk_hw_omap_clocks, node)
+		if (c->ops && c->ops->allow_idle)
+			c->ops->allow_idle(c);
+	return 0;
+}
+
+/**
+ * omap2_clk_disable_autoidle_all - disable autoidle on all OMAP clocks that
+ * support it
+ *
+ * Disable clock autoidle on all OMAP clocks that have allow_idle
+ * function pointers associated with them.  This function is intended
+ * to be temporary until support for this is added to the common clock
+ * code.  Returns 0.
+ */
+int omap2_clk_disable_autoidle_all(void)
+{
+	struct clk_hw_omap *c;
+
+	list_for_each_entry(c, &clk_hw_omap_clocks, node)
+		if (c->ops && c->ops->deny_idle)
+			c->ops->deny_idle(c);
+	return 0;
+}
+
+/**
+ * omap2_clk_enable_init_clocks - prepare & enable a list of clocks
+ * @clk_names: ptr to an array of strings of clock names to enable
+ * @num_clocks: number of clock names in @clk_names
+ *
+ * Prepare and enable a list of clocks, named by @clk_names.  No
+ * return value. XXX Deprecated; only needed until these clocks are
+ * properly claimed and enabled by the drivers or core code that uses
+ * them.  XXX What code disables & calls clk_put on these clocks?
+ */
+void omap2_clk_enable_init_clocks(const char **clk_names, u8 num_clocks)
+{
+	struct clk *init_clk;
+	int i;
+
+	for (i = 0; i < num_clocks; i++) {
+		init_clk = clk_get(NULL, clk_names[i]);
+		clk_prepare_enable(init_clk);
+	}
+}
+
+const struct clk_hw_omap_ops clkhwops_wait = {
+	.find_idlest	= omap2_clk_dflt_find_idlest,
+	.find_companion	= omap2_clk_dflt_find_companion,
+};
 
 /**
  * omap2_clk_switch_mpurate_at_boot - switch ARM MPU rate by boot-time argument
@@ -512,14 +598,12 @@
 	r = clk_set_rate(mpurate_ck, mpurate);
 	if (IS_ERR_VALUE(r)) {
 		WARN(1, "clock: %s: unable to set MPU rate to %d: %d\n",
-		     mpurate_ck->name, mpurate, r);
+		     mpurate_ck_name, mpurate, r);
 		clk_put(mpurate_ck);
 		return -EINVAL;
 	}
 
 	calibrate_delay();
-	recalculate_root_clocks();
-
 	clk_put(mpurate_ck);
 
 	return 0;
@@ -563,513 +647,3 @@
 		(clk_get_rate(core_ck) / 1000000),
 		(clk_get_rate(mpu_ck) / 1000000));
 }
-
-/* Common data */
-
-int clk_enable(struct clk *clk)
-{
-	unsigned long flags;
-	int ret;
-
-	if (clk == NULL || IS_ERR(clk))
-		return -EINVAL;
-
-	spin_lock_irqsave(&clockfw_lock, flags);
-	ret = omap2_clk_enable(clk);
-	spin_unlock_irqrestore(&clockfw_lock, flags);
-
-	return ret;
-}
-EXPORT_SYMBOL(clk_enable);
-
-void clk_disable(struct clk *clk)
-{
-	unsigned long flags;
-
-	if (clk == NULL || IS_ERR(clk))
-		return;
-
-	spin_lock_irqsave(&clockfw_lock, flags);
-	if (clk->usecount == 0) {
-		pr_err("Trying disable clock %s with 0 usecount\n",
-		       clk->name);
-		WARN_ON(1);
-		goto out;
-	}
-
-	omap2_clk_disable(clk);
-
-out:
-	spin_unlock_irqrestore(&clockfw_lock, flags);
-}
-EXPORT_SYMBOL(clk_disable);
-
-unsigned long clk_get_rate(struct clk *clk)
-{
-	unsigned long flags;
-	unsigned long ret;
-
-	if (clk == NULL || IS_ERR(clk))
-		return 0;
-
-	spin_lock_irqsave(&clockfw_lock, flags);
-	ret = clk->rate;
-	spin_unlock_irqrestore(&clockfw_lock, flags);
-
-	return ret;
-}
-EXPORT_SYMBOL(clk_get_rate);
-
-/*
- * Optional clock functions defined in include/linux/clk.h
- */
-
-long clk_round_rate(struct clk *clk, unsigned long rate)
-{
-	unsigned long flags;
-	long ret;
-
-	if (clk == NULL || IS_ERR(clk))
-		return 0;
-
-	spin_lock_irqsave(&clockfw_lock, flags);
-	ret = omap2_clk_round_rate(clk, rate);
-	spin_unlock_irqrestore(&clockfw_lock, flags);
-
-	return ret;
-}
-EXPORT_SYMBOL(clk_round_rate);
-
-int clk_set_rate(struct clk *clk, unsigned long rate)
-{
-	unsigned long flags;
-	int ret = -EINVAL;
-
-	if (clk == NULL || IS_ERR(clk))
-		return ret;
-
-	spin_lock_irqsave(&clockfw_lock, flags);
-	ret = omap2_clk_set_rate(clk, rate);
-	if (ret == 0)
-		propagate_rate(clk);
-	spin_unlock_irqrestore(&clockfw_lock, flags);
-
-	return ret;
-}
-EXPORT_SYMBOL(clk_set_rate);
-
-int clk_set_parent(struct clk *clk, struct clk *parent)
-{
-	unsigned long flags;
-	int ret = -EINVAL;
-
-	if (clk == NULL || IS_ERR(clk) || parent == NULL || IS_ERR(parent))
-		return ret;
-
-	spin_lock_irqsave(&clockfw_lock, flags);
-	if (clk->usecount == 0) {
-		ret = omap2_clk_set_parent(clk, parent);
-		if (ret == 0)
-			propagate_rate(clk);
-	} else {
-		ret = -EBUSY;
-	}
-	spin_unlock_irqrestore(&clockfw_lock, flags);
-
-	return ret;
-}
-EXPORT_SYMBOL(clk_set_parent);
-
-struct clk *clk_get_parent(struct clk *clk)
-{
-	return clk->parent;
-}
-EXPORT_SYMBOL(clk_get_parent);
-
-/*
- * OMAP specific clock functions shared between omap1 and omap2
- */
-
-int __initdata mpurate;
-
-/*
- * By default we use the rate set by the bootloader.
- * You can override this with mpurate= cmdline option.
- */
-static int __init omap_clk_setup(char *str)
-{
-	get_option(&str, &mpurate);
-
-	if (!mpurate)
-		return 1;
-
-	if (mpurate < 1000)
-		mpurate *= 1000000;
-
-	return 1;
-}
-__setup("mpurate=", omap_clk_setup);
-
-/* Used for clocks that always have same value as the parent clock */
-unsigned long followparent_recalc(struct clk *clk)
-{
-	return clk->parent->rate;
-}
-
-/*
- * Used for clocks that have the same value as the parent clock,
- * divided by some factor
- */
-unsigned long omap_fixed_divisor_recalc(struct clk *clk)
-{
-	WARN_ON(!clk->fixed_div);
-
-	return clk->parent->rate / clk->fixed_div;
-}
-
-void clk_reparent(struct clk *child, struct clk *parent)
-{
-	list_del_init(&child->sibling);
-	if (parent)
-		list_add(&child->sibling, &parent->children);
-	child->parent = parent;
-
-	/* now do the debugfs renaming to reattach the child
-	   to the proper parent */
-}
-
-/* Propagate rate to children */
-void propagate_rate(struct clk *tclk)
-{
-	struct clk *clkp;
-
-	list_for_each_entry(clkp, &tclk->children, sibling) {
-		if (clkp->recalc)
-			clkp->rate = clkp->recalc(clkp);
-		propagate_rate(clkp);
-	}
-}
-
-static LIST_HEAD(root_clks);
-
-/**
- * recalculate_root_clocks - recalculate and propagate all root clocks
- *
- * Recalculates all root clocks (clocks with no parent), which if the
- * clock's .recalc is set correctly, should also propagate their rates.
- * Called at init.
- */
-void recalculate_root_clocks(void)
-{
-	struct clk *clkp;
-
-	list_for_each_entry(clkp, &root_clks, sibling) {
-		if (clkp->recalc)
-			clkp->rate = clkp->recalc(clkp);
-		propagate_rate(clkp);
-	}
-}
-
-/**
- * clk_preinit - initialize any fields in the struct clk before clk init
- * @clk: struct clk * to initialize
- *
- * Initialize any struct clk fields needed before normal clk initialization
- * can run.  No return value.
- */
-void clk_preinit(struct clk *clk)
-{
-	INIT_LIST_HEAD(&clk->children);
-}
-
-int clk_register(struct clk *clk)
-{
-	if (clk == NULL || IS_ERR(clk))
-		return -EINVAL;
-
-	/*
-	 * trap out already registered clocks
-	 */
-	if (clk->node.next || clk->node.prev)
-		return 0;
-
-	mutex_lock(&clocks_mutex);
-	if (clk->parent)
-		list_add(&clk->sibling, &clk->parent->children);
-	else
-		list_add(&clk->sibling, &root_clks);
-
-	list_add(&clk->node, &clocks);
-	if (clk->init)
-		clk->init(clk);
-	mutex_unlock(&clocks_mutex);
-
-	return 0;
-}
-EXPORT_SYMBOL(clk_register);
-
-void clk_unregister(struct clk *clk)
-{
-	if (clk == NULL || IS_ERR(clk))
-		return;
-
-	mutex_lock(&clocks_mutex);
-	list_del(&clk->sibling);
-	list_del(&clk->node);
-	mutex_unlock(&clocks_mutex);
-}
-EXPORT_SYMBOL(clk_unregister);
-
-void clk_enable_init_clocks(void)
-{
-	struct clk *clkp;
-
-	list_for_each_entry(clkp, &clocks, node)
-		if (clkp->flags & ENABLE_ON_INIT)
-			clk_enable(clkp);
-}
-
-/**
- * omap_clk_get_by_name - locate OMAP struct clk by its name
- * @name: name of the struct clk to locate
- *
- * Locate an OMAP struct clk by its name.  Assumes that struct clk
- * names are unique.  Returns NULL if not found or a pointer to the
- * struct clk if found.
- */
-struct clk *omap_clk_get_by_name(const char *name)
-{
-	struct clk *c;
-	struct clk *ret = NULL;
-
-	mutex_lock(&clocks_mutex);
-
-	list_for_each_entry(c, &clocks, node) {
-		if (!strcmp(c->name, name)) {
-			ret = c;
-			break;
-		}
-	}
-
-	mutex_unlock(&clocks_mutex);
-
-	return ret;
-}
-
-int omap_clk_enable_autoidle_all(void)
-{
-	struct clk *c;
-	unsigned long flags;
-
-	spin_lock_irqsave(&clockfw_lock, flags);
-
-	list_for_each_entry(c, &clocks, node)
-		if (c->ops->allow_idle)
-			c->ops->allow_idle(c);
-
-	spin_unlock_irqrestore(&clockfw_lock, flags);
-
-	return 0;
-}
-
-int omap_clk_disable_autoidle_all(void)
-{
-	struct clk *c;
-	unsigned long flags;
-
-	spin_lock_irqsave(&clockfw_lock, flags);
-
-	list_for_each_entry(c, &clocks, node)
-		if (c->ops->deny_idle)
-			c->ops->deny_idle(c);
-
-	spin_unlock_irqrestore(&clockfw_lock, flags);
-
-	return 0;
-}
-
-/*
- * Low level helpers
- */
-static int clkll_enable_null(struct clk *clk)
-{
-	return 0;
-}
-
-static void clkll_disable_null(struct clk *clk)
-{
-}
-
-const struct clkops clkops_null = {
-	.enable		= clkll_enable_null,
-	.disable	= clkll_disable_null,
-};
-
-/*
- * Dummy clock
- *
- * Used for clock aliases that are needed on some OMAPs, but not others
- */
-struct clk dummy_ck = {
-	.name	= "dummy",
-	.ops	= &clkops_null,
-};
-
-/*
- *
- */
-
-#ifdef CONFIG_OMAP_RESET_CLOCKS
-/*
- * Disable any unused clocks left on by the bootloader
- */
-static int __init clk_disable_unused(void)
-{
-	struct clk *ck;
-	unsigned long flags;
-
-	pr_info("clock: disabling unused clocks to save power\n");
-
-	spin_lock_irqsave(&clockfw_lock, flags);
-	list_for_each_entry(ck, &clocks, node) {
-		if (ck->ops == &clkops_null)
-			continue;
-
-		if (ck->usecount > 0 || !ck->enable_reg)
-			continue;
-
-		omap2_clk_disable_unused(ck);
-	}
-	spin_unlock_irqrestore(&clockfw_lock, flags);
-
-	return 0;
-}
-late_initcall(clk_disable_unused);
-late_initcall(omap_clk_enable_autoidle_all);
-#endif
-
-#if defined(CONFIG_PM_DEBUG) && defined(CONFIG_DEBUG_FS)
-/*
- *	debugfs support to trace clock tree hierarchy and attributes
- */
-
-#include <linux/debugfs.h>
-#include <linux/seq_file.h>
-
-static struct dentry *clk_debugfs_root;
-
-static int clk_dbg_show_summary(struct seq_file *s, void *unused)
-{
-	struct clk *c;
-	struct clk *pa;
-
-	mutex_lock(&clocks_mutex);
-	seq_printf(s, "%-30s %-30s %-10s %s\n",
-		   "clock-name", "parent-name", "rate", "use-count");
-
-	list_for_each_entry(c, &clocks, node) {
-		pa = c->parent;
-		seq_printf(s, "%-30s %-30s %-10lu %d\n",
-			   c->name, pa ? pa->name : "none", c->rate,
-			   c->usecount);
-	}
-	mutex_unlock(&clocks_mutex);
-
-	return 0;
-}
-
-static int clk_dbg_open(struct inode *inode, struct file *file)
-{
-	return single_open(file, clk_dbg_show_summary, inode->i_private);
-}
-
-static const struct file_operations debug_clock_fops = {
-	.open           = clk_dbg_open,
-	.read           = seq_read,
-	.llseek         = seq_lseek,
-	.release        = single_release,
-};
-
-static int clk_debugfs_register_one(struct clk *c)
-{
-	int err;
-	struct dentry *d;
-	struct clk *pa = c->parent;
-
-	d = debugfs_create_dir(c->name, pa ? pa->dent : clk_debugfs_root);
-	if (!d)
-		return -ENOMEM;
-	c->dent = d;
-
-	d = debugfs_create_u8("usecount", S_IRUGO, c->dent, (u8 *)&c->usecount);
-	if (!d) {
-		err = -ENOMEM;
-		goto err_out;
-	}
-	d = debugfs_create_u32("rate", S_IRUGO, c->dent, (u32 *)&c->rate);
-	if (!d) {
-		err = -ENOMEM;
-		goto err_out;
-	}
-	d = debugfs_create_x32("flags", S_IRUGO, c->dent, (u32 *)&c->flags);
-	if (!d) {
-		err = -ENOMEM;
-		goto err_out;
-	}
-	return 0;
-
-err_out:
-	debugfs_remove_recursive(c->dent);
-	return err;
-}
-
-static int clk_debugfs_register(struct clk *c)
-{
-	int err;
-	struct clk *pa = c->parent;
-
-	if (pa && !pa->dent) {
-		err = clk_debugfs_register(pa);
-		if (err)
-			return err;
-	}
-
-	if (!c->dent) {
-		err = clk_debugfs_register_one(c);
-		if (err)
-			return err;
-	}
-	return 0;
-}
-
-static int __init clk_debugfs_init(void)
-{
-	struct clk *c;
-	struct dentry *d;
-	int err;
-
-	d = debugfs_create_dir("clock", NULL);
-	if (!d)
-		return -ENOMEM;
-	clk_debugfs_root = d;
-
-	list_for_each_entry(c, &clocks, node) {
-		err = clk_debugfs_register(c);
-		if (err)
-			goto err_out;
-	}
-
-	d = debugfs_create_file("summary", S_IRUGO,
-		d, NULL, &debug_clock_fops);
-	if (!d)
-		return -ENOMEM;
-
-	return 0;
-err_out:
-	debugfs_remove_recursive(clk_debugfs_root);
-	return err;
-}
-late_initcall(clk_debugfs_init);
-
-#endif /* defined(CONFIG_PM_DEBUG) && defined(CONFIG_DEBUG_FS) */
-
diff --git a/arch/arm/mach-omap2/clock.h b/arch/arm/mach-omap2/clock.h
index ff9789b..9917f79 100644
--- a/arch/arm/mach-omap2/clock.h
+++ b/arch/arm/mach-omap2/clock.h
@@ -20,6 +20,7 @@
 #include <linux/list.h>
 
 #include <linux/clkdev.h>
+#include <linux/clk-provider.h>
 
 struct omap_clk {
 	u16				cpu;
@@ -52,43 +53,84 @@
 #define CK_34XX		(CK_3430ES1 | CK_3430ES2PLUS)
 #define CK_3XXX		(CK_34XX | CK_AM35XX | CK_36XX)
 
-struct module;
-struct clk;
 struct clockdomain;
+#define to_clk_hw_omap(_hw) container_of(_hw, struct clk_hw_omap, hw)
 
-/* Temporary, needed during the common clock framework conversion */
-#define __clk_get_name(clk)	(clk->name)
-#define __clk_get_parent(clk)	(clk->parent)
-#define __clk_get_rate(clk)	(clk->rate)
+#define DEFINE_STRUCT_CLK(_name, _parent_array_name, _clkops_name)	\
+	static struct clk _name = {				\
+		.name = #_name,					\
+		.hw = &_name##_hw.hw,				\
+		.parent_names = _parent_array_name,		\
+		.num_parents = ARRAY_SIZE(_parent_array_name),	\
+		.ops = &_clkops_name,				\
+	};
 
-/**
- * struct clkops - some clock function pointers
- * @enable: fn ptr that enables the current clock in hardware
- * @disable: fn ptr that enables the current clock in hardware
- * @find_idlest: function returning the IDLEST register for the clock's IP blk
- * @find_companion: function returning the "companion" clk reg for the clock
- * @allow_idle: fn ptr that enables autoidle for the current clock in hardware
- * @deny_idle: fn ptr that disables autoidle for the current clock in hardware
- *
- * A "companion" clk is an accompanying clock to the one being queried
- * that must be enabled for the IP module connected to the clock to
- * become accessible by the hardware.  Neither @find_idlest nor
- * @find_companion should be needed; that information is IP
- * block-specific; the hwmod code has been created to handle this, but
- * until hwmod data is ready and drivers have been converted to use PM
- * runtime calls in place of clk_enable()/clk_disable(), @find_idlest and
- * @find_companion must, unfortunately, remain.
- */
-struct clkops {
-	int			(*enable)(struct clk *);
-	void			(*disable)(struct clk *);
-	void			(*find_idlest)(struct clk *, void __iomem **,
-					       u8 *, u8 *);
-	void			(*find_companion)(struct clk *, void __iomem **,
-						  u8 *);
-	void			(*allow_idle)(struct clk *);
-	void			(*deny_idle)(struct clk *);
-};
+#define DEFINE_STRUCT_CLK_HW_OMAP(_name, _clkdm_name)		\
+	static struct clk_hw_omap _name##_hw = {		\
+		.hw = {						\
+			.clk = &_name,				\
+		},						\
+		.clkdm_name = _clkdm_name,			\
+	};
+
+#define DEFINE_CLK_OMAP_MUX(_name, _clkdm_name, _clksel,	\
+			    _clksel_reg, _clksel_mask,		\
+			    _parent_names, _ops)		\
+	static struct clk _name;				\
+	static struct clk_hw_omap _name##_hw = {		\
+		.hw = {						\
+			.clk = &_name,				\
+		},						\
+		.clksel		= _clksel,			\
+		.clksel_reg	= _clksel_reg,			\
+		.clksel_mask	= _clksel_mask,			\
+		.clkdm_name	= _clkdm_name,			\
+	};							\
+	DEFINE_STRUCT_CLK(_name, _parent_names, _ops);
+
+#define DEFINE_CLK_OMAP_MUX_GATE(_name, _clkdm_name, _clksel,	\
+				 _clksel_reg, _clksel_mask,	\
+				 _enable_reg, _enable_bit,	\
+				 _hwops, _parent_names, _ops)	\
+	static struct clk _name;				\
+	static struct clk_hw_omap _name##_hw = {		\
+		.hw = {						\
+			.clk = &_name,				\
+		},						\
+		.ops		= _hwops,			\
+		.enable_reg	= _enable_reg,			\
+		.enable_bit	= _enable_bit,			\
+		.clksel		= _clksel,			\
+		.clksel_reg	= _clksel_reg,			\
+		.clksel_mask	= _clksel_mask,			\
+		.clkdm_name	= _clkdm_name,			\
+	};							\
+	DEFINE_STRUCT_CLK(_name, _parent_names, _ops);
+
+#define DEFINE_CLK_OMAP_HSDIVIDER(_name, _parent_name,		\
+				_parent_ptr, _flags,		\
+				_clksel_reg, _clksel_mask)	\
+	static const struct clksel _name##_div[] = {		\
+		{						\
+			.parent = _parent_ptr,			\
+			.rates = div31_1to31_rates		\
+		},						\
+		{ .parent = NULL },				\
+	};							\
+	static struct clk _name;				\
+	static const char *_name##_parent_names[] = {		\
+		_parent_name,					\
+	};							\
+	static struct clk_hw_omap _name##_hw = {		\
+		.hw = {						\
+			.clk = &_name,				\
+		},						\
+		.clksel		= _name##_div,			\
+		.clksel_reg	= _clksel_reg,			\
+		.clksel_mask	= _clksel_mask,			\
+		.ops		= &clkhwops_omap4_dpllmx,	\
+	};							\
+	DEFINE_STRUCT_CLK(_name, _name##_parent_names, omap_hsdivider_ops);
 
 /* struct clksel_rate.flags possibilities */
 #define RATE_IN_242X		(1 << 0)
@@ -229,22 +271,10 @@
 #define CLOCK_CLKOUTX2		(1 << 5)
 
 /**
- * struct clk - OMAP struct clk
+ * struct clk_hw_omap - OMAP struct clk
  * @node: list_head connecting this clock into the full clock list
- * @ops: struct clkops * for this clock
- * @name: the name of the clock in the hardware (used in hwmod data and debug)
- * @parent: pointer to this clock's parent struct clk
- * @children: list_head connecting to the child clks' @sibling list_heads
- * @sibling: list_head connecting this clk to its parent clk's @children
- * @rate: current clock rate
  * @enable_reg: register to write to enable the clock (see @enable_bit)
- * @recalc: fn ptr that returns the clock's current rate
- * @set_rate: fn ptr that can change the clock's current rate
- * @round_rate: fn ptr that can round the clock's current rate
- * @init: fn ptr to do clock-specific initialization
  * @enable_bit: bitshift to write to enable/disable the clock (see @enable_reg)
- * @usecount: number of users that have requested this clock to be enabled
- * @fixed_div: when > 0, this clock's rate is its parent's rate / @fixed_div
  * @flags: see "struct clk.flags possibilities" above
  * @clksel_reg: for clksel clks, register va containing src/divisor select
  * @clksel_mask: bitmask in @clksel_reg for the src/divisor selector
@@ -258,39 +288,17 @@
  * XXX @rate_offset, @src_offset should probably be removed and OMAP1
  * clock code converted to use clksel.
  *
- * XXX @usecount is poorly named.  It should be "enable_count" or
- * something similar.  "users" in the description refers to kernel
- * code (core code or drivers) that have called clk_enable() and not
- * yet called clk_disable(); the usecount of parent clocks is also
- * incremented by the clock code when clk_enable() is called on child
- * clocks and decremented by the clock code when clk_disable() is
- * called on child clocks.
- *
- * XXX @clkdm, @usecount, @children, @sibling should be marked for
- * internal use only.
- *
- * @children and @sibling are used to optimize parent-to-child clock
- * tree traversals.  (child-to-parent traversals use @parent.)
- *
- * XXX The notion of the clock's current rate probably needs to be
- * separated from the clock's target rate.
  */
-struct clk {
+
+struct clk_hw_omap_ops;
+
+struct clk_hw_omap {
+	struct clk_hw		hw;
 	struct list_head	node;
-	const struct clkops	*ops;
-	const char		*name;
-	struct clk		*parent;
-	struct list_head	children;
-	struct list_head	sibling;	/* node for children */
-	unsigned long		rate;
-	void __iomem		*enable_reg;
-	unsigned long		(*recalc)(struct clk *);
-	int			(*set_rate)(struct clk *, unsigned long);
-	long			(*round_rate)(struct clk *, unsigned long);
-	void			(*init)(struct clk *);
-	u8			enable_bit;
-	s8			usecount;
+	unsigned long		fixed_rate;
 	u8			fixed_div;
+	void __iomem		*enable_reg;
+	u8			enable_bit;
 	u8			flags;
 	void __iomem		*clksel_reg;
 	u32			clksel_mask;
@@ -298,42 +306,22 @@
 	struct dpll_data	*dpll_data;
 	const char		*clkdm_name;
 	struct clockdomain	*clkdm;
-#if defined(CONFIG_PM_DEBUG) && defined(CONFIG_DEBUG_FS)
-	struct dentry		*dent;	/* For visible tree hierarchy */
-#endif
+	const struct clk_hw_omap_ops	*ops;
 };
 
-struct clk_functions {
-	int		(*clk_enable)(struct clk *clk);
-	void		(*clk_disable)(struct clk *clk);
-	long		(*clk_round_rate)(struct clk *clk, unsigned long rate);
-	int		(*clk_set_rate)(struct clk *clk, unsigned long rate);
-	int		(*clk_set_parent)(struct clk *clk, struct clk *parent);
-	void		(*clk_allow_idle)(struct clk *clk);
-	void		(*clk_deny_idle)(struct clk *clk);
-	void		(*clk_disable_unused)(struct clk *clk);
+struct clk_hw_omap_ops {
+	void			(*find_idlest)(struct clk_hw_omap *oclk,
+					void __iomem **idlest_reg,
+					u8 *idlest_bit, u8 *idlest_val);
+	void			(*find_companion)(struct clk_hw_omap *oclk,
+					void __iomem **other_reg,
+					u8 *other_bit);
+	void			(*allow_idle)(struct clk_hw_omap *oclk);
+	void			(*deny_idle)(struct clk_hw_omap *oclk);
 };
 
-extern int mpurate;
-
-extern int clk_init(struct clk_functions *custom_clocks);
-extern void clk_preinit(struct clk *clk);
-extern int clk_register(struct clk *clk);
-extern void clk_reparent(struct clk *child, struct clk *parent);
-extern void clk_unregister(struct clk *clk);
-extern void propagate_rate(struct clk *clk);
-extern void recalculate_root_clocks(void);
-extern unsigned long followparent_recalc(struct clk *clk);
-extern void clk_enable_init_clocks(void);
-unsigned long omap_fixed_divisor_recalc(struct clk *clk);
-extern struct clk *omap_clk_get_by_name(const char *name);
-extern int omap_clk_enable_autoidle_all(void);
-extern int omap_clk_disable_autoidle_all(void);
-
-extern const struct clkops clkops_null;
-
-extern struct clk dummy_ck;
-
+unsigned long omap_fixed_divisor_recalc(struct clk_hw *hw,
+					unsigned long parent_rate);
 
 /* CM_CLKSEL2_PLL.CORE_CLK_SRC bits (2XXX) */
 #define CORE_CLK_SRC_32K		0x0
@@ -364,57 +352,62 @@
 /* DPLL Type and DCO Selection Flags */
 #define DPLL_J_TYPE		0x1
 
-int omap2_clk_enable(struct clk *clk);
-void omap2_clk_disable(struct clk *clk);
-long omap2_clk_round_rate(struct clk *clk, unsigned long rate);
-int omap2_clk_set_rate(struct clk *clk, unsigned long rate);
-int omap2_clk_set_parent(struct clk *clk, struct clk *new_parent);
-long omap2_dpll_round_rate(struct clk *clk, unsigned long target_rate);
-unsigned long omap3_dpll_recalc(struct clk *clk);
-unsigned long omap3_clkoutx2_recalc(struct clk *clk);
-void omap3_dpll_allow_idle(struct clk *clk);
-void omap3_dpll_deny_idle(struct clk *clk);
-u32 omap3_dpll_autoidle_read(struct clk *clk);
-int omap3_noncore_dpll_set_rate(struct clk *clk, unsigned long rate);
-int omap3_noncore_dpll_enable(struct clk *clk);
-void omap3_noncore_dpll_disable(struct clk *clk);
-int omap4_dpllmx_gatectrl_read(struct clk *clk);
-void omap4_dpllmx_allow_gatectrl(struct clk *clk);
-void omap4_dpllmx_deny_gatectrl(struct clk *clk);
-long omap4_dpll_regm4xen_round_rate(struct clk *clk, unsigned long target_rate);
-unsigned long omap4_dpll_regm4xen_recalc(struct clk *clk);
+long omap2_dpll_round_rate(struct clk_hw *hw, unsigned long target_rate,
+			unsigned long *parent_rate);
+unsigned long omap3_dpll_recalc(struct clk_hw *hw, unsigned long parent_rate);
+int omap3_noncore_dpll_enable(struct clk_hw *hw);
+void omap3_noncore_dpll_disable(struct clk_hw *hw);
+int omap3_noncore_dpll_set_rate(struct clk_hw *hw, unsigned long rate,
+				unsigned long parent_rate);
+u32 omap3_dpll_autoidle_read(struct clk_hw_omap *clk);
+void omap3_dpll_allow_idle(struct clk_hw_omap *clk);
+void omap3_dpll_deny_idle(struct clk_hw_omap *clk);
+unsigned long omap3_clkoutx2_recalc(struct clk_hw *hw,
+				    unsigned long parent_rate);
+int omap4_dpllmx_gatectrl_read(struct clk_hw_omap *clk);
+void omap4_dpllmx_allow_gatectrl(struct clk_hw_omap *clk);
+void omap4_dpllmx_deny_gatectrl(struct clk_hw_omap *clk);
+unsigned long omap4_dpll_regm4xen_recalc(struct clk_hw *hw,
+				unsigned long parent_rate);
+long omap4_dpll_regm4xen_round_rate(struct clk_hw *hw,
+				    unsigned long target_rate,
+				    unsigned long *parent_rate);
 
-#ifdef CONFIG_OMAP_RESET_CLOCKS
-void omap2_clk_disable_unused(struct clk *clk);
-#else
-#define omap2_clk_disable_unused	NULL
-#endif
-
-void omap2_init_clk_clkdm(struct clk *clk);
+void omap2_init_clk_clkdm(struct clk_hw *clk);
 void __init omap2_clk_disable_clkdm_control(void);
 
 /* clkt_clksel.c public functions */
-u32 omap2_clksel_round_rate_div(struct clk *clk, unsigned long target_rate,
+u32 omap2_clksel_round_rate_div(struct clk_hw_omap *clk,
+				unsigned long target_rate,
 				u32 *new_div);
-void omap2_init_clksel_parent(struct clk *clk);
-unsigned long omap2_clksel_recalc(struct clk *clk);
-long omap2_clksel_round_rate(struct clk *clk, unsigned long target_rate);
-int omap2_clksel_set_rate(struct clk *clk, unsigned long rate);
-int omap2_clksel_set_parent(struct clk *clk, struct clk *new_parent);
+u8 omap2_clksel_find_parent_index(struct clk_hw *hw);
+unsigned long omap2_clksel_recalc(struct clk_hw *hw, unsigned long parent_rate);
+long omap2_clksel_round_rate(struct clk_hw *hw, unsigned long target_rate,
+				unsigned long *parent_rate);
+int omap2_clksel_set_rate(struct clk_hw *hw, unsigned long rate,
+				unsigned long parent_rate);
+int omap2_clksel_set_parent(struct clk_hw *hw, u8 field_val);
 
 /* clkt_iclk.c public functions */
-extern void omap2_clkt_iclk_allow_idle(struct clk *clk);
-extern void omap2_clkt_iclk_deny_idle(struct clk *clk);
+extern void omap2_clkt_iclk_allow_idle(struct clk_hw_omap *clk);
+extern void omap2_clkt_iclk_deny_idle(struct clk_hw_omap *clk);
 
-u32 omap2_get_dpll_rate(struct clk *clk);
-void omap2_init_dpll_parent(struct clk *clk);
+u8 omap2_init_dpll_parent(struct clk_hw *hw);
+unsigned long omap2_get_dpll_rate(struct clk_hw_omap *clk);
 
-int omap2_dflt_clk_enable(struct clk *clk);
-void omap2_dflt_clk_disable(struct clk *clk);
-void omap2_clk_dflt_find_companion(struct clk *clk, void __iomem **other_reg,
+int omap2_dflt_clk_enable(struct clk_hw *hw);
+void omap2_dflt_clk_disable(struct clk_hw *hw);
+int omap2_dflt_clk_is_enabled(struct clk_hw *hw);
+void omap2_clk_dflt_find_companion(struct clk_hw_omap *clk,
+				   void __iomem **other_reg,
 				   u8 *other_bit);
-void omap2_clk_dflt_find_idlest(struct clk *clk, void __iomem **idlest_reg,
+void omap2_clk_dflt_find_idlest(struct clk_hw_omap *clk,
+				void __iomem **idlest_reg,
 				u8 *idlest_bit, u8 *idlest_val);
+void omap2_init_clk_hw_omap_clocks(struct clk *clk);
+int omap2_clk_enable_autoidle_all(void);
+int omap2_clk_disable_autoidle_all(void);
+void omap2_clk_enable_init_clocks(const char **clk_names, u8 num_clocks);
 int omap2_clk_switch_mpurate_at_boot(const char *mpurate_ck_name);
 void omap2_clk_print_new_rates(const char *hfclkin_ck_name,
 			       const char *core_ck_name,
@@ -432,28 +425,38 @@
 extern const struct clksel_rate gpt_sys_rates[];
 extern const struct clksel_rate gfx_l3_rates[];
 extern const struct clksel_rate dsp_ick_rates[];
+extern struct clk dummy_ck;
 
-extern const struct clkops clkops_omap2_iclk_dflt_wait;
-extern const struct clkops clkops_omap2_iclk_dflt;
-extern const struct clkops clkops_omap2_iclk_idle_only;
-extern const struct clkops clkops_omap2_mdmclk_dflt_wait;
-extern const struct clkops clkops_omap2xxx_dpll_ops;
-extern const struct clkops clkops_omap3_noncore_dpll_ops;
-extern const struct clkops clkops_omap3_core_dpll_ops;
-extern const struct clkops clkops_omap4_dpllmx_ops;
+extern const struct clk_hw_omap_ops clkhwops_omap3_dpll;
+extern const struct clk_hw_omap_ops clkhwops_iclk_wait;
+extern const struct clk_hw_omap_ops clkhwops_wait;
+extern const struct clk_hw_omap_ops clkhwops_omap4_dpllmx;
+extern const struct clk_hw_omap_ops clkhwops_iclk;
+extern const struct clk_hw_omap_ops clkhwops_omap3430es2_ssi_wait;
+extern const struct clk_hw_omap_ops clkhwops_omap3430es2_iclk_ssi_wait;
+extern const struct clk_hw_omap_ops clkhwops_omap3430es2_dss_usbhost_wait;
+extern const struct clk_hw_omap_ops clkhwops_omap3430es2_iclk_dss_usbhost_wait;
+extern const struct clk_hw_omap_ops clkhwops_omap3430es2_iclk_hsotgusb_wait;
+extern const struct clk_hw_omap_ops clkhwops_omap3430es2_hsotgusb_wait;
+extern const struct clk_hw_omap_ops clkhwops_am35xx_ipss_module_wait;
+extern const struct clk_hw_omap_ops clkhwops_am35xx_ipss_wait;
+extern const struct clk_hw_omap_ops clkhwops_apll54;
+extern const struct clk_hw_omap_ops clkhwops_apll96;
+extern const struct clk_hw_omap_ops clkhwops_omap2xxx_dpll;
+extern const struct clk_hw_omap_ops clkhwops_omap2430_i2chs_wait;
 
 /* clksel_rate blocks shared between OMAP44xx and AM33xx */
 extern const struct clksel_rate div_1_0_rates[];
+extern const struct clksel_rate div3_1to4_rates[];
 extern const struct clksel_rate div_1_1_rates[];
 extern const struct clksel_rate div_1_2_rates[];
 extern const struct clksel_rate div_1_3_rates[];
 extern const struct clksel_rate div_1_4_rates[];
 extern const struct clksel_rate div31_1to31_rates[];
 
-/* clocks shared between various OMAP SoCs */
-extern struct clk virt_19200000_ck;
-extern struct clk virt_26000000_ck;
-
 extern int am33xx_clk_init(void);
 
+extern int omap2_clkops_enable_clkdm(struct clk_hw *hw);
+extern void omap2_clkops_disable_clkdm(struct clk_hw *hw);
+
 #endif
diff --git a/arch/arm/mach-omap2/clock2420_data.c b/arch/arm/mach-omap2/clock2420_data.c
deleted file mode 100644
index 608874b6..0000000
--- a/arch/arm/mach-omap2/clock2420_data.c
+++ /dev/null
@@ -1,1972 +0,0 @@
-/*
- * OMAP2420 clock data
- *
- * Copyright (C) 2005-2009, 2012 Texas Instruments, Inc.
- * Copyright (C) 2004-2011 Nokia Corporation
- *
- * Contacts:
- * Richard Woodruff <r-woodruff2@ti.com>
- * Paul Walmsley
- *
- * 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/io.h>
-#include <linux/clk.h>
-#include <linux/list.h>
-
-#include "soc.h"
-#include "iomap.h"
-#include "clock.h"
-#include "clock2xxx.h"
-#include "opp2xxx.h"
-#include "cm2xxx.h"
-#include "prm2xxx_3xxx.h"
-#include "prm-regbits-24xx.h"
-#include "cm-regbits-24xx.h"
-#include "sdrc.h"
-#include "control.h"
-
-#define OMAP_CM_REGADDR                 OMAP2420_CM_REGADDR
-
-/*
- * 2420 clock tree.
- *
- * NOTE:In many cases here we are assigning a 'default' parent. In
- *	many cases the parent is selectable. The set parent calls will
- *	also switch sources.
- *
- *	Several sources are given initial rates which may be wrong, this will
- *	be fixed up in the init func.
- *
- *	Things are broadly separated below by clock domains. It is
- *	noteworthy that most peripherals have dependencies on multiple clock
- *	domains. Many get their interface clocks from the L4 domain, but get
- *	functional clocks from fixed sources or other core domain derived
- *	clocks.
- */
-
-/* Base external input clocks */
-static struct clk func_32k_ck = {
-	.name		= "func_32k_ck",
-	.ops		= &clkops_null,
-	.rate		= 32768,
-	.clkdm_name	= "wkup_clkdm",
-};
-
-static struct clk secure_32k_ck = {
-	.name		= "secure_32k_ck",
-	.ops		= &clkops_null,
-	.rate		= 32768,
-	.clkdm_name	= "wkup_clkdm",
-};
-
-/* Typical 12/13MHz in standalone mode, will be 26Mhz in chassis mode */
-static struct clk osc_ck = {		/* (*12, *13, 19.2, *26, 38.4)MHz */
-	.name		= "osc_ck",
-	.ops		= &clkops_oscck,
-	.clkdm_name	= "wkup_clkdm",
-	.recalc		= &omap2_osc_clk_recalc,
-};
-
-/* Without modem likely 12MHz, with modem likely 13MHz */
-static struct clk sys_ck = {		/* (*12, *13, 19.2, 26, 38.4)MHz */
-	.name		= "sys_ck",		/* ~ ref_clk also */
-	.ops		= &clkops_null,
-	.parent		= &osc_ck,
-	.clkdm_name	= "wkup_clkdm",
-	.recalc		= &omap2xxx_sys_clk_recalc,
-};
-
-static struct clk alt_ck = {		/* Typical 54M or 48M, may not exist */
-	.name		= "alt_ck",
-	.ops		= &clkops_null,
-	.rate		= 54000000,
-	.clkdm_name	= "wkup_clkdm",
-};
-
-/* Optional external clock input for McBSP CLKS */
-static struct clk mcbsp_clks = {
-	.name		= "mcbsp_clks",
-	.ops		= &clkops_null,
-};
-
-/*
- * Analog domain root source clocks
- */
-
-/* dpll_ck, is broken out in to special cases through clksel */
-/* REVISIT: Rate changes on dpll_ck trigger a full set change.	...
- * deal with this
- */
-
-static struct dpll_data dpll_dd = {
-	.mult_div1_reg		= OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1),
-	.mult_mask		= OMAP24XX_DPLL_MULT_MASK,
-	.div1_mask		= OMAP24XX_DPLL_DIV_MASK,
-	.clk_bypass		= &sys_ck,
-	.clk_ref		= &sys_ck,
-	.control_reg		= OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
-	.enable_mask		= OMAP24XX_EN_DPLL_MASK,
-	.max_multiplier		= 1023,
-	.min_divider		= 1,
-	.max_divider		= 16,
-};
-
-/*
- * XXX Cannot add round_rate here yet, as this is still a composite clock,
- * not just a DPLL
- */
-static struct clk dpll_ck = {
-	.name		= "dpll_ck",
-	.ops		= &clkops_omap2xxx_dpll_ops,
-	.parent		= &sys_ck,		/* Can be func_32k also */
-	.init		= &omap2xxx_clkt_dpllcore_init,
-	.dpll_data	= &dpll_dd,
-	.clkdm_name	= "wkup_clkdm",
-	.recalc		= &omap2_dpllcore_recalc,
-	.set_rate	= &omap2_reprogram_dpllcore,
-};
-
-static struct clk apll96_ck = {
-	.name		= "apll96_ck",
-	.ops		= &clkops_apll96,
-	.parent		= &sys_ck,
-	.rate		= 96000000,
-	.flags		= ENABLE_ON_INIT,
-	.clkdm_name	= "wkup_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
-	.enable_bit	= OMAP24XX_EN_96M_PLL_SHIFT,
-};
-
-static struct clk apll54_ck = {
-	.name		= "apll54_ck",
-	.ops		= &clkops_apll54,
-	.parent		= &sys_ck,
-	.rate		= 54000000,
-	.flags		= ENABLE_ON_INIT,
-	.clkdm_name	= "wkup_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
-	.enable_bit	= OMAP24XX_EN_54M_PLL_SHIFT,
-};
-
-/*
- * PRCM digital base sources
- */
-
-/* func_54m_ck */
-
-static const struct clksel_rate func_54m_apll54_rates[] = {
-	{ .div = 1, .val = 0, .flags = RATE_IN_24XX },
-	{ .div = 0 },
-};
-
-static const struct clksel_rate func_54m_alt_rates[] = {
-	{ .div = 1, .val = 1, .flags = RATE_IN_24XX },
-	{ .div = 0 },
-};
-
-static const struct clksel func_54m_clksel[] = {
-	{ .parent = &apll54_ck, .rates = func_54m_apll54_rates, },
-	{ .parent = &alt_ck,	.rates = func_54m_alt_rates, },
-	{ .parent = NULL },
-};
-
-static struct clk func_54m_ck = {
-	.name		= "func_54m_ck",
-	.ops		= &clkops_null,
-	.parent		= &apll54_ck,	/* can also be alt_clk */
-	.clkdm_name	= "wkup_clkdm",
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1),
-	.clksel_mask	= OMAP24XX_54M_SOURCE_MASK,
-	.clksel		= func_54m_clksel,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk core_ck = {
-	.name		= "core_ck",
-	.ops		= &clkops_null,
-	.parent		= &dpll_ck,		/* can also be 32k */
-	.clkdm_name	= "wkup_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk func_96m_ck = {
-	.name		= "func_96m_ck",
-	.ops		= &clkops_null,
-	.parent		= &apll96_ck,
-	.clkdm_name	= "wkup_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-/* func_48m_ck */
-
-static const struct clksel_rate func_48m_apll96_rates[] = {
-	{ .div = 2, .val = 0, .flags = RATE_IN_24XX },
-	{ .div = 0 },
-};
-
-static const struct clksel_rate func_48m_alt_rates[] = {
-	{ .div = 1, .val = 1, .flags = RATE_IN_24XX },
-	{ .div = 0 },
-};
-
-static const struct clksel func_48m_clksel[] = {
-	{ .parent = &apll96_ck,	.rates = func_48m_apll96_rates },
-	{ .parent = &alt_ck, .rates = func_48m_alt_rates },
-	{ .parent = NULL }
-};
-
-static struct clk func_48m_ck = {
-	.name		= "func_48m_ck",
-	.ops		= &clkops_null,
-	.parent		= &apll96_ck,	 /* 96M or Alt */
-	.clkdm_name	= "wkup_clkdm",
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1),
-	.clksel_mask	= OMAP24XX_48M_SOURCE_MASK,
-	.clksel		= func_48m_clksel,
-	.recalc		= &omap2_clksel_recalc,
-	.round_rate	= &omap2_clksel_round_rate,
-	.set_rate	= &omap2_clksel_set_rate
-};
-
-static struct clk func_12m_ck = {
-	.name		= "func_12m_ck",
-	.ops		= &clkops_null,
-	.parent		= &func_48m_ck,
-	.fixed_div	= 4,
-	.clkdm_name	= "wkup_clkdm",
-	.recalc		= &omap_fixed_divisor_recalc,
-};
-
-/* Secure timer, only available in secure mode */
-static struct clk wdt1_osc_ck = {
-	.name		= "ck_wdt1_osc",
-	.ops		= &clkops_null, /* RMK: missing? */
-	.parent		= &osc_ck,
-	.recalc		= &followparent_recalc,
-};
-
-/*
- * The common_clkout* clksel_rate structs are common to
- * sys_clkout, sys_clkout_src, sys_clkout2, and sys_clkout2_src.
- * sys_clkout2_* are 2420-only, so the
- * clksel_rate flags fields are inaccurate for those clocks. This is
- * harmless since access to those clocks are gated by the struct clk
- * flags fields, which mark them as 2420-only.
- */
-static const struct clksel_rate common_clkout_src_core_rates[] = {
-	{ .div = 1, .val = 0, .flags = RATE_IN_24XX },
-	{ .div = 0 }
-};
-
-static const struct clksel_rate common_clkout_src_sys_rates[] = {
-	{ .div = 1, .val = 1, .flags = RATE_IN_24XX },
-	{ .div = 0 }
-};
-
-static const struct clksel_rate common_clkout_src_96m_rates[] = {
-	{ .div = 1, .val = 2, .flags = RATE_IN_24XX },
-	{ .div = 0 }
-};
-
-static const struct clksel_rate common_clkout_src_54m_rates[] = {
-	{ .div = 1, .val = 3, .flags = RATE_IN_24XX },
-	{ .div = 0 }
-};
-
-static const struct clksel common_clkout_src_clksel[] = {
-	{ .parent = &core_ck,	  .rates = common_clkout_src_core_rates },
-	{ .parent = &sys_ck,	  .rates = common_clkout_src_sys_rates },
-	{ .parent = &func_96m_ck, .rates = common_clkout_src_96m_rates },
-	{ .parent = &func_54m_ck, .rates = common_clkout_src_54m_rates },
-	{ .parent = NULL }
-};
-
-static struct clk sys_clkout_src = {
-	.name		= "sys_clkout_src",
-	.ops		= &clkops_omap2_dflt,
-	.parent		= &func_54m_ck,
-	.clkdm_name	= "wkup_clkdm",
-	.enable_reg	= OMAP2420_PRCM_CLKOUT_CTRL,
-	.enable_bit	= OMAP24XX_CLKOUT_EN_SHIFT,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP2420_PRCM_CLKOUT_CTRL,
-	.clksel_mask	= OMAP24XX_CLKOUT_SOURCE_MASK,
-	.clksel		= common_clkout_src_clksel,
-	.recalc		= &omap2_clksel_recalc,
-	.round_rate	= &omap2_clksel_round_rate,
-	.set_rate	= &omap2_clksel_set_rate
-};
-
-static const struct clksel_rate common_clkout_rates[] = {
-	{ .div = 1, .val = 0, .flags = RATE_IN_24XX },
-	{ .div = 2, .val = 1, .flags = RATE_IN_24XX },
-	{ .div = 4, .val = 2, .flags = RATE_IN_24XX },
-	{ .div = 8, .val = 3, .flags = RATE_IN_24XX },
-	{ .div = 16, .val = 4, .flags = RATE_IN_24XX },
-	{ .div = 0 },
-};
-
-static const struct clksel sys_clkout_clksel[] = {
-	{ .parent = &sys_clkout_src, .rates = common_clkout_rates },
-	{ .parent = NULL }
-};
-
-static struct clk sys_clkout = {
-	.name		= "sys_clkout",
-	.ops		= &clkops_null,
-	.parent		= &sys_clkout_src,
-	.clkdm_name	= "wkup_clkdm",
-	.clksel_reg	= OMAP2420_PRCM_CLKOUT_CTRL,
-	.clksel_mask	= OMAP24XX_CLKOUT_DIV_MASK,
-	.clksel		= sys_clkout_clksel,
-	.recalc		= &omap2_clksel_recalc,
-	.round_rate	= &omap2_clksel_round_rate,
-	.set_rate	= &omap2_clksel_set_rate
-};
-
-/* In 2430, new in 2420 ES2 */
-static struct clk sys_clkout2_src = {
-	.name		= "sys_clkout2_src",
-	.ops		= &clkops_omap2_dflt,
-	.parent		= &func_54m_ck,
-	.clkdm_name	= "wkup_clkdm",
-	.enable_reg	= OMAP2420_PRCM_CLKOUT_CTRL,
-	.enable_bit	= OMAP2420_CLKOUT2_EN_SHIFT,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP2420_PRCM_CLKOUT_CTRL,
-	.clksel_mask	= OMAP2420_CLKOUT2_SOURCE_MASK,
-	.clksel		= common_clkout_src_clksel,
-	.recalc		= &omap2_clksel_recalc,
-	.round_rate	= &omap2_clksel_round_rate,
-	.set_rate	= &omap2_clksel_set_rate
-};
-
-static const struct clksel sys_clkout2_clksel[] = {
-	{ .parent = &sys_clkout2_src, .rates = common_clkout_rates },
-	{ .parent = NULL }
-};
-
-/* In 2430, new in 2420 ES2 */
-static struct clk sys_clkout2 = {
-	.name		= "sys_clkout2",
-	.ops		= &clkops_null,
-	.parent		= &sys_clkout2_src,
-	.clkdm_name	= "wkup_clkdm",
-	.clksel_reg	= OMAP2420_PRCM_CLKOUT_CTRL,
-	.clksel_mask	= OMAP2420_CLKOUT2_DIV_MASK,
-	.clksel		= sys_clkout2_clksel,
-	.recalc		= &omap2_clksel_recalc,
-	.round_rate	= &omap2_clksel_round_rate,
-	.set_rate	= &omap2_clksel_set_rate
-};
-
-static struct clk emul_ck = {
-	.name		= "emul_ck",
-	.ops		= &clkops_omap2_dflt,
-	.parent		= &func_54m_ck,
-	.clkdm_name	= "wkup_clkdm",
-	.enable_reg	= OMAP2420_PRCM_CLKEMUL_CTRL,
-	.enable_bit	= OMAP24XX_EMULATION_EN_SHIFT,
-	.recalc		= &followparent_recalc,
-
-};
-
-/*
- * MPU clock domain
- *	Clocks:
- *		MPU_FCLK, MPU_ICLK
- *		INT_M_FCLK, INT_M_I_CLK
- *
- * - Individual clocks are hardware managed.
- * - Base divider comes from: CM_CLKSEL_MPU
- *
- */
-static const struct clksel_rate mpu_core_rates[] = {
-	{ .div = 1, .val = 1, .flags = RATE_IN_24XX },
-	{ .div = 2, .val = 2, .flags = RATE_IN_24XX },
-	{ .div = 4, .val = 4, .flags = RATE_IN_242X },
-	{ .div = 6, .val = 6, .flags = RATE_IN_242X },
-	{ .div = 8, .val = 8, .flags = RATE_IN_242X },
-	{ .div = 0 },
-};
-
-static const struct clksel mpu_clksel[] = {
-	{ .parent = &core_ck, .rates = mpu_core_rates },
-	{ .parent = NULL }
-};
-
-static struct clk mpu_ck = {	/* Control cpu */
-	.name		= "mpu_ck",
-	.ops		= &clkops_null,
-	.parent		= &core_ck,
-	.clkdm_name	= "mpu_clkdm",
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(MPU_MOD, CM_CLKSEL),
-	.clksel_mask	= OMAP24XX_CLKSEL_MPU_MASK,
-	.clksel		= mpu_clksel,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-/*
- * DSP (2420-UMA+IVA1) clock domain
- * Clocks:
- *	2420: UMA_FCLK, UMA_ICLK, IVA_MPU, IVA_COP
- *
- * Won't be too specific here. The core clock comes into this block
- * it is divided then tee'ed. One branch goes directly to xyz enable
- * controls. The other branch gets further divided by 2 then possibly
- * routed into a synchronizer and out of clocks abc.
- */
-static const struct clksel_rate dsp_fck_core_rates[] = {
-	{ .div = 1, .val = 1, .flags = RATE_IN_24XX },
-	{ .div = 2, .val = 2, .flags = RATE_IN_24XX },
-	{ .div = 3, .val = 3, .flags = RATE_IN_24XX },
-	{ .div = 4, .val = 4, .flags = RATE_IN_24XX },
-	{ .div = 6, .val = 6, .flags = RATE_IN_242X },
-	{ .div = 8, .val = 8, .flags = RATE_IN_242X },
-	{ .div = 12, .val = 12, .flags = RATE_IN_242X },
-	{ .div = 0 },
-};
-
-static const struct clksel dsp_fck_clksel[] = {
-	{ .parent = &core_ck, .rates = dsp_fck_core_rates },
-	{ .parent = NULL }
-};
-
-static struct clk dsp_fck = {
-	.name		= "dsp_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &core_ck,
-	.clkdm_name	= "dsp_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP24XX_CM_FCLKEN_DSP_EN_DSP_SHIFT,
-	.clksel_reg	= OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_CLKSEL),
-	.clksel_mask	= OMAP24XX_CLKSEL_DSP_MASK,
-	.clksel		= dsp_fck_clksel,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static const struct clksel dsp_ick_clksel[] = {
-	{ .parent = &dsp_fck, .rates = dsp_ick_rates },
-	{ .parent = NULL }
-};
-
-static struct clk dsp_ick = {
-	.name		= "dsp_ick",	 /* apparently ipi and isp */
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &dsp_fck,
-	.clkdm_name	= "dsp_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP2420_EN_DSP_IPI_SHIFT,	      /* for ipi */
-	.clksel_reg	= OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_CLKSEL),
-	.clksel_mask	= OMAP24XX_CLKSEL_DSP_IF_MASK,
-	.clksel		= dsp_ick_clksel,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-/*
- * The IVA1 is an ARM7 core on the 2420 that has nothing to do with
- * the C54x, but which is contained in the DSP powerdomain.  Does not
- * exist on later OMAPs.
- */
-static struct clk iva1_ifck = {
-	.name		= "iva1_ifck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &core_ck,
-	.clkdm_name	= "iva1_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP2420_EN_IVA_COP_SHIFT,
-	.clksel_reg	= OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_CLKSEL),
-	.clksel_mask	= OMAP2420_CLKSEL_IVA_MASK,
-	.clksel		= dsp_fck_clksel,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-/* IVA1 mpu/int/i/f clocks are /2 of parent */
-static struct clk iva1_mpu_int_ifck = {
-	.name		= "iva1_mpu_int_ifck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &iva1_ifck,
-	.clkdm_name	= "iva1_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP2420_EN_IVA_MPU_SHIFT,
-	.fixed_div	= 2,
-	.recalc		= &omap_fixed_divisor_recalc,
-};
-
-/*
- * L3 clock domain
- * L3 clocks are used for both interface and functional clocks to
- * multiple entities. Some of these clocks are completely managed
- * by hardware, and some others allow software control. Hardware
- * managed ones general are based on directly CLK_REQ signals and
- * various auto idle settings. The functional spec sets many of these
- * as 'tie-high' for their enables.
- *
- * I-CLOCKS:
- *	L3-Interconnect, SMS, GPMC, SDRC, OCM_RAM, OCM_ROM, SDMA
- *	CAM, HS-USB.
- * F-CLOCK
- *	SSI.
- *
- * GPMC memories and SDRC have timing and clock sensitive registers which
- * may very well need notification when the clock changes. Currently for low
- * operating points, these are taken care of in sleep.S.
- */
-static const struct clksel_rate core_l3_core_rates[] = {
-	{ .div = 1, .val = 1, .flags = RATE_IN_24XX },
-	{ .div = 2, .val = 2, .flags = RATE_IN_242X },
-	{ .div = 4, .val = 4, .flags = RATE_IN_24XX },
-	{ .div = 6, .val = 6, .flags = RATE_IN_24XX },
-	{ .div = 8, .val = 8, .flags = RATE_IN_242X },
-	{ .div = 12, .val = 12, .flags = RATE_IN_242X },
-	{ .div = 16, .val = 16, .flags = RATE_IN_242X },
-	{ .div = 0 }
-};
-
-static const struct clksel core_l3_clksel[] = {
-	{ .parent = &core_ck, .rates = core_l3_core_rates },
-	{ .parent = NULL }
-};
-
-static struct clk core_l3_ck = {	/* Used for ick and fck, interconnect */
-	.name		= "core_l3_ck",
-	.ops		= &clkops_null,
-	.parent		= &core_ck,
-	.clkdm_name	= "core_l3_clkdm",
-	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1),
-	.clksel_mask	= OMAP24XX_CLKSEL_L3_MASK,
-	.clksel		= core_l3_clksel,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-/* usb_l4_ick */
-static const struct clksel_rate usb_l4_ick_core_l3_rates[] = {
-	{ .div = 1, .val = 1, .flags = RATE_IN_24XX },
-	{ .div = 2, .val = 2, .flags = RATE_IN_24XX },
-	{ .div = 4, .val = 4, .flags = RATE_IN_24XX },
-	{ .div = 0 }
-};
-
-static const struct clksel usb_l4_ick_clksel[] = {
-	{ .parent = &core_l3_ck, .rates = usb_l4_ick_core_l3_rates },
-	{ .parent = NULL },
-};
-
-/* It is unclear from TRM whether usb_l4_ick is really in L3 or L4 clkdm */
-static struct clk usb_l4_ick = {	/* FS-USB interface clock */
-	.name		= "usb_l4_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &core_l3_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
-	.enable_bit	= OMAP24XX_EN_USB_SHIFT,
-	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1),
-	.clksel_mask	= OMAP24XX_CLKSEL_USB_MASK,
-	.clksel		= usb_l4_ick_clksel,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-/*
- * L4 clock management domain
- *
- * This domain contains lots of interface clocks from the L4 interface, some
- * functional clocks.	Fixed APLL functional source clocks are managed in
- * this domain.
- */
-static const struct clksel_rate l4_core_l3_rates[] = {
-	{ .div = 1, .val = 1, .flags = RATE_IN_24XX },
-	{ .div = 2, .val = 2, .flags = RATE_IN_24XX },
-	{ .div = 0 }
-};
-
-static const struct clksel l4_clksel[] = {
-	{ .parent = &core_l3_ck, .rates = l4_core_l3_rates },
-	{ .parent = NULL }
-};
-
-static struct clk l4_ck = {		/* used both as an ick and fck */
-	.name		= "l4_ck",
-	.ops		= &clkops_null,
-	.parent		= &core_l3_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1),
-	.clksel_mask	= OMAP24XX_CLKSEL_L4_MASK,
-	.clksel		= l4_clksel,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-/*
- * SSI is in L3 management domain, its direct parent is core not l3,
- * many core power domain entities are grouped into the L3 clock
- * domain.
- * SSI_SSR_FCLK, SSI_SST_FCLK, SSI_L4_ICLK
- *
- * ssr = core/1/2/3/4/5, sst = 1/2 ssr.
- */
-static const struct clksel_rate ssi_ssr_sst_fck_core_rates[] = {
-	{ .div = 1, .val = 1, .flags = RATE_IN_24XX },
-	{ .div = 2, .val = 2, .flags = RATE_IN_24XX },
-	{ .div = 3, .val = 3, .flags = RATE_IN_24XX },
-	{ .div = 4, .val = 4, .flags = RATE_IN_24XX },
-	{ .div = 6, .val = 6, .flags = RATE_IN_242X },
-	{ .div = 8, .val = 8, .flags = RATE_IN_242X },
-	{ .div = 0 }
-};
-
-static const struct clksel ssi_ssr_sst_fck_clksel[] = {
-	{ .parent = &core_ck, .rates = ssi_ssr_sst_fck_core_rates },
-	{ .parent = NULL }
-};
-
-static struct clk ssi_ssr_sst_fck = {
-	.name		= "ssi_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &core_ck,
-	.clkdm_name	= "core_l3_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
-	.enable_bit	= OMAP24XX_EN_SSI_SHIFT,
-	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1),
-	.clksel_mask	= OMAP24XX_CLKSEL_SSI_MASK,
-	.clksel		= ssi_ssr_sst_fck_clksel,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-/*
- * Presumably this is the same as SSI_ICLK.
- * TRM contradicts itself on what clockdomain SSI_ICLK is in
- */
-static struct clk ssi_l4_ick = {
-	.name		= "ssi_l4_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
-	.enable_bit	= OMAP24XX_EN_SSI_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-
-/*
- * GFX clock domain
- *	Clocks:
- * GFX_FCLK, GFX_ICLK
- * GFX_CG1(2d), GFX_CG2(3d)
- *
- * GFX_FCLK runs from L3, and is divided by (1,2,3,4)
- * The 2d and 3d clocks run at a hardware determined
- * divided value of fclk.
- *
- */
-
-/* This clksel struct is shared between gfx_3d_fck and gfx_2d_fck */
-static const struct clksel gfx_fck_clksel[] = {
-	{ .parent = &core_l3_ck, .rates = gfx_l3_rates },
-	{ .parent = NULL },
-};
-
-static struct clk gfx_3d_fck = {
-	.name		= "gfx_3d_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &core_l3_ck,
-	.clkdm_name	= "gfx_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(GFX_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP24XX_EN_3D_SHIFT,
-	.clksel_reg	= OMAP_CM_REGADDR(GFX_MOD, CM_CLKSEL),
-	.clksel_mask	= OMAP_CLKSEL_GFX_MASK,
-	.clksel		= gfx_fck_clksel,
-	.recalc		= &omap2_clksel_recalc,
-	.round_rate	= &omap2_clksel_round_rate,
-	.set_rate	= &omap2_clksel_set_rate
-};
-
-static struct clk gfx_2d_fck = {
-	.name		= "gfx_2d_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &core_l3_ck,
-	.clkdm_name	= "gfx_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(GFX_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP24XX_EN_2D_SHIFT,
-	.clksel_reg	= OMAP_CM_REGADDR(GFX_MOD, CM_CLKSEL),
-	.clksel_mask	= OMAP_CLKSEL_GFX_MASK,
-	.clksel		= gfx_fck_clksel,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-/* This interface clock does not have a CM_AUTOIDLE bit */
-static struct clk gfx_ick = {
-	.name		= "gfx_ick",		/* From l3 */
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &core_l3_ck,
-	.clkdm_name	= "gfx_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(GFX_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP_EN_GFX_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-/*
- * DSS clock domain
- * CLOCKs:
- * DSS_L4_ICLK, DSS_L3_ICLK,
- * DSS_CLK1, DSS_CLK2, DSS_54MHz_CLK
- *
- * DSS is both initiator and target.
- */
-/* XXX Add RATE_NOT_VALIDATED */
-
-static const struct clksel_rate dss1_fck_sys_rates[] = {
-	{ .div = 1, .val = 0, .flags = RATE_IN_24XX },
-	{ .div = 0 }
-};
-
-static const struct clksel_rate dss1_fck_core_rates[] = {
-	{ .div = 1, .val = 1, .flags = RATE_IN_24XX },
-	{ .div = 2, .val = 2, .flags = RATE_IN_24XX },
-	{ .div = 3, .val = 3, .flags = RATE_IN_24XX },
-	{ .div = 4, .val = 4, .flags = RATE_IN_24XX },
-	{ .div = 5, .val = 5, .flags = RATE_IN_24XX },
-	{ .div = 6, .val = 6, .flags = RATE_IN_24XX },
-	{ .div = 8, .val = 8, .flags = RATE_IN_24XX },
-	{ .div = 9, .val = 9, .flags = RATE_IN_24XX },
-	{ .div = 12, .val = 12, .flags = RATE_IN_24XX },
-	{ .div = 16, .val = 16, .flags = RATE_IN_24XX },
-	{ .div = 0 }
-};
-
-static const struct clksel dss1_fck_clksel[] = {
-	{ .parent = &sys_ck,  .rates = dss1_fck_sys_rates },
-	{ .parent = &core_ck, .rates = dss1_fck_core_rates },
-	{ .parent = NULL },
-};
-
-static struct clk dss_ick = {		/* Enables both L3,L4 ICLK's */
-	.name		= "dss_ick",
-	.ops		= &clkops_omap2_iclk_dflt,
-	.parent		= &l4_ck,	/* really both l3 and l4 */
-	.clkdm_name	= "dss_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP24XX_EN_DSS1_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk dss1_fck = {
-	.name		= "dss1_fck",
-	.ops		= &clkops_omap2_dflt,
-	.parent		= &core_ck,		/* Core or sys */
-	.clkdm_name	= "dss_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP24XX_EN_DSS1_SHIFT,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1),
-	.clksel_mask	= OMAP24XX_CLKSEL_DSS1_MASK,
-	.clksel		= dss1_fck_clksel,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static const struct clksel_rate dss2_fck_sys_rates[] = {
-	{ .div = 1, .val = 0, .flags = RATE_IN_24XX },
-	{ .div = 0 }
-};
-
-static const struct clksel_rate dss2_fck_48m_rates[] = {
-	{ .div = 1, .val = 1, .flags = RATE_IN_24XX },
-	{ .div = 0 }
-};
-
-static const struct clksel dss2_fck_clksel[] = {
-	{ .parent = &sys_ck,	  .rates = dss2_fck_sys_rates },
-	{ .parent = &func_48m_ck, .rates = dss2_fck_48m_rates },
-	{ .parent = NULL }
-};
-
-static struct clk dss2_fck = {		/* Alt clk used in power management */
-	.name		= "dss2_fck",
-	.ops		= &clkops_omap2_dflt,
-	.parent		= &sys_ck,		/* fixed at sys_ck or 48MHz */
-	.clkdm_name	= "dss_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP24XX_EN_DSS2_SHIFT,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1),
-	.clksel_mask	= OMAP24XX_CLKSEL_DSS2_MASK,
-	.clksel		= dss2_fck_clksel,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk dss_54m_fck = {	/* Alt clk used in power management */
-	.name		= "dss_54m_fck",	/* 54m tv clk */
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_54m_ck,
-	.clkdm_name	= "dss_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP24XX_EN_TV_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk wu_l4_ick = {
-	.name		= "wu_l4_ick",
-	.ops		= &clkops_null,
-	.parent		= &sys_ck,
-	.clkdm_name	= "wkup_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-/*
- * CORE power domain ICLK & FCLK defines.
- * Many of the these can have more than one possible parent. Entries
- * here will likely have an L4 interface parent, and may have multiple
- * functional clock parents.
- */
-static const struct clksel_rate gpt_alt_rates[] = {
-	{ .div = 1, .val = 2, .flags = RATE_IN_24XX },
-	{ .div = 0 }
-};
-
-static const struct clksel omap24xx_gpt_clksel[] = {
-	{ .parent = &func_32k_ck, .rates = gpt_32k_rates },
-	{ .parent = &sys_ck,	  .rates = gpt_sys_rates },
-	{ .parent = &alt_ck,	  .rates = gpt_alt_rates },
-	{ .parent = NULL },
-};
-
-static struct clk gpt1_ick = {
-	.name		= "gpt1_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &wu_l4_ick,
-	.clkdm_name	= "wkup_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP24XX_EN_GPT1_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpt1_fck = {
-	.name		= "gpt1_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_32k_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP24XX_EN_GPT1_SHIFT,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_CLKSEL1),
-	.clksel_mask	= OMAP24XX_CLKSEL_GPT1_MASK,
-	.clksel		= omap24xx_gpt_clksel,
-	.recalc		= &omap2_clksel_recalc,
-	.round_rate	= &omap2_clksel_round_rate,
-	.set_rate	= &omap2_clksel_set_rate
-};
-
-static struct clk gpt2_ick = {
-	.name		= "gpt2_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP24XX_EN_GPT2_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpt2_fck = {
-	.name		= "gpt2_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_32k_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP24XX_EN_GPT2_SHIFT,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
-	.clksel_mask	= OMAP24XX_CLKSEL_GPT2_MASK,
-	.clksel		= omap24xx_gpt_clksel,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk gpt3_ick = {
-	.name		= "gpt3_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP24XX_EN_GPT3_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpt3_fck = {
-	.name		= "gpt3_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_32k_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP24XX_EN_GPT3_SHIFT,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
-	.clksel_mask	= OMAP24XX_CLKSEL_GPT3_MASK,
-	.clksel		= omap24xx_gpt_clksel,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk gpt4_ick = {
-	.name		= "gpt4_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP24XX_EN_GPT4_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpt4_fck = {
-	.name		= "gpt4_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_32k_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP24XX_EN_GPT4_SHIFT,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
-	.clksel_mask	= OMAP24XX_CLKSEL_GPT4_MASK,
-	.clksel		= omap24xx_gpt_clksel,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk gpt5_ick = {
-	.name		= "gpt5_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP24XX_EN_GPT5_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpt5_fck = {
-	.name		= "gpt5_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_32k_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP24XX_EN_GPT5_SHIFT,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
-	.clksel_mask	= OMAP24XX_CLKSEL_GPT5_MASK,
-	.clksel		= omap24xx_gpt_clksel,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk gpt6_ick = {
-	.name		= "gpt6_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP24XX_EN_GPT6_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpt6_fck = {
-	.name		= "gpt6_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_32k_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP24XX_EN_GPT6_SHIFT,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
-	.clksel_mask	= OMAP24XX_CLKSEL_GPT6_MASK,
-	.clksel		= omap24xx_gpt_clksel,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk gpt7_ick = {
-	.name		= "gpt7_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP24XX_EN_GPT7_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpt7_fck = {
-	.name		= "gpt7_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_32k_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP24XX_EN_GPT7_SHIFT,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
-	.clksel_mask	= OMAP24XX_CLKSEL_GPT7_MASK,
-	.clksel		= omap24xx_gpt_clksel,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk gpt8_ick = {
-	.name		= "gpt8_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP24XX_EN_GPT8_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpt8_fck = {
-	.name		= "gpt8_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_32k_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP24XX_EN_GPT8_SHIFT,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
-	.clksel_mask	= OMAP24XX_CLKSEL_GPT8_MASK,
-	.clksel		= omap24xx_gpt_clksel,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk gpt9_ick = {
-	.name		= "gpt9_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP24XX_EN_GPT9_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpt9_fck = {
-	.name		= "gpt9_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_32k_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP24XX_EN_GPT9_SHIFT,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
-	.clksel_mask	= OMAP24XX_CLKSEL_GPT9_MASK,
-	.clksel		= omap24xx_gpt_clksel,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk gpt10_ick = {
-	.name		= "gpt10_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP24XX_EN_GPT10_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpt10_fck = {
-	.name		= "gpt10_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_32k_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP24XX_EN_GPT10_SHIFT,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
-	.clksel_mask	= OMAP24XX_CLKSEL_GPT10_MASK,
-	.clksel		= omap24xx_gpt_clksel,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk gpt11_ick = {
-	.name		= "gpt11_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP24XX_EN_GPT11_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpt11_fck = {
-	.name		= "gpt11_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_32k_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP24XX_EN_GPT11_SHIFT,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
-	.clksel_mask	= OMAP24XX_CLKSEL_GPT11_MASK,
-	.clksel		= omap24xx_gpt_clksel,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk gpt12_ick = {
-	.name		= "gpt12_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP24XX_EN_GPT12_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpt12_fck = {
-	.name		= "gpt12_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &secure_32k_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP24XX_EN_GPT12_SHIFT,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
-	.clksel_mask	= OMAP24XX_CLKSEL_GPT12_MASK,
-	.clksel		= omap24xx_gpt_clksel,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk mcbsp1_ick = {
-	.name		= "mcbsp1_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP24XX_EN_MCBSP1_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static const struct clksel_rate common_mcbsp_96m_rates[] = {
-	{ .div = 1, .val = 0, .flags = RATE_IN_24XX },
-	{ .div = 0 }
-};
-
-static const struct clksel_rate common_mcbsp_mcbsp_rates[] = {
-	{ .div = 1, .val = 1, .flags = RATE_IN_24XX },
-	{ .div = 0 }
-};
-
-static const struct clksel mcbsp_fck_clksel[] = {
-	{ .parent = &func_96m_ck,  .rates = common_mcbsp_96m_rates },
-	{ .parent = &mcbsp_clks,   .rates = common_mcbsp_mcbsp_rates },
-	{ .parent = NULL }
-};
-
-static struct clk mcbsp1_fck = {
-	.name		= "mcbsp1_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_96m_ck,
-	.init		= &omap2_init_clksel_parent,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP24XX_EN_MCBSP1_SHIFT,
-	.clksel_reg	= OMAP242X_CTRL_REGADDR(OMAP2_CONTROL_DEVCONF0),
-	.clksel_mask	= OMAP2_MCBSP1_CLKS_MASK,
-	.clksel		= mcbsp_fck_clksel,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk mcbsp2_ick = {
-	.name		= "mcbsp2_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP24XX_EN_MCBSP2_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mcbsp2_fck = {
-	.name		= "mcbsp2_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_96m_ck,
-	.init		= &omap2_init_clksel_parent,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP24XX_EN_MCBSP2_SHIFT,
-	.clksel_reg	= OMAP242X_CTRL_REGADDR(OMAP2_CONTROL_DEVCONF0),
-	.clksel_mask	= OMAP2_MCBSP2_CLKS_MASK,
-	.clksel		= mcbsp_fck_clksel,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk mcspi1_ick = {
-	.name		= "mcspi1_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP24XX_EN_MCSPI1_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mcspi1_fck = {
-	.name		= "mcspi1_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_48m_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP24XX_EN_MCSPI1_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mcspi2_ick = {
-	.name		= "mcspi2_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP24XX_EN_MCSPI2_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mcspi2_fck = {
-	.name		= "mcspi2_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_48m_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP24XX_EN_MCSPI2_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk uart1_ick = {
-	.name		= "uart1_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP24XX_EN_UART1_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk uart1_fck = {
-	.name		= "uart1_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_48m_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP24XX_EN_UART1_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk uart2_ick = {
-	.name		= "uart2_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP24XX_EN_UART2_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk uart2_fck = {
-	.name		= "uart2_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_48m_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP24XX_EN_UART2_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk uart3_ick = {
-	.name		= "uart3_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
-	.enable_bit	= OMAP24XX_EN_UART3_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk uart3_fck = {
-	.name		= "uart3_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_48m_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
-	.enable_bit	= OMAP24XX_EN_UART3_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpios_ick = {
-	.name		= "gpios_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &wu_l4_ick,
-	.clkdm_name	= "wkup_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP24XX_EN_GPIOS_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpios_fck = {
-	.name		= "gpios_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_32k_ck,
-	.clkdm_name	= "wkup_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP24XX_EN_GPIOS_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mpu_wdt_ick = {
-	.name		= "mpu_wdt_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &wu_l4_ick,
-	.clkdm_name	= "wkup_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP24XX_EN_MPU_WDT_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mpu_wdt_fck = {
-	.name		= "mpu_wdt_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_32k_ck,
-	.clkdm_name	= "wkup_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP24XX_EN_MPU_WDT_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk sync_32k_ick = {
-	.name		= "sync_32k_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &wu_l4_ick,
-	.clkdm_name	= "wkup_clkdm",
-	.flags		= ENABLE_ON_INIT,
-	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP24XX_EN_32KSYNC_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk wdt1_ick = {
-	.name		= "wdt1_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &wu_l4_ick,
-	.clkdm_name	= "wkup_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP24XX_EN_WDT1_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk omapctrl_ick = {
-	.name		= "omapctrl_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &wu_l4_ick,
-	.clkdm_name	= "wkup_clkdm",
-	.flags		= ENABLE_ON_INIT,
-	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP24XX_EN_OMAPCTRL_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk cam_ick = {
-	.name		= "cam_ick",
-	.ops		= &clkops_omap2_iclk_dflt,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP24XX_EN_CAM_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-/*
- * cam_fck controls both CAM_MCLK and CAM_FCLK.  It should probably be
- * split into two separate clocks, since the parent clocks are different
- * and the clockdomains are also different.
- */
-static struct clk cam_fck = {
-	.name		= "cam_fck",
-	.ops		= &clkops_omap2_dflt,
-	.parent		= &func_96m_ck,
-	.clkdm_name	= "core_l3_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP24XX_EN_CAM_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mailboxes_ick = {
-	.name		= "mailboxes_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP24XX_EN_MAILBOXES_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk wdt4_ick = {
-	.name		= "wdt4_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP24XX_EN_WDT4_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk wdt4_fck = {
-	.name		= "wdt4_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_32k_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP24XX_EN_WDT4_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk wdt3_ick = {
-	.name		= "wdt3_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP2420_EN_WDT3_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk wdt3_fck = {
-	.name		= "wdt3_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_32k_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP2420_EN_WDT3_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mspro_ick = {
-	.name		= "mspro_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP24XX_EN_MSPRO_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mspro_fck = {
-	.name		= "mspro_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_96m_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP24XX_EN_MSPRO_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mmc_ick = {
-	.name		= "mmc_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP2420_EN_MMC_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mmc_fck = {
-	.name		= "mmc_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_96m_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP2420_EN_MMC_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk fac_ick = {
-	.name		= "fac_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP24XX_EN_FAC_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk fac_fck = {
-	.name		= "fac_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_12m_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP24XX_EN_FAC_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk eac_ick = {
-	.name		= "eac_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP2420_EN_EAC_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk eac_fck = {
-	.name		= "eac_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_96m_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP2420_EN_EAC_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk hdq_ick = {
-	.name		= "hdq_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP24XX_EN_HDQ_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk hdq_fck = {
-	.name		= "hdq_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_12m_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP24XX_EN_HDQ_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk i2c2_ick = {
-	.name		= "i2c2_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP2420_EN_I2C2_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk i2c2_fck = {
-	.name		= "i2c2_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_12m_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP2420_EN_I2C2_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk i2c1_ick = {
-	.name		= "i2c1_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP2420_EN_I2C1_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk i2c1_fck = {
-	.name		= "i2c1_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_12m_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP2420_EN_I2C1_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-/*
- * The enable_reg/enable_bit in this clock is only used for CM_AUTOIDLE
- * accesses derived from this data.
- */
-static struct clk gpmc_fck = {
-	.name		= "gpmc_fck",
-	.ops		= &clkops_omap2_iclk_idle_only,
-	.parent		= &core_l3_ck,
-	.flags		= ENABLE_ON_INIT,
-	.clkdm_name	= "core_l3_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN3),
-	.enable_bit	= OMAP24XX_AUTO_GPMC_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk sdma_fck = {
-	.name		= "sdma_fck",
-	.ops		= &clkops_null, /* RMK: missing? */
-	.parent		= &core_l3_ck,
-	.clkdm_name	= "core_l3_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-/*
- * The enable_reg/enable_bit in this clock is only used for CM_AUTOIDLE
- * accesses derived from this data.
- */
-static struct clk sdma_ick = {
-	.name		= "sdma_ick",
-	.ops		= &clkops_omap2_iclk_idle_only,
-	.parent		= &core_l3_ck,
-	.clkdm_name	= "core_l3_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN3),
-	.enable_bit	= OMAP24XX_AUTO_SDMA_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-/*
- * The enable_reg/enable_bit in this clock is only used for CM_AUTOIDLE
- * accesses derived from this data.
- */
-static struct clk sdrc_ick = {
-	.name		= "sdrc_ick",
-	.ops		= &clkops_omap2_iclk_idle_only,
-	.parent		= &core_l3_ck,
-	.flags		= ENABLE_ON_INIT,
-	.clkdm_name	= "core_l3_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN3),
-	.enable_bit	= OMAP24XX_AUTO_SDRC_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk vlynq_ick = {
-	.name		= "vlynq_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &core_l3_ck,
-	.clkdm_name	= "core_l3_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP2420_EN_VLYNQ_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static const struct clksel_rate vlynq_fck_96m_rates[] = {
-	{ .div = 1, .val = 0, .flags = RATE_IN_242X },
-	{ .div = 0 }
-};
-
-static const struct clksel_rate vlynq_fck_core_rates[] = {
-	{ .div = 1, .val = 1, .flags = RATE_IN_242X },
-	{ .div = 2, .val = 2, .flags = RATE_IN_242X },
-	{ .div = 3, .val = 3, .flags = RATE_IN_242X },
-	{ .div = 4, .val = 4, .flags = RATE_IN_242X },
-	{ .div = 6, .val = 6, .flags = RATE_IN_242X },
-	{ .div = 8, .val = 8, .flags = RATE_IN_242X },
-	{ .div = 9, .val = 9, .flags = RATE_IN_242X },
-	{ .div = 12, .val = 12, .flags = RATE_IN_242X },
-	{ .div = 16, .val = 16, .flags = RATE_IN_242X },
-	{ .div = 18, .val = 18, .flags = RATE_IN_242X },
-	{ .div = 0 }
-};
-
-static const struct clksel vlynq_fck_clksel[] = {
-	{ .parent = &func_96m_ck, .rates = vlynq_fck_96m_rates },
-	{ .parent = &core_ck,	  .rates = vlynq_fck_core_rates },
-	{ .parent = NULL }
-};
-
-static struct clk vlynq_fck = {
-	.name		= "vlynq_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_96m_ck,
-	.clkdm_name	= "core_l3_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP2420_EN_VLYNQ_SHIFT,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1),
-	.clksel_mask	= OMAP2420_CLKSEL_VLYNQ_MASK,
-	.clksel		= vlynq_fck_clksel,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk des_ick = {
-	.name		= "des_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_ICLKEN4),
-	.enable_bit	= OMAP24XX_EN_DES_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk sha_ick = {
-	.name		= "sha_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_ICLKEN4),
-	.enable_bit	= OMAP24XX_EN_SHA_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk rng_ick = {
-	.name		= "rng_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_ICLKEN4),
-	.enable_bit	= OMAP24XX_EN_RNG_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk aes_ick = {
-	.name		= "aes_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_ICLKEN4),
-	.enable_bit	= OMAP24XX_EN_AES_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk pka_ick = {
-	.name		= "pka_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_ICLKEN4),
-	.enable_bit	= OMAP24XX_EN_PKA_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk usb_fck = {
-	.name		= "usb_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_48m_ck,
-	.clkdm_name	= "core_l3_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
-	.enable_bit	= OMAP24XX_EN_USB_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-/*
- * This clock is a composite clock which does entire set changes then
- * forces a rebalance. It keys on the MPU speed, but it really could
- * be any key speed part of a set in the rate table.
- *
- * to really change a set, you need memory table sets which get changed
- * in sram, pre-notifiers & post notifiers, changing the top set, without
- * having low level display recalc's won't work... this is why dpm notifiers
- * work, isr's off, walk a list of clocks already _off_ and not messing with
- * the bus.
- *
- * This clock should have no parent. It embodies the entire upper level
- * active set. A parent will mess up some of the init also.
- */
-static struct clk virt_prcm_set = {
-	.name		= "virt_prcm_set",
-	.ops		= &clkops_null,
-	.parent		= &mpu_ck,	/* Indexed by mpu speed, no parent */
-	.recalc		= &omap2_table_mpu_recalc,	/* sets are keyed on mpu rate */
-	.set_rate	= &omap2_select_table_rate,
-	.round_rate	= &omap2_round_to_table_rate,
-};
-
-
-/*
- * clkdev integration
- */
-
-static struct omap_clk omap2420_clks[] = {
-	/* external root sources */
-	CLK(NULL,	"func_32k_ck",	&func_32k_ck,	CK_242X),
-	CLK(NULL,	"secure_32k_ck", &secure_32k_ck, CK_242X),
-	CLK(NULL,	"osc_ck",	&osc_ck,	CK_242X),
-	CLK(NULL,	"sys_ck",	&sys_ck,	CK_242X),
-	CLK(NULL,	"alt_ck",	&alt_ck,	CK_242X),
-	CLK(NULL,	"mcbsp_clks",	&mcbsp_clks,	CK_242X),
-	/* internal analog sources */
-	CLK(NULL,	"dpll_ck",	&dpll_ck,	CK_242X),
-	CLK(NULL,	"apll96_ck",	&apll96_ck,	CK_242X),
-	CLK(NULL,	"apll54_ck",	&apll54_ck,	CK_242X),
-	/* internal prcm root sources */
-	CLK(NULL,	"func_54m_ck",	&func_54m_ck,	CK_242X),
-	CLK(NULL,	"core_ck",	&core_ck,	CK_242X),
-	CLK(NULL,	"func_96m_ck",	&func_96m_ck,	CK_242X),
-	CLK(NULL,	"func_48m_ck",	&func_48m_ck,	CK_242X),
-	CLK(NULL,	"func_12m_ck",	&func_12m_ck,	CK_242X),
-	CLK(NULL,	"ck_wdt1_osc",	&wdt1_osc_ck,	CK_242X),
-	CLK(NULL,	"sys_clkout_src", &sys_clkout_src, CK_242X),
-	CLK(NULL,	"sys_clkout",	&sys_clkout,	CK_242X),
-	CLK(NULL,	"sys_clkout2_src", &sys_clkout2_src, CK_242X),
-	CLK(NULL,	"sys_clkout2",	&sys_clkout2,	CK_242X),
-	CLK(NULL,	"emul_ck",	&emul_ck,	CK_242X),
-	/* mpu domain clocks */
-	CLK(NULL,	"mpu_ck",	&mpu_ck,	CK_242X),
-	/* dsp domain clocks */
-	CLK(NULL,	"dsp_fck",	&dsp_fck,	CK_242X),
-	CLK(NULL,	"dsp_ick",	&dsp_ick,	CK_242X),
-	CLK(NULL,	"iva1_ifck",	&iva1_ifck,	CK_242X),
-	CLK(NULL,	"iva1_mpu_int_ifck", &iva1_mpu_int_ifck, CK_242X),
-	/* GFX domain clocks */
-	CLK(NULL,	"gfx_3d_fck",	&gfx_3d_fck,	CK_242X),
-	CLK(NULL,	"gfx_2d_fck",	&gfx_2d_fck,	CK_242X),
-	CLK(NULL,	"gfx_ick",	&gfx_ick,	CK_242X),
-	/* DSS domain clocks */
-	CLK("omapdss_dss",	"ick",		&dss_ick,	CK_242X),
-	CLK(NULL,	"dss_ick",		&dss_ick,	CK_242X),
-	CLK(NULL,	"dss1_fck",		&dss1_fck,	CK_242X),
-	CLK(NULL,	"dss2_fck",	&dss2_fck,	CK_242X),
-	CLK(NULL,	"dss_54m_fck",	&dss_54m_fck,	CK_242X),
-	/* L3 domain clocks */
-	CLK(NULL,	"core_l3_ck",	&core_l3_ck,	CK_242X),
-	CLK(NULL,	"ssi_fck",	&ssi_ssr_sst_fck, CK_242X),
-	CLK(NULL,	"usb_l4_ick",	&usb_l4_ick,	CK_242X),
-	/* L4 domain clocks */
-	CLK(NULL,	"l4_ck",	&l4_ck,		CK_242X),
-	CLK(NULL,	"ssi_l4_ick",	&ssi_l4_ick,	CK_242X),
-	CLK(NULL,	"wu_l4_ick",	&wu_l4_ick,	CK_242X),
-	/* virtual meta-group clock */
-	CLK(NULL,	"virt_prcm_set", &virt_prcm_set, CK_242X),
-	/* general l4 interface ck, multi-parent functional clk */
-	CLK(NULL,	"gpt1_ick",	&gpt1_ick,	CK_242X),
-	CLK(NULL,	"gpt1_fck",	&gpt1_fck,	CK_242X),
-	CLK(NULL,	"gpt2_ick",	&gpt2_ick,	CK_242X),
-	CLK(NULL,	"gpt2_fck",	&gpt2_fck,	CK_242X),
-	CLK(NULL,	"gpt3_ick",	&gpt3_ick,	CK_242X),
-	CLK(NULL,	"gpt3_fck",	&gpt3_fck,	CK_242X),
-	CLK(NULL,	"gpt4_ick",	&gpt4_ick,	CK_242X),
-	CLK(NULL,	"gpt4_fck",	&gpt4_fck,	CK_242X),
-	CLK(NULL,	"gpt5_ick",	&gpt5_ick,	CK_242X),
-	CLK(NULL,	"gpt5_fck",	&gpt5_fck,	CK_242X),
-	CLK(NULL,	"gpt6_ick",	&gpt6_ick,	CK_242X),
-	CLK(NULL,	"gpt6_fck",	&gpt6_fck,	CK_242X),
-	CLK(NULL,	"gpt7_ick",	&gpt7_ick,	CK_242X),
-	CLK(NULL,	"gpt7_fck",	&gpt7_fck,	CK_242X),
-	CLK(NULL,	"gpt8_ick",	&gpt8_ick,	CK_242X),
-	CLK(NULL,	"gpt8_fck",	&gpt8_fck,	CK_242X),
-	CLK(NULL,	"gpt9_ick",	&gpt9_ick,	CK_242X),
-	CLK(NULL,	"gpt9_fck",	&gpt9_fck,	CK_242X),
-	CLK(NULL,	"gpt10_ick",	&gpt10_ick,	CK_242X),
-	CLK(NULL,	"gpt10_fck",	&gpt10_fck,	CK_242X),
-	CLK(NULL,	"gpt11_ick",	&gpt11_ick,	CK_242X),
-	CLK(NULL,	"gpt11_fck",	&gpt11_fck,	CK_242X),
-	CLK(NULL,	"gpt12_ick",	&gpt12_ick,	CK_242X),
-	CLK(NULL,	"gpt12_fck",	&gpt12_fck,	CK_242X),
-	CLK("omap-mcbsp.1", "ick",	&mcbsp1_ick,	CK_242X),
-	CLK(NULL,	"mcbsp1_ick",	&mcbsp1_ick,	CK_242X),
-	CLK(NULL,	"mcbsp1_fck",	&mcbsp1_fck,	CK_242X),
-	CLK("omap-mcbsp.2", "ick",	&mcbsp2_ick,	CK_242X),
-	CLK(NULL,	"mcbsp2_ick",	&mcbsp2_ick,	CK_242X),
-	CLK(NULL,	"mcbsp2_fck",	&mcbsp2_fck,	CK_242X),
-	CLK("omap2_mcspi.1", "ick",	&mcspi1_ick,	CK_242X),
-	CLK(NULL,	"mcspi1_ick",	&mcspi1_ick,	CK_242X),
-	CLK(NULL,	"mcspi1_fck",	&mcspi1_fck,	CK_242X),
-	CLK("omap2_mcspi.2", "ick",	&mcspi2_ick,	CK_242X),
-	CLK(NULL,	"mcspi2_ick",	&mcspi2_ick,	CK_242X),
-	CLK(NULL,	"mcspi2_fck",	&mcspi2_fck,	CK_242X),
-	CLK(NULL,	"uart1_ick",	&uart1_ick,	CK_242X),
-	CLK(NULL,	"uart1_fck",	&uart1_fck,	CK_242X),
-	CLK(NULL,	"uart2_ick",	&uart2_ick,	CK_242X),
-	CLK(NULL,	"uart2_fck",	&uart2_fck,	CK_242X),
-	CLK(NULL,	"uart3_ick",	&uart3_ick,	CK_242X),
-	CLK(NULL,	"uart3_fck",	&uart3_fck,	CK_242X),
-	CLK(NULL,	"gpios_ick",	&gpios_ick,	CK_242X),
-	CLK(NULL,	"gpios_fck",	&gpios_fck,	CK_242X),
-	CLK("omap_wdt",	"ick",		&mpu_wdt_ick,	CK_242X),
-	CLK(NULL,	"mpu_wdt_ick",		&mpu_wdt_ick,	CK_242X),
-	CLK(NULL,	"mpu_wdt_fck",	&mpu_wdt_fck,	CK_242X),
-	CLK(NULL,	"sync_32k_ick",	&sync_32k_ick,	CK_242X),
-	CLK(NULL,	"wdt1_ick",	&wdt1_ick,	CK_242X),
-	CLK(NULL,	"omapctrl_ick",	&omapctrl_ick,	CK_242X),
-	CLK("omap24xxcam", "fck",	&cam_fck,	CK_242X),
-	CLK(NULL,	"cam_fck",	&cam_fck,	CK_242X),
-	CLK("omap24xxcam", "ick",	&cam_ick,	CK_242X),
-	CLK(NULL,	"cam_ick",	&cam_ick,	CK_242X),
-	CLK(NULL,	"mailboxes_ick", &mailboxes_ick,	CK_242X),
-	CLK(NULL,	"wdt4_ick",	&wdt4_ick,	CK_242X),
-	CLK(NULL,	"wdt4_fck",	&wdt4_fck,	CK_242X),
-	CLK(NULL,	"wdt3_ick",	&wdt3_ick,	CK_242X),
-	CLK(NULL,	"wdt3_fck",	&wdt3_fck,	CK_242X),
-	CLK(NULL,	"mspro_ick",	&mspro_ick,	CK_242X),
-	CLK(NULL,	"mspro_fck",	&mspro_fck,	CK_242X),
-	CLK("mmci-omap.0", "ick",	&mmc_ick,	CK_242X),
-	CLK(NULL,	"mmc_ick",	&mmc_ick,	CK_242X),
-	CLK("mmci-omap.0", "fck",	&mmc_fck,	CK_242X),
-	CLK(NULL,	"mmc_fck",	&mmc_fck,	CK_242X),
-	CLK(NULL,	"fac_ick",	&fac_ick,	CK_242X),
-	CLK(NULL,	"fac_fck",	&fac_fck,	CK_242X),
-	CLK(NULL,	"eac_ick",	&eac_ick,	CK_242X),
-	CLK(NULL,	"eac_fck",	&eac_fck,	CK_242X),
-	CLK("omap_hdq.0", "ick",	&hdq_ick,	CK_242X),
-	CLK(NULL,	"hdq_ick",	&hdq_ick,	CK_242X),
-	CLK("omap_hdq.0", "fck",	&hdq_fck,	CK_242X),
-	CLK(NULL,	"hdq_fck",	&hdq_fck,	CK_242X),
-	CLK("omap_i2c.1", "ick",	&i2c1_ick,	CK_242X),
-	CLK(NULL,	"i2c1_ick",	&i2c1_ick,	CK_242X),
-	CLK(NULL,	"i2c1_fck",	&i2c1_fck,	CK_242X),
-	CLK("omap_i2c.2", "ick",	&i2c2_ick,	CK_242X),
-	CLK(NULL,	"i2c2_ick",	&i2c2_ick,	CK_242X),
-	CLK(NULL,	"i2c2_fck",	&i2c2_fck,	CK_242X),
-	CLK(NULL,	"gpmc_fck",	&gpmc_fck,	CK_242X),
-	CLK(NULL,	"sdma_fck",	&sdma_fck,	CK_242X),
-	CLK(NULL,	"sdma_ick",	&sdma_ick,	CK_242X),
-	CLK(NULL,	"sdrc_ick",	&sdrc_ick,	CK_242X),
-	CLK(NULL,	"vlynq_ick",	&vlynq_ick,	CK_242X),
-	CLK(NULL,	"vlynq_fck",	&vlynq_fck,	CK_242X),
-	CLK(NULL,	"des_ick",	&des_ick,	CK_242X),
-	CLK("omap-sham",	"ick",	&sha_ick,	CK_242X),
-	CLK(NULL,	"sha_ick",	&sha_ick,	CK_242X),
-	CLK("omap_rng",	"ick",		&rng_ick,	CK_242X),
-	CLK(NULL,	"rng_ick",		&rng_ick,	CK_242X),
-	CLK("omap-aes",	"ick",	&aes_ick,	CK_242X),
-	CLK(NULL,	"aes_ick",	&aes_ick,	CK_242X),
-	CLK(NULL,	"pka_ick",	&pka_ick,	CK_242X),
-	CLK(NULL,	"usb_fck",	&usb_fck,	CK_242X),
-	CLK("musb-hdrc",	"fck",	&osc_ck,	CK_242X),
-	CLK(NULL,	"timer_32k_ck",	&func_32k_ck,	CK_242X),
-	CLK(NULL,	"timer_sys_ck",	&sys_ck,	CK_242X),
-	CLK(NULL,	"timer_ext_ck",	&alt_ck,	CK_242X),
-	CLK(NULL,	"cpufreq_ck",	&virt_prcm_set,	CK_242X),
-};
-
-/*
- * init code
- */
-
-int __init omap2420_clk_init(void)
-{
-	struct omap_clk *c;
-
-	prcm_clksrc_ctrl = OMAP2420_PRCM_CLKSRC_CTRL;
-	cpu_mask = RATE_IN_242X;
-	rate_table = omap2420_rate_table;
-
-	for (c = omap2420_clks; c < omap2420_clks + ARRAY_SIZE(omap2420_clks);
-	     c++)
-		clk_preinit(c->lk.clk);
-
-	osc_ck.rate = omap2_osc_clk_recalc(&osc_ck);
-	propagate_rate(&osc_ck);
-	sys_ck.rate = omap2xxx_sys_clk_recalc(&sys_ck);
-	propagate_rate(&sys_ck);
-
-	for (c = omap2420_clks; c < omap2420_clks + ARRAY_SIZE(omap2420_clks);
-	     c++) {
-		clkdev_add(&c->lk);
-		clk_register(c->lk.clk);
-		omap2_init_clk_clkdm(c->lk.clk);
-	}
-
-	omap2xxx_clkt_vps_late_init();
-
-	/* Disable autoidle on all clocks; let the PM code enable it later */
-	omap_clk_disable_autoidle_all();
-
-	/* XXX Can this be done from the virt_prcm_set clk init function? */
-	omap2xxx_clkt_vps_check_bootloader_rates();
-
-	recalculate_root_clocks();
-
-	pr_info("Clocking rate (Crystal/DPLL/MPU): %ld.%01ld/%ld/%ld MHz\n",
-		(sys_ck.rate / 1000000), (sys_ck.rate / 100000) % 10,
-		(dpll_ck.rate / 1000000), (mpu_ck.rate / 1000000)) ;
-
-	/*
-	 * Only enable those clocks we will need, let the drivers
-	 * enable other clocks as necessary
-	 */
-	clk_enable_init_clocks();
-
-	return 0;
-}
-
diff --git a/arch/arm/mach-omap2/clock2430.c b/arch/arm/mach-omap2/clock2430.c
index e37df53..cef0c8d 100644
--- a/arch/arm/mach-omap2/clock2430.c
+++ b/arch/arm/mach-omap2/clock2430.c
@@ -40,7 +40,7 @@
  * passes back the correct CM_IDLEST register address for I2CHS
  * modules.  No return value.
  */
-static void omap2430_clk_i2chs_find_idlest(struct clk *clk,
+static void omap2430_clk_i2chs_find_idlest(struct clk_hw_omap *clk,
 					   void __iomem **idlest_reg,
 					   u8 *idlest_bit,
 					   u8 *idlest_val)
@@ -51,9 +51,7 @@
 }
 
 /* 2430 I2CHS has non-standard IDLEST register */
-const struct clkops clkops_omap2430_i2chs_wait = {
-	.enable		= omap2_dflt_clk_enable,
-	.disable	= omap2_dflt_clk_disable,
+const struct clk_hw_omap_ops clkhwops_omap2430_i2chs_wait = {
 	.find_idlest	= omap2430_clk_i2chs_find_idlest,
-	.find_companion = omap2_clk_dflt_find_companion,
+	.find_companion	= omap2_clk_dflt_find_companion,
 };
diff --git a/arch/arm/mach-omap2/clock2430_data.c b/arch/arm/mach-omap2/clock2430_data.c
deleted file mode 100644
index b179b6e..0000000
--- a/arch/arm/mach-omap2/clock2430_data.c
+++ /dev/null
@@ -1,2071 +0,0 @@
-/*
- * OMAP2430 clock data
- *
- * Copyright (C) 2005-2009, 2012 Texas Instruments, Inc.
- * Copyright (C) 2004-2011 Nokia Corporation
- *
- * Contacts:
- * Richard Woodruff <r-woodruff2@ti.com>
- * Paul Walmsley
- *
- * 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/clk.h>
-#include <linux/list.h>
-
-#include "soc.h"
-#include "iomap.h"
-#include "clock.h"
-#include "clock2xxx.h"
-#include "opp2xxx.h"
-#include "cm2xxx.h"
-#include "prm2xxx_3xxx.h"
-#include "prm-regbits-24xx.h"
-#include "cm-regbits-24xx.h"
-#include "sdrc.h"
-#include "control.h"
-
-#define OMAP_CM_REGADDR			OMAP2430_CM_REGADDR
-
-/*
- * 2430 clock tree.
- *
- * NOTE:In many cases here we are assigning a 'default' parent. In
- *	many cases the parent is selectable. The set parent calls will
- *	also switch sources.
- *
- *	Several sources are given initial rates which may be wrong, this will
- *	be fixed up in the init func.
- *
- *	Things are broadly separated below by clock domains. It is
- *	noteworthy that most peripherals have dependencies on multiple clock
- *	domains. Many get their interface clocks from the L4 domain, but get
- *	functional clocks from fixed sources or other core domain derived
- *	clocks.
- */
-
-/* Base external input clocks */
-static struct clk func_32k_ck = {
-	.name		= "func_32k_ck",
-	.ops		= &clkops_null,
-	.rate		= 32768,
-	.clkdm_name	= "wkup_clkdm",
-};
-
-static struct clk secure_32k_ck = {
-	.name		= "secure_32k_ck",
-	.ops		= &clkops_null,
-	.rate		= 32768,
-	.clkdm_name	= "wkup_clkdm",
-};
-
-/* Typical 12/13MHz in standalone mode, will be 26Mhz in chassis mode */
-static struct clk osc_ck = {		/* (*12, *13, 19.2, *26, 38.4)MHz */
-	.name		= "osc_ck",
-	.ops		= &clkops_oscck,
-	.clkdm_name	= "wkup_clkdm",
-	.recalc		= &omap2_osc_clk_recalc,
-};
-
-/* Without modem likely 12MHz, with modem likely 13MHz */
-static struct clk sys_ck = {		/* (*12, *13, 19.2, 26, 38.4)MHz */
-	.name		= "sys_ck",		/* ~ ref_clk also */
-	.ops		= &clkops_null,
-	.parent		= &osc_ck,
-	.clkdm_name	= "wkup_clkdm",
-	.recalc		= &omap2xxx_sys_clk_recalc,
-};
-
-static struct clk alt_ck = {		/* Typical 54M or 48M, may not exist */
-	.name		= "alt_ck",
-	.ops		= &clkops_null,
-	.rate		= 54000000,
-	.clkdm_name	= "wkup_clkdm",
-};
-
-/* Optional external clock input for McBSP CLKS */
-static struct clk mcbsp_clks = {
-	.name		= "mcbsp_clks",
-	.ops		= &clkops_null,
-};
-
-/*
- * Analog domain root source clocks
- */
-
-/* dpll_ck, is broken out in to special cases through clksel */
-/* REVISIT: Rate changes on dpll_ck trigger a full set change.	...
- * deal with this
- */
-
-static struct dpll_data dpll_dd = {
-	.mult_div1_reg		= OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1),
-	.mult_mask		= OMAP24XX_DPLL_MULT_MASK,
-	.div1_mask		= OMAP24XX_DPLL_DIV_MASK,
-	.clk_bypass		= &sys_ck,
-	.clk_ref		= &sys_ck,
-	.control_reg		= OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
-	.enable_mask		= OMAP24XX_EN_DPLL_MASK,
-	.max_multiplier		= 1023,
-	.min_divider		= 1,
-	.max_divider		= 16,
-};
-
-/*
- * XXX Cannot add round_rate here yet, as this is still a composite clock,
- * not just a DPLL
- */
-static struct clk dpll_ck = {
-	.name		= "dpll_ck",
-	.ops		= &clkops_omap2xxx_dpll_ops,
-	.parent		= &sys_ck,		/* Can be func_32k also */
-	.init		= &omap2xxx_clkt_dpllcore_init,
-	.dpll_data	= &dpll_dd,
-	.clkdm_name	= "wkup_clkdm",
-	.recalc		= &omap2_dpllcore_recalc,
-	.set_rate	= &omap2_reprogram_dpllcore,
-};
-
-static struct clk apll96_ck = {
-	.name		= "apll96_ck",
-	.ops		= &clkops_apll96,
-	.parent		= &sys_ck,
-	.rate		= 96000000,
-	.flags		= ENABLE_ON_INIT,
-	.clkdm_name	= "wkup_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
-	.enable_bit	= OMAP24XX_EN_96M_PLL_SHIFT,
-};
-
-static struct clk apll54_ck = {
-	.name		= "apll54_ck",
-	.ops		= &clkops_apll54,
-	.parent		= &sys_ck,
-	.rate		= 54000000,
-	.flags		= ENABLE_ON_INIT,
-	.clkdm_name	= "wkup_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
-	.enable_bit	= OMAP24XX_EN_54M_PLL_SHIFT,
-};
-
-/*
- * PRCM digital base sources
- */
-
-/* func_54m_ck */
-
-static const struct clksel_rate func_54m_apll54_rates[] = {
-	{ .div = 1, .val = 0, .flags = RATE_IN_24XX },
-	{ .div = 0 },
-};
-
-static const struct clksel_rate func_54m_alt_rates[] = {
-	{ .div = 1, .val = 1, .flags = RATE_IN_24XX },
-	{ .div = 0 },
-};
-
-static const struct clksel func_54m_clksel[] = {
-	{ .parent = &apll54_ck, .rates = func_54m_apll54_rates, },
-	{ .parent = &alt_ck,	.rates = func_54m_alt_rates, },
-	{ .parent = NULL },
-};
-
-static struct clk func_54m_ck = {
-	.name		= "func_54m_ck",
-	.ops		= &clkops_null,
-	.parent		= &apll54_ck,	/* can also be alt_clk */
-	.clkdm_name	= "wkup_clkdm",
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1),
-	.clksel_mask	= OMAP24XX_54M_SOURCE_MASK,
-	.clksel		= func_54m_clksel,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk core_ck = {
-	.name		= "core_ck",
-	.ops		= &clkops_null,
-	.parent		= &dpll_ck,		/* can also be 32k */
-	.clkdm_name	= "wkup_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-/* func_96m_ck */
-static const struct clksel_rate func_96m_apll96_rates[] = {
-	{ .div = 1, .val = 0, .flags = RATE_IN_24XX },
-	{ .div = 0 },
-};
-
-static const struct clksel_rate func_96m_alt_rates[] = {
-	{ .div = 1, .val = 1, .flags = RATE_IN_243X },
-	{ .div = 0 },
-};
-
-static const struct clksel func_96m_clksel[] = {
-	{ .parent = &apll96_ck,	.rates = func_96m_apll96_rates },
-	{ .parent = &alt_ck,	.rates = func_96m_alt_rates },
-	{ .parent = NULL }
-};
-
-static struct clk func_96m_ck = {
-	.name		= "func_96m_ck",
-	.ops		= &clkops_null,
-	.parent		= &apll96_ck,
-	.clkdm_name	= "wkup_clkdm",
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1),
-	.clksel_mask	= OMAP2430_96M_SOURCE_MASK,
-	.clksel		= func_96m_clksel,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-/* func_48m_ck */
-
-static const struct clksel_rate func_48m_apll96_rates[] = {
-	{ .div = 2, .val = 0, .flags = RATE_IN_24XX },
-	{ .div = 0 },
-};
-
-static const struct clksel_rate func_48m_alt_rates[] = {
-	{ .div = 1, .val = 1, .flags = RATE_IN_24XX },
-	{ .div = 0 },
-};
-
-static const struct clksel func_48m_clksel[] = {
-	{ .parent = &apll96_ck,	.rates = func_48m_apll96_rates },
-	{ .parent = &alt_ck, .rates = func_48m_alt_rates },
-	{ .parent = NULL }
-};
-
-static struct clk func_48m_ck = {
-	.name		= "func_48m_ck",
-	.ops		= &clkops_null,
-	.parent		= &apll96_ck,	 /* 96M or Alt */
-	.clkdm_name	= "wkup_clkdm",
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1),
-	.clksel_mask	= OMAP24XX_48M_SOURCE_MASK,
-	.clksel		= func_48m_clksel,
-	.recalc		= &omap2_clksel_recalc,
-	.round_rate	= &omap2_clksel_round_rate,
-	.set_rate	= &omap2_clksel_set_rate
-};
-
-static struct clk func_12m_ck = {
-	.name		= "func_12m_ck",
-	.ops		= &clkops_null,
-	.parent		= &func_48m_ck,
-	.fixed_div	= 4,
-	.clkdm_name	= "wkup_clkdm",
-	.recalc		= &omap_fixed_divisor_recalc,
-};
-
-/* Secure timer, only available in secure mode */
-static struct clk wdt1_osc_ck = {
-	.name		= "ck_wdt1_osc",
-	.ops		= &clkops_null, /* RMK: missing? */
-	.parent		= &osc_ck,
-	.recalc		= &followparent_recalc,
-};
-
-/*
- * The common_clkout* clksel_rate structs are common to
- * sys_clkout, sys_clkout_src, sys_clkout2, and sys_clkout2_src.
- * sys_clkout2_* are 2420-only, so the
- * clksel_rate flags fields are inaccurate for those clocks. This is
- * harmless since access to those clocks are gated by the struct clk
- * flags fields, which mark them as 2420-only.
- */
-static const struct clksel_rate common_clkout_src_core_rates[] = {
-	{ .div = 1, .val = 0, .flags = RATE_IN_24XX },
-	{ .div = 0 }
-};
-
-static const struct clksel_rate common_clkout_src_sys_rates[] = {
-	{ .div = 1, .val = 1, .flags = RATE_IN_24XX },
-	{ .div = 0 }
-};
-
-static const struct clksel_rate common_clkout_src_96m_rates[] = {
-	{ .div = 1, .val = 2, .flags = RATE_IN_24XX },
-	{ .div = 0 }
-};
-
-static const struct clksel_rate common_clkout_src_54m_rates[] = {
-	{ .div = 1, .val = 3, .flags = RATE_IN_24XX },
-	{ .div = 0 }
-};
-
-static const struct clksel common_clkout_src_clksel[] = {
-	{ .parent = &core_ck,	  .rates = common_clkout_src_core_rates },
-	{ .parent = &sys_ck,	  .rates = common_clkout_src_sys_rates },
-	{ .parent = &func_96m_ck, .rates = common_clkout_src_96m_rates },
-	{ .parent = &func_54m_ck, .rates = common_clkout_src_54m_rates },
-	{ .parent = NULL }
-};
-
-static struct clk sys_clkout_src = {
-	.name		= "sys_clkout_src",
-	.ops		= &clkops_omap2_dflt,
-	.parent		= &func_54m_ck,
-	.clkdm_name	= "wkup_clkdm",
-	.enable_reg	= OMAP2430_PRCM_CLKOUT_CTRL,
-	.enable_bit	= OMAP24XX_CLKOUT_EN_SHIFT,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP2430_PRCM_CLKOUT_CTRL,
-	.clksel_mask	= OMAP24XX_CLKOUT_SOURCE_MASK,
-	.clksel		= common_clkout_src_clksel,
-	.recalc		= &omap2_clksel_recalc,
-	.round_rate	= &omap2_clksel_round_rate,
-	.set_rate	= &omap2_clksel_set_rate
-};
-
-static const struct clksel_rate common_clkout_rates[] = {
-	{ .div = 1, .val = 0, .flags = RATE_IN_24XX },
-	{ .div = 2, .val = 1, .flags = RATE_IN_24XX },
-	{ .div = 4, .val = 2, .flags = RATE_IN_24XX },
-	{ .div = 8, .val = 3, .flags = RATE_IN_24XX },
-	{ .div = 16, .val = 4, .flags = RATE_IN_24XX },
-	{ .div = 0 },
-};
-
-static const struct clksel sys_clkout_clksel[] = {
-	{ .parent = &sys_clkout_src, .rates = common_clkout_rates },
-	{ .parent = NULL }
-};
-
-static struct clk sys_clkout = {
-	.name		= "sys_clkout",
-	.ops		= &clkops_null,
-	.parent		= &sys_clkout_src,
-	.clkdm_name	= "wkup_clkdm",
-	.clksel_reg	= OMAP2430_PRCM_CLKOUT_CTRL,
-	.clksel_mask	= OMAP24XX_CLKOUT_DIV_MASK,
-	.clksel		= sys_clkout_clksel,
-	.recalc		= &omap2_clksel_recalc,
-	.round_rate	= &omap2_clksel_round_rate,
-	.set_rate	= &omap2_clksel_set_rate
-};
-
-static struct clk emul_ck = {
-	.name		= "emul_ck",
-	.ops		= &clkops_omap2_dflt,
-	.parent		= &func_54m_ck,
-	.clkdm_name	= "wkup_clkdm",
-	.enable_reg	= OMAP2430_PRCM_CLKEMUL_CTRL,
-	.enable_bit	= OMAP24XX_EMULATION_EN_SHIFT,
-	.recalc		= &followparent_recalc,
-
-};
-
-/*
- * MPU clock domain
- *	Clocks:
- *		MPU_FCLK, MPU_ICLK
- *		INT_M_FCLK, INT_M_I_CLK
- *
- * - Individual clocks are hardware managed.
- * - Base divider comes from: CM_CLKSEL_MPU
- *
- */
-static const struct clksel_rate mpu_core_rates[] = {
-	{ .div = 1, .val = 1, .flags = RATE_IN_24XX },
-	{ .div = 2, .val = 2, .flags = RATE_IN_24XX },
-	{ .div = 0 },
-};
-
-static const struct clksel mpu_clksel[] = {
-	{ .parent = &core_ck, .rates = mpu_core_rates },
-	{ .parent = NULL }
-};
-
-static struct clk mpu_ck = {	/* Control cpu */
-	.name		= "mpu_ck",
-	.ops		= &clkops_null,
-	.parent		= &core_ck,
-	.clkdm_name	= "mpu_clkdm",
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(MPU_MOD, CM_CLKSEL),
-	.clksel_mask	= OMAP24XX_CLKSEL_MPU_MASK,
-	.clksel		= mpu_clksel,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-/*
- * DSP (2430-IVA2.1) clock domain
- * Clocks:
- *	2430: IVA2.1_FCLK (really just DSP_FCLK), IVA2.1_ICLK
- *
- * Won't be too specific here. The core clock comes into this block
- * it is divided then tee'ed. One branch goes directly to xyz enable
- * controls. The other branch gets further divided by 2 then possibly
- * routed into a synchronizer and out of clocks abc.
- */
-static const struct clksel_rate dsp_fck_core_rates[] = {
-	{ .div = 1, .val = 1, .flags = RATE_IN_24XX },
-	{ .div = 2, .val = 2, .flags = RATE_IN_24XX },
-	{ .div = 3, .val = 3, .flags = RATE_IN_24XX },
-	{ .div = 4, .val = 4, .flags = RATE_IN_24XX },
-	{ .div = 0 },
-};
-
-static const struct clksel dsp_fck_clksel[] = {
-	{ .parent = &core_ck, .rates = dsp_fck_core_rates },
-	{ .parent = NULL }
-};
-
-static struct clk dsp_fck = {
-	.name		= "dsp_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &core_ck,
-	.clkdm_name	= "dsp_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP24XX_CM_FCLKEN_DSP_EN_DSP_SHIFT,
-	.clksel_reg	= OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_CLKSEL),
-	.clksel_mask	= OMAP24XX_CLKSEL_DSP_MASK,
-	.clksel		= dsp_fck_clksel,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static const struct clksel dsp_ick_clksel[] = {
-	{ .parent = &dsp_fck, .rates = dsp_ick_rates },
-	{ .parent = NULL }
-};
-
-/* 2430 only - EN_DSP controls both dsp fclk and iclk on 2430 */
-static struct clk iva2_1_ick = {
-	.name		= "iva2_1_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &dsp_fck,
-	.clkdm_name	= "dsp_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP24XX_CM_FCLKEN_DSP_EN_DSP_SHIFT,
-	.clksel_reg	= OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_CLKSEL),
-	.clksel_mask	= OMAP24XX_CLKSEL_DSP_IF_MASK,
-	.clksel		= dsp_ick_clksel,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-/*
- * L3 clock domain
- * L3 clocks are used for both interface and functional clocks to
- * multiple entities. Some of these clocks are completely managed
- * by hardware, and some others allow software control. Hardware
- * managed ones general are based on directly CLK_REQ signals and
- * various auto idle settings. The functional spec sets many of these
- * as 'tie-high' for their enables.
- *
- * I-CLOCKS:
- *	L3-Interconnect, SMS, GPMC, SDRC, OCM_RAM, OCM_ROM, SDMA
- *	CAM, HS-USB.
- * F-CLOCK
- *	SSI.
- *
- * GPMC memories and SDRC have timing and clock sensitive registers which
- * may very well need notification when the clock changes. Currently for low
- * operating points, these are taken care of in sleep.S.
- */
-static const struct clksel_rate core_l3_core_rates[] = {
-	{ .div = 1, .val = 1, .flags = RATE_IN_24XX },
-	{ .div = 4, .val = 4, .flags = RATE_IN_24XX },
-	{ .div = 6, .val = 6, .flags = RATE_IN_24XX },
-	{ .div = 0 }
-};
-
-static const struct clksel core_l3_clksel[] = {
-	{ .parent = &core_ck, .rates = core_l3_core_rates },
-	{ .parent = NULL }
-};
-
-static struct clk core_l3_ck = {	/* Used for ick and fck, interconnect */
-	.name		= "core_l3_ck",
-	.ops		= &clkops_null,
-	.parent		= &core_ck,
-	.clkdm_name	= "core_l3_clkdm",
-	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1),
-	.clksel_mask	= OMAP24XX_CLKSEL_L3_MASK,
-	.clksel		= core_l3_clksel,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-/* usb_l4_ick */
-static const struct clksel_rate usb_l4_ick_core_l3_rates[] = {
-	{ .div = 1, .val = 1, .flags = RATE_IN_24XX },
-	{ .div = 2, .val = 2, .flags = RATE_IN_24XX },
-	{ .div = 4, .val = 4, .flags = RATE_IN_24XX },
-	{ .div = 0 }
-};
-
-static const struct clksel usb_l4_ick_clksel[] = {
-	{ .parent = &core_l3_ck, .rates = usb_l4_ick_core_l3_rates },
-	{ .parent = NULL },
-};
-
-/* It is unclear from TRM whether usb_l4_ick is really in L3 or L4 clkdm */
-static struct clk usb_l4_ick = {	/* FS-USB interface clock */
-	.name		= "usb_l4_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &core_l3_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
-	.enable_bit	= OMAP24XX_EN_USB_SHIFT,
-	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1),
-	.clksel_mask	= OMAP24XX_CLKSEL_USB_MASK,
-	.clksel		= usb_l4_ick_clksel,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-/*
- * L4 clock management domain
- *
- * This domain contains lots of interface clocks from the L4 interface, some
- * functional clocks.	Fixed APLL functional source clocks are managed in
- * this domain.
- */
-static const struct clksel_rate l4_core_l3_rates[] = {
-	{ .div = 1, .val = 1, .flags = RATE_IN_24XX },
-	{ .div = 2, .val = 2, .flags = RATE_IN_24XX },
-	{ .div = 0 }
-};
-
-static const struct clksel l4_clksel[] = {
-	{ .parent = &core_l3_ck, .rates = l4_core_l3_rates },
-	{ .parent = NULL }
-};
-
-static struct clk l4_ck = {		/* used both as an ick and fck */
-	.name		= "l4_ck",
-	.ops		= &clkops_null,
-	.parent		= &core_l3_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1),
-	.clksel_mask	= OMAP24XX_CLKSEL_L4_MASK,
-	.clksel		= l4_clksel,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-/*
- * SSI is in L3 management domain, its direct parent is core not l3,
- * many core power domain entities are grouped into the L3 clock
- * domain.
- * SSI_SSR_FCLK, SSI_SST_FCLK, SSI_L4_ICLK
- *
- * ssr = core/1/2/3/4/5, sst = 1/2 ssr.
- */
-static const struct clksel_rate ssi_ssr_sst_fck_core_rates[] = {
-	{ .div = 1, .val = 1, .flags = RATE_IN_24XX },
-	{ .div = 2, .val = 2, .flags = RATE_IN_24XX },
-	{ .div = 3, .val = 3, .flags = RATE_IN_24XX },
-	{ .div = 4, .val = 4, .flags = RATE_IN_24XX },
-	{ .div = 5, .val = 5, .flags = RATE_IN_243X },
-	{ .div = 0 }
-};
-
-static const struct clksel ssi_ssr_sst_fck_clksel[] = {
-	{ .parent = &core_ck, .rates = ssi_ssr_sst_fck_core_rates },
-	{ .parent = NULL }
-};
-
-static struct clk ssi_ssr_sst_fck = {
-	.name		= "ssi_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &core_ck,
-	.clkdm_name	= "core_l3_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
-	.enable_bit	= OMAP24XX_EN_SSI_SHIFT,
-	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1),
-	.clksel_mask	= OMAP24XX_CLKSEL_SSI_MASK,
-	.clksel		= ssi_ssr_sst_fck_clksel,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-/*
- * Presumably this is the same as SSI_ICLK.
- * TRM contradicts itself on what clockdomain SSI_ICLK is in
- */
-static struct clk ssi_l4_ick = {
-	.name		= "ssi_l4_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
-	.enable_bit	= OMAP24XX_EN_SSI_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-
-/*
- * GFX clock domain
- *	Clocks:
- * GFX_FCLK, GFX_ICLK
- * GFX_CG1(2d), GFX_CG2(3d)
- *
- * GFX_FCLK runs from L3, and is divided by (1,2,3,4)
- * The 2d and 3d clocks run at a hardware determined
- * divided value of fclk.
- *
- */
-
-/* This clksel struct is shared between gfx_3d_fck and gfx_2d_fck */
-static const struct clksel gfx_fck_clksel[] = {
-	{ .parent = &core_l3_ck, .rates = gfx_l3_rates },
-	{ .parent = NULL },
-};
-
-static struct clk gfx_3d_fck = {
-	.name		= "gfx_3d_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &core_l3_ck,
-	.clkdm_name	= "gfx_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(GFX_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP24XX_EN_3D_SHIFT,
-	.clksel_reg	= OMAP_CM_REGADDR(GFX_MOD, CM_CLKSEL),
-	.clksel_mask	= OMAP_CLKSEL_GFX_MASK,
-	.clksel		= gfx_fck_clksel,
-	.recalc		= &omap2_clksel_recalc,
-	.round_rate	= &omap2_clksel_round_rate,
-	.set_rate	= &omap2_clksel_set_rate
-};
-
-static struct clk gfx_2d_fck = {
-	.name		= "gfx_2d_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &core_l3_ck,
-	.clkdm_name	= "gfx_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(GFX_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP24XX_EN_2D_SHIFT,
-	.clksel_reg	= OMAP_CM_REGADDR(GFX_MOD, CM_CLKSEL),
-	.clksel_mask	= OMAP_CLKSEL_GFX_MASK,
-	.clksel		= gfx_fck_clksel,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-/* This interface clock does not have a CM_AUTOIDLE bit */
-static struct clk gfx_ick = {
-	.name		= "gfx_ick",		/* From l3 */
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &core_l3_ck,
-	.clkdm_name	= "gfx_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(GFX_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP_EN_GFX_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-/*
- * Modem clock domain (2430)
- *	CLOCKS:
- *		MDM_OSC_CLK
- *		MDM_ICLK
- * These clocks are usable in chassis mode only.
- */
-static const struct clksel_rate mdm_ick_core_rates[] = {
-	{ .div = 1, .val = 1, .flags = RATE_IN_243X },
-	{ .div = 4, .val = 4, .flags = RATE_IN_243X },
-	{ .div = 6, .val = 6, .flags = RATE_IN_243X },
-	{ .div = 9, .val = 9, .flags = RATE_IN_243X },
-	{ .div = 0 }
-};
-
-static const struct clksel mdm_ick_clksel[] = {
-	{ .parent = &core_ck, .rates = mdm_ick_core_rates },
-	{ .parent = NULL }
-};
-
-static struct clk mdm_ick = {		/* used both as a ick and fck */
-	.name		= "mdm_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &core_ck,
-	.clkdm_name	= "mdm_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(OMAP2430_MDM_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP2430_CM_ICLKEN_MDM_EN_MDM_SHIFT,
-	.clksel_reg	= OMAP_CM_REGADDR(OMAP2430_MDM_MOD, CM_CLKSEL),
-	.clksel_mask	= OMAP2430_CLKSEL_MDM_MASK,
-	.clksel		= mdm_ick_clksel,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk mdm_osc_ck = {
-	.name		= "mdm_osc_ck",
-	.ops		= &clkops_omap2_mdmclk_dflt_wait,
-	.parent		= &osc_ck,
-	.clkdm_name	= "mdm_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(OMAP2430_MDM_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP2430_EN_OSC_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-/*
- * DSS clock domain
- * CLOCKs:
- * DSS_L4_ICLK, DSS_L3_ICLK,
- * DSS_CLK1, DSS_CLK2, DSS_54MHz_CLK
- *
- * DSS is both initiator and target.
- */
-/* XXX Add RATE_NOT_VALIDATED */
-
-static const struct clksel_rate dss1_fck_sys_rates[] = {
-	{ .div = 1, .val = 0, .flags = RATE_IN_24XX },
-	{ .div = 0 }
-};
-
-static const struct clksel_rate dss1_fck_core_rates[] = {
-	{ .div = 1, .val = 1, .flags = RATE_IN_24XX },
-	{ .div = 2, .val = 2, .flags = RATE_IN_24XX },
-	{ .div = 3, .val = 3, .flags = RATE_IN_24XX },
-	{ .div = 4, .val = 4, .flags = RATE_IN_24XX },
-	{ .div = 5, .val = 5, .flags = RATE_IN_24XX },
-	{ .div = 6, .val = 6, .flags = RATE_IN_24XX },
-	{ .div = 8, .val = 8, .flags = RATE_IN_24XX },
-	{ .div = 9, .val = 9, .flags = RATE_IN_24XX },
-	{ .div = 12, .val = 12, .flags = RATE_IN_24XX },
-	{ .div = 16, .val = 16, .flags = RATE_IN_24XX },
-	{ .div = 0 }
-};
-
-static const struct clksel dss1_fck_clksel[] = {
-	{ .parent = &sys_ck,  .rates = dss1_fck_sys_rates },
-	{ .parent = &core_ck, .rates = dss1_fck_core_rates },
-	{ .parent = NULL },
-};
-
-static struct clk dss_ick = {		/* Enables both L3,L4 ICLK's */
-	.name		= "dss_ick",
-	.ops		= &clkops_omap2_iclk_dflt,
-	.parent		= &l4_ck,	/* really both l3 and l4 */
-	.clkdm_name	= "dss_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP24XX_EN_DSS1_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk dss1_fck = {
-	.name		= "dss1_fck",
-	.ops		= &clkops_omap2_dflt,
-	.parent		= &core_ck,		/* Core or sys */
-	.clkdm_name	= "dss_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP24XX_EN_DSS1_SHIFT,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1),
-	.clksel_mask	= OMAP24XX_CLKSEL_DSS1_MASK,
-	.clksel		= dss1_fck_clksel,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static const struct clksel_rate dss2_fck_sys_rates[] = {
-	{ .div = 1, .val = 0, .flags = RATE_IN_24XX },
-	{ .div = 0 }
-};
-
-static const struct clksel_rate dss2_fck_48m_rates[] = {
-	{ .div = 1, .val = 1, .flags = RATE_IN_24XX },
-	{ .div = 0 }
-};
-
-static const struct clksel dss2_fck_clksel[] = {
-	{ .parent = &sys_ck,	  .rates = dss2_fck_sys_rates },
-	{ .parent = &func_48m_ck, .rates = dss2_fck_48m_rates },
-	{ .parent = NULL }
-};
-
-static struct clk dss2_fck = {		/* Alt clk used in power management */
-	.name		= "dss2_fck",
-	.ops		= &clkops_omap2_dflt,
-	.parent		= &sys_ck,		/* fixed at sys_ck or 48MHz */
-	.clkdm_name	= "dss_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP24XX_EN_DSS2_SHIFT,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1),
-	.clksel_mask	= OMAP24XX_CLKSEL_DSS2_MASK,
-	.clksel		= dss2_fck_clksel,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk dss_54m_fck = {	/* Alt clk used in power management */
-	.name		= "dss_54m_fck",	/* 54m tv clk */
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_54m_ck,
-	.clkdm_name	= "dss_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP24XX_EN_TV_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk wu_l4_ick = {
-	.name		= "wu_l4_ick",
-	.ops		= &clkops_null,
-	.parent		= &sys_ck,
-	.clkdm_name	= "wkup_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-/*
- * CORE power domain ICLK & FCLK defines.
- * Many of the these can have more than one possible parent. Entries
- * here will likely have an L4 interface parent, and may have multiple
- * functional clock parents.
- */
-static const struct clksel_rate gpt_alt_rates[] = {
-	{ .div = 1, .val = 2, .flags = RATE_IN_24XX },
-	{ .div = 0 }
-};
-
-static const struct clksel omap24xx_gpt_clksel[] = {
-	{ .parent = &func_32k_ck, .rates = gpt_32k_rates },
-	{ .parent = &sys_ck,	  .rates = gpt_sys_rates },
-	{ .parent = &alt_ck,	  .rates = gpt_alt_rates },
-	{ .parent = NULL },
-};
-
-static struct clk gpt1_ick = {
-	.name		= "gpt1_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &wu_l4_ick,
-	.clkdm_name	= "wkup_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP24XX_EN_GPT1_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpt1_fck = {
-	.name		= "gpt1_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_32k_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP24XX_EN_GPT1_SHIFT,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_CLKSEL1),
-	.clksel_mask	= OMAP24XX_CLKSEL_GPT1_MASK,
-	.clksel		= omap24xx_gpt_clksel,
-	.recalc		= &omap2_clksel_recalc,
-	.round_rate	= &omap2_clksel_round_rate,
-	.set_rate	= &omap2_clksel_set_rate
-};
-
-static struct clk gpt2_ick = {
-	.name		= "gpt2_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP24XX_EN_GPT2_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpt2_fck = {
-	.name		= "gpt2_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_32k_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP24XX_EN_GPT2_SHIFT,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
-	.clksel_mask	= OMAP24XX_CLKSEL_GPT2_MASK,
-	.clksel		= omap24xx_gpt_clksel,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk gpt3_ick = {
-	.name		= "gpt3_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP24XX_EN_GPT3_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpt3_fck = {
-	.name		= "gpt3_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_32k_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP24XX_EN_GPT3_SHIFT,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
-	.clksel_mask	= OMAP24XX_CLKSEL_GPT3_MASK,
-	.clksel		= omap24xx_gpt_clksel,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk gpt4_ick = {
-	.name		= "gpt4_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP24XX_EN_GPT4_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpt4_fck = {
-	.name		= "gpt4_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_32k_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP24XX_EN_GPT4_SHIFT,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
-	.clksel_mask	= OMAP24XX_CLKSEL_GPT4_MASK,
-	.clksel		= omap24xx_gpt_clksel,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk gpt5_ick = {
-	.name		= "gpt5_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP24XX_EN_GPT5_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpt5_fck = {
-	.name		= "gpt5_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_32k_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP24XX_EN_GPT5_SHIFT,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
-	.clksel_mask	= OMAP24XX_CLKSEL_GPT5_MASK,
-	.clksel		= omap24xx_gpt_clksel,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk gpt6_ick = {
-	.name		= "gpt6_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP24XX_EN_GPT6_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpt6_fck = {
-	.name		= "gpt6_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_32k_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP24XX_EN_GPT6_SHIFT,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
-	.clksel_mask	= OMAP24XX_CLKSEL_GPT6_MASK,
-	.clksel		= omap24xx_gpt_clksel,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk gpt7_ick = {
-	.name		= "gpt7_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP24XX_EN_GPT7_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpt7_fck = {
-	.name		= "gpt7_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_32k_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP24XX_EN_GPT7_SHIFT,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
-	.clksel_mask	= OMAP24XX_CLKSEL_GPT7_MASK,
-	.clksel		= omap24xx_gpt_clksel,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk gpt8_ick = {
-	.name		= "gpt8_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP24XX_EN_GPT8_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpt8_fck = {
-	.name		= "gpt8_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_32k_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP24XX_EN_GPT8_SHIFT,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
-	.clksel_mask	= OMAP24XX_CLKSEL_GPT8_MASK,
-	.clksel		= omap24xx_gpt_clksel,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk gpt9_ick = {
-	.name		= "gpt9_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP24XX_EN_GPT9_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpt9_fck = {
-	.name		= "gpt9_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_32k_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP24XX_EN_GPT9_SHIFT,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
-	.clksel_mask	= OMAP24XX_CLKSEL_GPT9_MASK,
-	.clksel		= omap24xx_gpt_clksel,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk gpt10_ick = {
-	.name		= "gpt10_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP24XX_EN_GPT10_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpt10_fck = {
-	.name		= "gpt10_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_32k_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP24XX_EN_GPT10_SHIFT,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
-	.clksel_mask	= OMAP24XX_CLKSEL_GPT10_MASK,
-	.clksel		= omap24xx_gpt_clksel,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk gpt11_ick = {
-	.name		= "gpt11_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP24XX_EN_GPT11_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpt11_fck = {
-	.name		= "gpt11_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_32k_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP24XX_EN_GPT11_SHIFT,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
-	.clksel_mask	= OMAP24XX_CLKSEL_GPT11_MASK,
-	.clksel		= omap24xx_gpt_clksel,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk gpt12_ick = {
-	.name		= "gpt12_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP24XX_EN_GPT12_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpt12_fck = {
-	.name		= "gpt12_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &secure_32k_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP24XX_EN_GPT12_SHIFT,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
-	.clksel_mask	= OMAP24XX_CLKSEL_GPT12_MASK,
-	.clksel		= omap24xx_gpt_clksel,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk mcbsp1_ick = {
-	.name		= "mcbsp1_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP24XX_EN_MCBSP1_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static const struct clksel_rate common_mcbsp_96m_rates[] = {
-	{ .div = 1, .val = 0, .flags = RATE_IN_24XX },
-	{ .div = 0 }
-};
-
-static const struct clksel_rate common_mcbsp_mcbsp_rates[] = {
-	{ .div = 1, .val = 1, .flags = RATE_IN_24XX },
-	{ .div = 0 }
-};
-
-static const struct clksel mcbsp_fck_clksel[] = {
-	{ .parent = &func_96m_ck,  .rates = common_mcbsp_96m_rates },
-	{ .parent = &mcbsp_clks,   .rates = common_mcbsp_mcbsp_rates },
-	{ .parent = NULL }
-};
-
-static struct clk mcbsp1_fck = {
-	.name		= "mcbsp1_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_96m_ck,
-	.init		= &omap2_init_clksel_parent,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP24XX_EN_MCBSP1_SHIFT,
-	.clksel_reg	= OMAP243X_CTRL_REGADDR(OMAP2_CONTROL_DEVCONF0),
-	.clksel_mask	= OMAP2_MCBSP1_CLKS_MASK,
-	.clksel		= mcbsp_fck_clksel,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk mcbsp2_ick = {
-	.name		= "mcbsp2_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP24XX_EN_MCBSP2_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mcbsp2_fck = {
-	.name		= "mcbsp2_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_96m_ck,
-	.init		= &omap2_init_clksel_parent,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP24XX_EN_MCBSP2_SHIFT,
-	.clksel_reg	= OMAP243X_CTRL_REGADDR(OMAP2_CONTROL_DEVCONF0),
-	.clksel_mask	= OMAP2_MCBSP2_CLKS_MASK,
-	.clksel		= mcbsp_fck_clksel,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk mcbsp3_ick = {
-	.name		= "mcbsp3_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
-	.enable_bit	= OMAP2430_EN_MCBSP3_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mcbsp3_fck = {
-	.name		= "mcbsp3_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_96m_ck,
-	.init		= &omap2_init_clksel_parent,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
-	.enable_bit	= OMAP2430_EN_MCBSP3_SHIFT,
-	.clksel_reg	= OMAP243X_CTRL_REGADDR(OMAP243X_CONTROL_DEVCONF1),
-	.clksel_mask	= OMAP2_MCBSP3_CLKS_MASK,
-	.clksel		= mcbsp_fck_clksel,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk mcbsp4_ick = {
-	.name		= "mcbsp4_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
-	.enable_bit	= OMAP2430_EN_MCBSP4_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mcbsp4_fck = {
-	.name		= "mcbsp4_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_96m_ck,
-	.init		= &omap2_init_clksel_parent,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
-	.enable_bit	= OMAP2430_EN_MCBSP4_SHIFT,
-	.clksel_reg	= OMAP243X_CTRL_REGADDR(OMAP243X_CONTROL_DEVCONF1),
-	.clksel_mask	= OMAP2_MCBSP4_CLKS_MASK,
-	.clksel		= mcbsp_fck_clksel,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk mcbsp5_ick = {
-	.name		= "mcbsp5_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
-	.enable_bit	= OMAP2430_EN_MCBSP5_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mcbsp5_fck = {
-	.name		= "mcbsp5_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_96m_ck,
-	.init		= &omap2_init_clksel_parent,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
-	.enable_bit	= OMAP2430_EN_MCBSP5_SHIFT,
-	.clksel_reg	= OMAP243X_CTRL_REGADDR(OMAP243X_CONTROL_DEVCONF1),
-	.clksel_mask	= OMAP2_MCBSP5_CLKS_MASK,
-	.clksel		= mcbsp_fck_clksel,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk mcspi1_ick = {
-	.name		= "mcspi1_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP24XX_EN_MCSPI1_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mcspi1_fck = {
-	.name		= "mcspi1_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_48m_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP24XX_EN_MCSPI1_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mcspi2_ick = {
-	.name		= "mcspi2_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP24XX_EN_MCSPI2_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mcspi2_fck = {
-	.name		= "mcspi2_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_48m_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP24XX_EN_MCSPI2_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mcspi3_ick = {
-	.name		= "mcspi3_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
-	.enable_bit	= OMAP2430_EN_MCSPI3_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mcspi3_fck = {
-	.name		= "mcspi3_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_48m_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
-	.enable_bit	= OMAP2430_EN_MCSPI3_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk uart1_ick = {
-	.name		= "uart1_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP24XX_EN_UART1_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk uart1_fck = {
-	.name		= "uart1_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_48m_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP24XX_EN_UART1_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk uart2_ick = {
-	.name		= "uart2_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP24XX_EN_UART2_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk uart2_fck = {
-	.name		= "uart2_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_48m_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP24XX_EN_UART2_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk uart3_ick = {
-	.name		= "uart3_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
-	.enable_bit	= OMAP24XX_EN_UART3_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk uart3_fck = {
-	.name		= "uart3_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_48m_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
-	.enable_bit	= OMAP24XX_EN_UART3_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpios_ick = {
-	.name		= "gpios_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &wu_l4_ick,
-	.clkdm_name	= "wkup_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP24XX_EN_GPIOS_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpios_fck = {
-	.name		= "gpios_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_32k_ck,
-	.clkdm_name	= "wkup_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP24XX_EN_GPIOS_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mpu_wdt_ick = {
-	.name		= "mpu_wdt_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &wu_l4_ick,
-	.clkdm_name	= "wkup_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP24XX_EN_MPU_WDT_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mpu_wdt_fck = {
-	.name		= "mpu_wdt_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_32k_ck,
-	.clkdm_name	= "wkup_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP24XX_EN_MPU_WDT_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk sync_32k_ick = {
-	.name		= "sync_32k_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.flags		= ENABLE_ON_INIT,
-	.parent		= &wu_l4_ick,
-	.clkdm_name	= "wkup_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP24XX_EN_32KSYNC_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk wdt1_ick = {
-	.name		= "wdt1_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &wu_l4_ick,
-	.clkdm_name	= "wkup_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP24XX_EN_WDT1_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk omapctrl_ick = {
-	.name		= "omapctrl_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.flags		= ENABLE_ON_INIT,
-	.parent		= &wu_l4_ick,
-	.clkdm_name	= "wkup_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP24XX_EN_OMAPCTRL_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk icr_ick = {
-	.name		= "icr_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &wu_l4_ick,
-	.clkdm_name	= "wkup_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP2430_EN_ICR_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk cam_ick = {
-	.name		= "cam_ick",
-	.ops		= &clkops_omap2_iclk_dflt,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP24XX_EN_CAM_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-/*
- * cam_fck controls both CAM_MCLK and CAM_FCLK.  It should probably be
- * split into two separate clocks, since the parent clocks are different
- * and the clockdomains are also different.
- */
-static struct clk cam_fck = {
-	.name		= "cam_fck",
-	.ops		= &clkops_omap2_dflt,
-	.parent		= &func_96m_ck,
-	.clkdm_name	= "core_l3_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP24XX_EN_CAM_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mailboxes_ick = {
-	.name		= "mailboxes_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP24XX_EN_MAILBOXES_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk wdt4_ick = {
-	.name		= "wdt4_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP24XX_EN_WDT4_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk wdt4_fck = {
-	.name		= "wdt4_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_32k_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP24XX_EN_WDT4_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mspro_ick = {
-	.name		= "mspro_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP24XX_EN_MSPRO_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mspro_fck = {
-	.name		= "mspro_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_96m_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP24XX_EN_MSPRO_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk fac_ick = {
-	.name		= "fac_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP24XX_EN_FAC_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk fac_fck = {
-	.name		= "fac_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_12m_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP24XX_EN_FAC_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk hdq_ick = {
-	.name		= "hdq_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP24XX_EN_HDQ_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk hdq_fck = {
-	.name		= "hdq_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_12m_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP24XX_EN_HDQ_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-/*
- * XXX This is marked as a 2420-only define, but it claims to be present
- * on 2430 also.  Double-check.
- */
-static struct clk i2c2_ick = {
-	.name		= "i2c2_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP2420_EN_I2C2_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk i2chs2_fck = {
-	.name		= "i2chs2_fck",
-	.ops		= &clkops_omap2430_i2chs_wait,
-	.parent		= &func_96m_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
-	.enable_bit	= OMAP2430_EN_I2CHS2_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-/*
- * XXX This is marked as a 2420-only define, but it claims to be present
- * on 2430 also.  Double-check.
- */
-static struct clk i2c1_ick = {
-	.name		= "i2c1_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP2420_EN_I2C1_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk i2chs1_fck = {
-	.name		= "i2chs1_fck",
-	.ops		= &clkops_omap2430_i2chs_wait,
-	.parent		= &func_96m_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
-	.enable_bit	= OMAP2430_EN_I2CHS1_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-/*
- * The enable_reg/enable_bit in this clock is only used for CM_AUTOIDLE
- * accesses derived from this data.
- */
-static struct clk gpmc_fck = {
-	.name		= "gpmc_fck",
-	.ops		= &clkops_omap2_iclk_idle_only,
-	.parent		= &core_l3_ck,
-	.flags		= ENABLE_ON_INIT,
-	.clkdm_name	= "core_l3_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN3),
-	.enable_bit	= OMAP24XX_AUTO_GPMC_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk sdma_fck = {
-	.name		= "sdma_fck",
-	.ops		= &clkops_null, /* RMK: missing? */
-	.parent		= &core_l3_ck,
-	.clkdm_name	= "core_l3_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-/*
- * The enable_reg/enable_bit in this clock is only used for CM_AUTOIDLE
- * accesses derived from this data.
- */
-static struct clk sdma_ick = {
-	.name		= "sdma_ick",
-	.ops		= &clkops_omap2_iclk_idle_only,
-	.parent		= &core_l3_ck,
-	.clkdm_name	= "core_l3_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN3),
-	.enable_bit	= OMAP24XX_AUTO_SDMA_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk sdrc_ick = {
-	.name		= "sdrc_ick",
-	.ops		= &clkops_omap2_iclk_idle_only,
-	.parent		= &core_l3_ck,
-	.flags		= ENABLE_ON_INIT,
-	.clkdm_name	= "core_l3_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN3),
-	.enable_bit	= OMAP2430_EN_SDRC_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk des_ick = {
-	.name		= "des_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_ICLKEN4),
-	.enable_bit	= OMAP24XX_EN_DES_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk sha_ick = {
-	.name		= "sha_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_ICLKEN4),
-	.enable_bit	= OMAP24XX_EN_SHA_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk rng_ick = {
-	.name		= "rng_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_ICLKEN4),
-	.enable_bit	= OMAP24XX_EN_RNG_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk aes_ick = {
-	.name		= "aes_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_ICLKEN4),
-	.enable_bit	= OMAP24XX_EN_AES_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk pka_ick = {
-	.name		= "pka_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_ICLKEN4),
-	.enable_bit	= OMAP24XX_EN_PKA_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk usb_fck = {
-	.name		= "usb_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_48m_ck,
-	.clkdm_name	= "core_l3_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
-	.enable_bit	= OMAP24XX_EN_USB_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk usbhs_ick = {
-	.name		= "usbhs_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &core_l3_ck,
-	.clkdm_name	= "core_l3_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
-	.enable_bit	= OMAP2430_EN_USBHS_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mmchs1_ick = {
-	.name		= "mmchs1_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
-	.enable_bit	= OMAP2430_EN_MMCHS1_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mmchs1_fck = {
-	.name		= "mmchs1_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_96m_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
-	.enable_bit	= OMAP2430_EN_MMCHS1_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mmchs2_ick = {
-	.name		= "mmchs2_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
-	.enable_bit	= OMAP2430_EN_MMCHS2_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mmchs2_fck = {
-	.name		= "mmchs2_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_96m_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
-	.enable_bit	= OMAP2430_EN_MMCHS2_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpio5_ick = {
-	.name		= "gpio5_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
-	.enable_bit	= OMAP2430_EN_GPIO5_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpio5_fck = {
-	.name		= "gpio5_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_32k_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
-	.enable_bit	= OMAP2430_EN_GPIO5_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mdm_intc_ick = {
-	.name		= "mdm_intc_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &l4_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
-	.enable_bit	= OMAP2430_EN_MDM_INTC_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mmchsdb1_fck = {
-	.name		= "mmchsdb1_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_32k_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
-	.enable_bit	= OMAP2430_EN_MMCHSDB1_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mmchsdb2_fck = {
-	.name		= "mmchsdb2_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &func_32k_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
-	.enable_bit	= OMAP2430_EN_MMCHSDB2_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-/*
- * This clock is a composite clock which does entire set changes then
- * forces a rebalance. It keys on the MPU speed, but it really could
- * be any key speed part of a set in the rate table.
- *
- * to really change a set, you need memory table sets which get changed
- * in sram, pre-notifiers & post notifiers, changing the top set, without
- * having low level display recalc's won't work... this is why dpm notifiers
- * work, isr's off, walk a list of clocks already _off_ and not messing with
- * the bus.
- *
- * This clock should have no parent. It embodies the entire upper level
- * active set. A parent will mess up some of the init also.
- */
-static struct clk virt_prcm_set = {
-	.name		= "virt_prcm_set",
-	.ops		= &clkops_null,
-	.parent		= &mpu_ck,	/* Indexed by mpu speed, no parent */
-	.recalc		= &omap2_table_mpu_recalc,	/* sets are keyed on mpu rate */
-	.set_rate	= &omap2_select_table_rate,
-	.round_rate	= &omap2_round_to_table_rate,
-};
-
-
-/*
- * clkdev integration
- */
-
-static struct omap_clk omap2430_clks[] = {
-	/* external root sources */
-	CLK(NULL,	"func_32k_ck",	&func_32k_ck,	CK_243X),
-	CLK(NULL,	"secure_32k_ck", &secure_32k_ck, CK_243X),
-	CLK(NULL,	"osc_ck",	&osc_ck,	CK_243X),
-	CLK("twl",	"fck",		&osc_ck,	CK_243X),
-	CLK(NULL,	"sys_ck",	&sys_ck,	CK_243X),
-	CLK(NULL,	"alt_ck",	&alt_ck,	CK_243X),
-	CLK(NULL,	"mcbsp_clks",	&mcbsp_clks,	CK_243X),
-	/* internal analog sources */
-	CLK(NULL,	"dpll_ck",	&dpll_ck,	CK_243X),
-	CLK(NULL,	"apll96_ck",	&apll96_ck,	CK_243X),
-	CLK(NULL,	"apll54_ck",	&apll54_ck,	CK_243X),
-	/* internal prcm root sources */
-	CLK(NULL,	"func_54m_ck",	&func_54m_ck,	CK_243X),
-	CLK(NULL,	"core_ck",	&core_ck,	CK_243X),
-	CLK(NULL,	"func_96m_ck",	&func_96m_ck,	CK_243X),
-	CLK(NULL,	"func_48m_ck",	&func_48m_ck,	CK_243X),
-	CLK(NULL,	"func_12m_ck",	&func_12m_ck,	CK_243X),
-	CLK(NULL,	"ck_wdt1_osc",	&wdt1_osc_ck,	CK_243X),
-	CLK(NULL,	"sys_clkout_src", &sys_clkout_src, CK_243X),
-	CLK(NULL,	"sys_clkout",	&sys_clkout,	CK_243X),
-	CLK(NULL,	"emul_ck",	&emul_ck,	CK_243X),
-	/* mpu domain clocks */
-	CLK(NULL,	"mpu_ck",	&mpu_ck,	CK_243X),
-	/* dsp domain clocks */
-	CLK(NULL,	"dsp_fck",	&dsp_fck,	CK_243X),
-	CLK(NULL,	"iva2_1_ick",	&iva2_1_ick,	CK_243X),
-	/* GFX domain clocks */
-	CLK(NULL,	"gfx_3d_fck",	&gfx_3d_fck,	CK_243X),
-	CLK(NULL,	"gfx_2d_fck",	&gfx_2d_fck,	CK_243X),
-	CLK(NULL,	"gfx_ick",	&gfx_ick,	CK_243X),
-	/* Modem domain clocks */
-	CLK(NULL,	"mdm_ick",	&mdm_ick,	CK_243X),
-	CLK(NULL,	"mdm_osc_ck",	&mdm_osc_ck,	CK_243X),
-	/* DSS domain clocks */
-	CLK("omapdss_dss",	"ick",		&dss_ick,	CK_243X),
-	CLK(NULL,	"dss_ick",		&dss_ick,	CK_243X),
-	CLK(NULL,	"dss1_fck",		&dss1_fck,	CK_243X),
-	CLK(NULL,	"dss2_fck",	&dss2_fck,	CK_243X),
-	CLK(NULL,	"dss_54m_fck",	&dss_54m_fck,	CK_243X),
-	/* L3 domain clocks */
-	CLK(NULL,	"core_l3_ck",	&core_l3_ck,	CK_243X),
-	CLK(NULL,	"ssi_fck",	&ssi_ssr_sst_fck, CK_243X),
-	CLK(NULL,	"usb_l4_ick",	&usb_l4_ick,	CK_243X),
-	/* L4 domain clocks */
-	CLK(NULL,	"l4_ck",	&l4_ck,		CK_243X),
-	CLK(NULL,	"ssi_l4_ick",	&ssi_l4_ick,	CK_243X),
-	CLK(NULL,	"wu_l4_ick",	&wu_l4_ick,	CK_243X),
-	/* virtual meta-group clock */
-	CLK(NULL,	"virt_prcm_set", &virt_prcm_set, CK_243X),
-	/* general l4 interface ck, multi-parent functional clk */
-	CLK(NULL,	"gpt1_ick",	&gpt1_ick,	CK_243X),
-	CLK(NULL,	"gpt1_fck",	&gpt1_fck,	CK_243X),
-	CLK(NULL,	"gpt2_ick",	&gpt2_ick,	CK_243X),
-	CLK(NULL,	"gpt2_fck",	&gpt2_fck,	CK_243X),
-	CLK(NULL,	"gpt3_ick",	&gpt3_ick,	CK_243X),
-	CLK(NULL,	"gpt3_fck",	&gpt3_fck,	CK_243X),
-	CLK(NULL,	"gpt4_ick",	&gpt4_ick,	CK_243X),
-	CLK(NULL,	"gpt4_fck",	&gpt4_fck,	CK_243X),
-	CLK(NULL,	"gpt5_ick",	&gpt5_ick,	CK_243X),
-	CLK(NULL,	"gpt5_fck",	&gpt5_fck,	CK_243X),
-	CLK(NULL,	"gpt6_ick",	&gpt6_ick,	CK_243X),
-	CLK(NULL,	"gpt6_fck",	&gpt6_fck,	CK_243X),
-	CLK(NULL,	"gpt7_ick",	&gpt7_ick,	CK_243X),
-	CLK(NULL,	"gpt7_fck",	&gpt7_fck,	CK_243X),
-	CLK(NULL,	"gpt8_ick",	&gpt8_ick,	CK_243X),
-	CLK(NULL,	"gpt8_fck",	&gpt8_fck,	CK_243X),
-	CLK(NULL,	"gpt9_ick",	&gpt9_ick,	CK_243X),
-	CLK(NULL,	"gpt9_fck",	&gpt9_fck,	CK_243X),
-	CLK(NULL,	"gpt10_ick",	&gpt10_ick,	CK_243X),
-	CLK(NULL,	"gpt10_fck",	&gpt10_fck,	CK_243X),
-	CLK(NULL,	"gpt11_ick",	&gpt11_ick,	CK_243X),
-	CLK(NULL,	"gpt11_fck",	&gpt11_fck,	CK_243X),
-	CLK(NULL,	"gpt12_ick",	&gpt12_ick,	CK_243X),
-	CLK(NULL,	"gpt12_fck",	&gpt12_fck,	CK_243X),
-	CLK("omap-mcbsp.1", "ick",	&mcbsp1_ick,	CK_243X),
-	CLK(NULL,	"mcbsp1_ick",	&mcbsp1_ick,	CK_243X),
-	CLK(NULL,	"mcbsp1_fck",	&mcbsp1_fck,	CK_243X),
-	CLK("omap-mcbsp.2", "ick",	&mcbsp2_ick,	CK_243X),
-	CLK(NULL,	"mcbsp2_ick",	&mcbsp2_ick,	CK_243X),
-	CLK(NULL,	"mcbsp2_fck",	&mcbsp2_fck,	CK_243X),
-	CLK("omap-mcbsp.3", "ick",	&mcbsp3_ick,	CK_243X),
-	CLK(NULL,	"mcbsp3_ick",	&mcbsp3_ick,	CK_243X),
-	CLK(NULL,	"mcbsp3_fck",	&mcbsp3_fck,	CK_243X),
-	CLK("omap-mcbsp.4", "ick",	&mcbsp4_ick,	CK_243X),
-	CLK(NULL,	"mcbsp4_ick",	&mcbsp4_ick,	CK_243X),
-	CLK(NULL,	"mcbsp4_fck",	&mcbsp4_fck,	CK_243X),
-	CLK("omap-mcbsp.5", "ick",	&mcbsp5_ick,	CK_243X),
-	CLK(NULL,	"mcbsp5_ick",	&mcbsp5_ick,	CK_243X),
-	CLK(NULL,	"mcbsp5_fck",	&mcbsp5_fck,	CK_243X),
-	CLK("omap2_mcspi.1", "ick",	&mcspi1_ick,	CK_243X),
-	CLK(NULL,	"mcspi1_ick",	&mcspi1_ick,	CK_243X),
-	CLK(NULL,	"mcspi1_fck",	&mcspi1_fck,	CK_243X),
-	CLK("omap2_mcspi.2", "ick",	&mcspi2_ick,	CK_243X),
-	CLK(NULL,	"mcspi2_ick",	&mcspi2_ick,	CK_243X),
-	CLK(NULL,	"mcspi2_fck",	&mcspi2_fck,	CK_243X),
-	CLK("omap2_mcspi.3", "ick",	&mcspi3_ick,	CK_243X),
-	CLK(NULL,	"mcspi3_ick",	&mcspi3_ick,	CK_243X),
-	CLK(NULL,	"mcspi3_fck",	&mcspi3_fck,	CK_243X),
-	CLK(NULL,	"uart1_ick",	&uart1_ick,	CK_243X),
-	CLK(NULL,	"uart1_fck",	&uart1_fck,	CK_243X),
-	CLK(NULL,	"uart2_ick",	&uart2_ick,	CK_243X),
-	CLK(NULL,	"uart2_fck",	&uart2_fck,	CK_243X),
-	CLK(NULL,	"uart3_ick",	&uart3_ick,	CK_243X),
-	CLK(NULL,	"uart3_fck",	&uart3_fck,	CK_243X),
-	CLK(NULL,	"gpios_ick",	&gpios_ick,	CK_243X),
-	CLK(NULL,	"gpios_fck",	&gpios_fck,	CK_243X),
-	CLK("omap_wdt",	"ick",		&mpu_wdt_ick,	CK_243X),
-	CLK(NULL,	"mpu_wdt_ick",	&mpu_wdt_ick,	CK_243X),
-	CLK(NULL,	"mpu_wdt_fck",	&mpu_wdt_fck,	CK_243X),
-	CLK(NULL,	"sync_32k_ick",	&sync_32k_ick,	CK_243X),
-	CLK(NULL,	"wdt1_ick",	&wdt1_ick,	CK_243X),
-	CLK(NULL,	"omapctrl_ick",	&omapctrl_ick,	CK_243X),
-	CLK(NULL,	"icr_ick",	&icr_ick,	CK_243X),
-	CLK("omap24xxcam", "fck",	&cam_fck,	CK_243X),
-	CLK(NULL,	"cam_fck",	&cam_fck,	CK_243X),
-	CLK("omap24xxcam", "ick",	&cam_ick,	CK_243X),
-	CLK(NULL,	"cam_ick",	&cam_ick,	CK_243X),
-	CLK(NULL,	"mailboxes_ick", &mailboxes_ick,	CK_243X),
-	CLK(NULL,	"wdt4_ick",	&wdt4_ick,	CK_243X),
-	CLK(NULL,	"wdt4_fck",	&wdt4_fck,	CK_243X),
-	CLK(NULL,	"mspro_ick",	&mspro_ick,	CK_243X),
-	CLK(NULL,	"mspro_fck",	&mspro_fck,	CK_243X),
-	CLK(NULL,	"fac_ick",	&fac_ick,	CK_243X),
-	CLK(NULL,	"fac_fck",	&fac_fck,	CK_243X),
-	CLK("omap_hdq.0", "ick",	&hdq_ick,	CK_243X),
-	CLK(NULL,	"hdq_ick",	&hdq_ick,	CK_243X),
-	CLK("omap_hdq.1", "fck",	&hdq_fck,	CK_243X),
-	CLK(NULL,	"hdq_fck",	&hdq_fck,	CK_243X),
-	CLK("omap_i2c.1", "ick",	&i2c1_ick,	CK_243X),
-	CLK(NULL,	"i2c1_ick",	&i2c1_ick,	CK_243X),
-	CLK(NULL,	"i2chs1_fck",	&i2chs1_fck,	CK_243X),
-	CLK("omap_i2c.2", "ick",	&i2c2_ick,	CK_243X),
-	CLK(NULL,	"i2c2_ick",	&i2c2_ick,	CK_243X),
-	CLK(NULL,	"i2chs2_fck",	&i2chs2_fck,	CK_243X),
-	CLK(NULL,	"gpmc_fck",	&gpmc_fck,	CK_243X),
-	CLK(NULL,	"sdma_fck",	&sdma_fck,	CK_243X),
-	CLK(NULL,	"sdma_ick",	&sdma_ick,	CK_243X),
-	CLK(NULL,	"sdrc_ick",	&sdrc_ick,	CK_243X),
-	CLK(NULL,	"des_ick",	&des_ick,	CK_243X),
-	CLK("omap-sham",	"ick",	&sha_ick,	CK_243X),
-	CLK("omap_rng",	"ick",		&rng_ick,	CK_243X),
-	CLK(NULL,	"rng_ick",	&rng_ick,	CK_243X),
-	CLK("omap-aes",	"ick",	&aes_ick,	CK_243X),
-	CLK(NULL,	"pka_ick",	&pka_ick,	CK_243X),
-	CLK(NULL,	"usb_fck",	&usb_fck,	CK_243X),
-	CLK("musb-omap2430",	"ick",	&usbhs_ick,	CK_243X),
-	CLK(NULL,	"usbhs_ick",	&usbhs_ick,	CK_243X),
-	CLK("omap_hsmmc.0", "ick",	&mmchs1_ick,	CK_243X),
-	CLK(NULL,	"mmchs1_ick",	&mmchs1_ick,	CK_243X),
-	CLK(NULL,	"mmchs1_fck",	&mmchs1_fck,	CK_243X),
-	CLK("omap_hsmmc.1", "ick",	&mmchs2_ick,	CK_243X),
-	CLK(NULL,	"mmchs2_ick",	&mmchs2_ick,	CK_243X),
-	CLK(NULL,	"mmchs2_fck",	&mmchs2_fck,	CK_243X),
-	CLK(NULL,	"gpio5_ick",	&gpio5_ick,	CK_243X),
-	CLK(NULL,	"gpio5_fck",	&gpio5_fck,	CK_243X),
-	CLK(NULL,	"mdm_intc_ick",	&mdm_intc_ick,	CK_243X),
-	CLK("omap_hsmmc.0", "mmchsdb_fck",	&mmchsdb1_fck,	CK_243X),
-	CLK(NULL,	"mmchsdb1_fck",		&mmchsdb1_fck,	CK_243X),
-	CLK("omap_hsmmc.1", "mmchsdb_fck",	&mmchsdb2_fck,	CK_243X),
-	CLK(NULL,	"mmchsdb2_fck",		&mmchsdb2_fck,	CK_243X),
-	CLK(NULL,	"timer_32k_ck",  &func_32k_ck,   CK_243X),
-	CLK(NULL,	"timer_sys_ck",	&sys_ck,	CK_243X),
-	CLK(NULL,	"timer_ext_ck",	&alt_ck,	CK_243X),
-	CLK(NULL,	"cpufreq_ck",	&virt_prcm_set,	CK_243X),
-};
-
-/*
- * init code
- */
-
-int __init omap2430_clk_init(void)
-{
-	struct omap_clk *c;
-
-	prcm_clksrc_ctrl = OMAP2430_PRCM_CLKSRC_CTRL;
-	cpu_mask = RATE_IN_243X;
-	rate_table = omap2430_rate_table;
-
-	for (c = omap2430_clks; c < omap2430_clks + ARRAY_SIZE(omap2430_clks);
-	     c++)
-		clk_preinit(c->lk.clk);
-
-	osc_ck.rate = omap2_osc_clk_recalc(&osc_ck);
-	propagate_rate(&osc_ck);
-	sys_ck.rate = omap2xxx_sys_clk_recalc(&sys_ck);
-	propagate_rate(&sys_ck);
-
-	for (c = omap2430_clks; c < omap2430_clks + ARRAY_SIZE(omap2430_clks);
-	     c++) {
-		clkdev_add(&c->lk);
-		clk_register(c->lk.clk);
-		omap2_init_clk_clkdm(c->lk.clk);
-	}
-
-	omap2xxx_clkt_vps_late_init();
-
-	/* Disable autoidle on all clocks; let the PM code enable it later */
-	omap_clk_disable_autoidle_all();
-
-	/* XXX Can this be done from the virt_prcm_set clk init function? */
-	omap2xxx_clkt_vps_check_bootloader_rates();
-
-	recalculate_root_clocks();
-
-	pr_info("Clocking rate (Crystal/DPLL/MPU): %ld.%01ld/%ld/%ld MHz\n",
-		(sys_ck.rate / 1000000), (sys_ck.rate / 100000) % 10,
-		(dpll_ck.rate / 1000000), (mpu_ck.rate / 1000000)) ;
-
-	/*
-	 * Only enable those clocks we will need, let the drivers
-	 * enable other clocks as necessary
-	 */
-	clk_enable_init_clocks();
-
-	return 0;
-}
-
diff --git a/arch/arm/mach-omap2/clock2xxx.c b/arch/arm/mach-omap2/clock2xxx.c
index 5f7faeb..1ff6469 100644
--- a/arch/arm/mach-omap2/clock2xxx.c
+++ b/arch/arm/mach-omap2/clock2xxx.c
@@ -28,6 +28,7 @@
 #include "cm.h"
 #include "cm-regbits-24xx.h"
 
+struct clk_hw *dclk_hw;
 /*
  * Omap24xx specific clock functions
  */
diff --git a/arch/arm/mach-omap2/clock2xxx.h b/arch/arm/mach-omap2/clock2xxx.h
index ce809c9..539dc08 100644
--- a/arch/arm/mach-omap2/clock2xxx.h
+++ b/arch/arm/mach-omap2/clock2xxx.h
@@ -8,18 +8,32 @@
 #ifndef __ARCH_ARM_MACH_OMAP2_CLOCK2XXX_H
 #define __ARCH_ARM_MACH_OMAP2_CLOCK2XXX_H
 
-unsigned long omap2_table_mpu_recalc(struct clk *clk);
-int omap2_select_table_rate(struct clk *clk, unsigned long rate);
-long omap2_round_to_table_rate(struct clk *clk, unsigned long rate);
-unsigned long omap2xxx_sys_clk_recalc(struct clk *clk);
-unsigned long omap2_osc_clk_recalc(struct clk *clk);
-unsigned long omap2_dpllcore_recalc(struct clk *clk);
-int omap2_reprogram_dpllcore(struct clk *clk, unsigned long rate);
+#include <linux/clk-provider.h>
+#include "clock.h"
+
+unsigned long omap2_table_mpu_recalc(struct clk_hw *clk,
+				     unsigned long parent_rate);
+int omap2_select_table_rate(struct clk_hw *hw, unsigned long rate,
+			    unsigned long parent_rate);
+long omap2_round_to_table_rate(struct clk_hw *hw, unsigned long rate,
+			       unsigned long *parent_rate);
+unsigned long omap2xxx_sys_clk_recalc(struct clk_hw *clk,
+				      unsigned long parent_rate);
+unsigned long omap2_osc_clk_recalc(struct clk_hw *clk,
+				   unsigned long parent_rate);
+unsigned long omap2_dpllcore_recalc(struct clk_hw *hw,
+				    unsigned long parent_rate);
+int omap2_reprogram_dpllcore(struct clk_hw *clk, unsigned long rate,
+			     unsigned long parent_rate);
+void omap2xxx_clkt_dpllcore_init(struct clk_hw *hw);
+unsigned long omap2_clk_apll54_recalc(struct clk_hw *hw,
+				      unsigned long parent_rate);
+unsigned long omap2_clk_apll96_recalc(struct clk_hw *hw,
+				      unsigned long parent_rate);
 unsigned long omap2xxx_clk_get_core_rate(void);
 u32 omap2xxx_get_apll_clkin(void);
 u32 omap2xxx_get_sysclkdiv(void);
 void omap2xxx_clk_prepare_for_reboot(void);
-void omap2xxx_clkt_dpllcore_init(struct clk *clk);
 void omap2xxx_clkt_vps_check_bootloader_rates(void);
 void omap2xxx_clkt_vps_late_init(void);
 
@@ -37,9 +51,12 @@
 
 extern void __iomem *prcm_clksrc_ctrl;
 
-extern const struct clkops clkops_omap2430_i2chs_wait;
-extern const struct clkops clkops_oscck;
-extern const struct clkops clkops_apll96;
-extern const struct clkops clkops_apll54;
+extern struct clk_hw *dclk_hw;
+int omap2_enable_osc_ck(struct clk_hw *hw);
+void omap2_disable_osc_ck(struct clk_hw *hw);
+int omap2_clk_apll96_enable(struct clk_hw *hw);
+int omap2_clk_apll54_enable(struct clk_hw *hw);
+void omap2_clk_apll96_disable(struct clk_hw *hw);
+void omap2_clk_apll54_disable(struct clk_hw *hw);
 
 #endif
diff --git a/arch/arm/mach-omap2/clock33xx_data.c b/arch/arm/mach-omap2/clock33xx_data.c
deleted file mode 100644
index 17e3de5..0000000
--- a/arch/arm/mach-omap2/clock33xx_data.c
+++ /dev/null
@@ -1,1109 +0,0 @@
-/*
- * AM33XX Clock data
- *
- * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
- * Vaibhav Hiremath <hvaibhav@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/list.h>
-#include <linux/clk.h>
-
-#include "soc.h"
-#include "iomap.h"
-#include "control.h"
-#include "clock.h"
-#include "cm.h"
-#include "cm33xx.h"
-#include "cm-regbits-33xx.h"
-#include "prm.h"
-
-/* Maximum DPLL multiplier, divider values for AM33XX */
-#define AM33XX_MAX_DPLL_MULT		2047
-#define AM33XX_MAX_DPLL_DIV		128
-
-/* Modulemode control */
-#define AM33XX_MODULEMODE_HWCTRL	0
-#define AM33XX_MODULEMODE_SWCTRL	1
-
-/* TRM ERRATA: Timer 3 & 6 default parent (TCLKIN) may not be always
- *    physically present, in such a case HWMOD enabling of
- *    clock would be failure with default parent. And timer
- *    probe thinks clock is already enabled, this leads to
- *    crash upon accessing timer 3 & 6 registers in probe.
- *    Fix by setting parent of both these timers to master
- *    oscillator clock.
- */
-static inline void am33xx_init_timer_parent(struct clk *clk)
-{
-	omap2_clksel_set_parent(clk, clk->parent);
-}
-
-/* Root clocks */
-
-/* RTC 32k */
-static struct clk clk_32768_ck = {
-	.name		= "clk_32768_ck",
-	.clkdm_name	= "l4_rtc_clkdm",
-	.rate		= 32768,
-	.ops		= &clkops_null,
-};
-
-/* On-Chip 32KHz RC OSC */
-static struct clk clk_rc32k_ck = {
-	.name		= "clk_rc32k_ck",
-	.rate		= 32000,
-	.ops		= &clkops_null,
-};
-
-/* Crystal input clks */
-static struct clk virt_24000000_ck = {
-	.name		= "virt_24000000_ck",
-	.rate		= 24000000,
-	.ops		= &clkops_null,
-};
-
-static struct clk virt_25000000_ck = {
-	.name		= "virt_25000000_ck",
-	.rate		= 25000000,
-	.ops		= &clkops_null,
-};
-
-/* Oscillator clock */
-/* 19.2, 24, 25 or 26 MHz */
-static const struct clksel sys_clkin_sel[] = {
-	{ .parent = &virt_19200000_ck, .rates = div_1_0_rates },
-	{ .parent = &virt_24000000_ck, .rates = div_1_1_rates },
-	{ .parent = &virt_25000000_ck, .rates = div_1_2_rates },
-	{ .parent = &virt_26000000_ck, .rates = div_1_3_rates },
-	{ .parent = NULL },
-};
-
-/* External clock - 12 MHz */
-static struct clk tclkin_ck = {
-	.name		= "tclkin_ck",
-	.rate		= 12000000,
-	.ops		= &clkops_null,
-};
-
-/*
- * sys_clk in: input to the dpll and also used as funtional clock for,
- *   adc_tsc, smartreflex0-1, timer1-7, mcasp0-1, dcan0-1, cefuse
- *
- */
-static struct clk sys_clkin_ck = {
-	.name		= "sys_clkin_ck",
-	.parent		= &virt_24000000_ck,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= AM33XX_CTRL_REGADDR(AM33XX_CONTROL_STATUS),
-	.clksel_mask	= AM33XX_CONTROL_STATUS_SYSBOOT1_MASK,
-	.clksel		= sys_clkin_sel,
-	.ops		= &clkops_null,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-/* DPLL_CORE */
-static struct dpll_data dpll_core_dd = {
-	.mult_div1_reg	= AM33XX_CM_CLKSEL_DPLL_CORE,
-	.clk_bypass	= &sys_clkin_ck,
-	.clk_ref	= &sys_clkin_ck,
-	.control_reg	= AM33XX_CM_CLKMODE_DPLL_CORE,
-	.modes		= (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
-	.idlest_reg	= AM33XX_CM_IDLEST_DPLL_CORE,
-	.mult_mask	= AM33XX_DPLL_MULT_MASK,
-	.div1_mask	= AM33XX_DPLL_DIV_MASK,
-	.enable_mask	= AM33XX_DPLL_EN_MASK,
-	.idlest_mask	= AM33XX_ST_DPLL_CLK_MASK,
-	.max_multiplier	= AM33XX_MAX_DPLL_MULT,
-	.max_divider	= AM33XX_MAX_DPLL_DIV,
-	.min_divider	= 1,
-};
-
-/* CLKDCOLDO output */
-static struct clk dpll_core_ck = {
-	.name		= "dpll_core_ck",
-	.parent		= &sys_clkin_ck,
-	.dpll_data	= &dpll_core_dd,
-	.init		= &omap2_init_dpll_parent,
-	.ops		= &clkops_omap3_core_dpll_ops,
-	.recalc		= &omap3_dpll_recalc,
-};
-
-static struct clk dpll_core_x2_ck = {
-	.name		= "dpll_core_x2_ck",
-	.parent		= &dpll_core_ck,
-	.flags		= CLOCK_CLKOUTX2,
-	.ops		= &clkops_null,
-	.recalc		= &omap3_clkoutx2_recalc,
-};
-
-
-static const struct clksel dpll_core_m4_div[] = {
-	{ .parent = &dpll_core_x2_ck, .rates = div31_1to31_rates },
-	{ .parent = NULL },
-};
-
-static struct clk dpll_core_m4_ck = {
-	.name		= "dpll_core_m4_ck",
-	.parent		= &dpll_core_x2_ck,
-	.init		= &omap2_init_clksel_parent,
-	.clksel		= dpll_core_m4_div,
-	.clksel_reg	= AM33XX_CM_DIV_M4_DPLL_CORE,
-	.clksel_mask	= AM33XX_HSDIVIDER_CLKOUT1_DIV_MASK,
-	.ops		= &clkops_null,
-	.recalc		= &omap2_clksel_recalc,
-	.round_rate	= &omap2_clksel_round_rate,
-	.set_rate	= &omap2_clksel_set_rate,
-};
-
-static const struct clksel dpll_core_m5_div[] = {
-	{ .parent = &dpll_core_x2_ck, .rates = div31_1to31_rates },
-	{ .parent = NULL },
-};
-
-static struct clk dpll_core_m5_ck = {
-	.name		= "dpll_core_m5_ck",
-	.parent		= &dpll_core_x2_ck,
-	.init		= &omap2_init_clksel_parent,
-	.clksel		= dpll_core_m5_div,
-	.clksel_reg	= AM33XX_CM_DIV_M5_DPLL_CORE,
-	.clksel_mask	= AM33XX_HSDIVIDER_CLKOUT2_DIV_MASK,
-	.ops		= &clkops_null,
-	.recalc		= &omap2_clksel_recalc,
-	.round_rate	= &omap2_clksel_round_rate,
-	.set_rate	= &omap2_clksel_set_rate,
-};
-
-static const struct clksel dpll_core_m6_div[] = {
-	{ .parent = &dpll_core_x2_ck, .rates = div31_1to31_rates },
-	{ .parent = NULL },
-};
-
-static struct clk dpll_core_m6_ck = {
-	.name		= "dpll_core_m6_ck",
-	.parent		= &dpll_core_x2_ck,
-	.init		= &omap2_init_clksel_parent,
-	.clksel		= dpll_core_m6_div,
-	.clksel_reg	= AM33XX_CM_DIV_M6_DPLL_CORE,
-	.clksel_mask	= AM33XX_HSDIVIDER_CLKOUT3_DIV_MASK,
-	.ops		= &clkops_null,
-	.recalc		= &omap2_clksel_recalc,
-	.round_rate	= &omap2_clksel_round_rate,
-	.set_rate	= &omap2_clksel_set_rate,
-};
-
-/* DPLL_MPU */
-static struct dpll_data dpll_mpu_dd = {
-	.mult_div1_reg	= AM33XX_CM_CLKSEL_DPLL_MPU,
-	.clk_bypass	= &sys_clkin_ck,
-	.clk_ref	= &sys_clkin_ck,
-	.control_reg	= AM33XX_CM_CLKMODE_DPLL_MPU,
-	.modes		= (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
-	.idlest_reg	= AM33XX_CM_IDLEST_DPLL_MPU,
-	.mult_mask	= AM33XX_DPLL_MULT_MASK,
-	.div1_mask	= AM33XX_DPLL_DIV_MASK,
-	.enable_mask	= AM33XX_DPLL_EN_MASK,
-	.idlest_mask	= AM33XX_ST_DPLL_CLK_MASK,
-	.max_multiplier	= AM33XX_MAX_DPLL_MULT,
-	.max_divider	= AM33XX_MAX_DPLL_DIV,
-	.min_divider	= 1,
-};
-
-/* CLKOUT: fdpll/M2 */
-static struct clk dpll_mpu_ck = {
-	.name		= "dpll_mpu_ck",
-	.parent		= &sys_clkin_ck,
-	.dpll_data	= &dpll_mpu_dd,
-	.init		= &omap2_init_dpll_parent,
-	.ops		= &clkops_omap3_noncore_dpll_ops,
-	.recalc		= &omap3_dpll_recalc,
-	.round_rate	= &omap2_dpll_round_rate,
-	.set_rate	= &omap3_noncore_dpll_set_rate,
-};
-
-/*
- * TODO: Add clksel here (sys_clkin, CORE_CLKOUTM6, PER_CLKOUTM2
- * and ALT_CLK1/2)
- */
-static const struct clksel dpll_mpu_m2_div[] = {
-	{ .parent = &dpll_mpu_ck, .rates = div31_1to31_rates },
-	{ .parent = NULL },
-};
-
-static struct clk dpll_mpu_m2_ck = {
-	.name		= "dpll_mpu_m2_ck",
-	.clkdm_name	= "mpu_clkdm",
-	.parent		= &dpll_mpu_ck,
-	.clksel		= dpll_mpu_m2_div,
-	.clksel_reg	= AM33XX_CM_DIV_M2_DPLL_MPU,
-	.clksel_mask	= AM33XX_DPLL_CLKOUT_DIV_MASK,
-	.ops		= &clkops_null,
-	.recalc		= &omap2_clksel_recalc,
-	.round_rate	= &omap2_clksel_round_rate,
-	.set_rate	= &omap2_clksel_set_rate,
-};
-
-/* DPLL_DDR */
-static struct dpll_data dpll_ddr_dd = {
-	.mult_div1_reg	= AM33XX_CM_CLKSEL_DPLL_DDR,
-	.clk_bypass	= &sys_clkin_ck,
-	.clk_ref	= &sys_clkin_ck,
-	.control_reg	= AM33XX_CM_CLKMODE_DPLL_DDR,
-	.modes		= (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
-	.idlest_reg	= AM33XX_CM_IDLEST_DPLL_DDR,
-	.mult_mask	= AM33XX_DPLL_MULT_MASK,
-	.div1_mask	= AM33XX_DPLL_DIV_MASK,
-	.enable_mask	= AM33XX_DPLL_EN_MASK,
-	.idlest_mask	= AM33XX_ST_DPLL_CLK_MASK,
-	.max_multiplier	= AM33XX_MAX_DPLL_MULT,
-	.max_divider	= AM33XX_MAX_DPLL_DIV,
-	.min_divider	= 1,
-};
-
-/* CLKOUT: fdpll/M2 */
-static struct clk dpll_ddr_ck = {
-	.name		= "dpll_ddr_ck",
-	.parent		= &sys_clkin_ck,
-	.dpll_data	= &dpll_ddr_dd,
-	.init		= &omap2_init_dpll_parent,
-	.ops		= &clkops_null,
-	.recalc		= &omap3_dpll_recalc,
-};
-
-/*
- * TODO: Add clksel here (sys_clkin, CORE_CLKOUTM6, PER_CLKOUTM2
- * and ALT_CLK1/2)
- */
-static const struct clksel dpll_ddr_m2_div[] = {
-	{ .parent = &dpll_ddr_ck, .rates = div31_1to31_rates },
-	{ .parent = NULL },
-};
-
-static struct clk dpll_ddr_m2_ck = {
-	.name		= "dpll_ddr_m2_ck",
-	.parent		= &dpll_ddr_ck,
-	.clksel		= dpll_ddr_m2_div,
-	.clksel_reg	= AM33XX_CM_DIV_M2_DPLL_DDR,
-	.clksel_mask	= AM33XX_DPLL_CLKOUT_DIV_MASK,
-	.ops		= &clkops_null,
-	.recalc		= &omap2_clksel_recalc,
-	.round_rate	= &omap2_clksel_round_rate,
-	.set_rate	= &omap2_clksel_set_rate,
-};
-
-/* emif_fck functional clock */
-static struct clk dpll_ddr_m2_div2_ck = {
-	.name		= "dpll_ddr_m2_div2_ck",
-	.clkdm_name	= "l3_clkdm",
-	.parent		= &dpll_ddr_m2_ck,
-	.ops		= &clkops_null,
-	.fixed_div	= 2,
-	.recalc		= &omap_fixed_divisor_recalc,
-};
-
-/* DPLL_DISP */
-static struct dpll_data dpll_disp_dd = {
-	.mult_div1_reg	= AM33XX_CM_CLKSEL_DPLL_DISP,
-	.clk_bypass	= &sys_clkin_ck,
-	.clk_ref	= &sys_clkin_ck,
-	.control_reg	= AM33XX_CM_CLKMODE_DPLL_DISP,
-	.modes		= (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
-	.idlest_reg	= AM33XX_CM_IDLEST_DPLL_DISP,
-	.mult_mask	= AM33XX_DPLL_MULT_MASK,
-	.div1_mask	= AM33XX_DPLL_DIV_MASK,
-	.enable_mask	= AM33XX_DPLL_EN_MASK,
-	.idlest_mask	= AM33XX_ST_DPLL_CLK_MASK,
-	.max_multiplier	= AM33XX_MAX_DPLL_MULT,
-	.max_divider	= AM33XX_MAX_DPLL_DIV,
-	.min_divider	= 1,
-};
-
-/* CLKOUT: fdpll/M2 */
-static struct clk dpll_disp_ck = {
-	.name		= "dpll_disp_ck",
-	.parent		= &sys_clkin_ck,
-	.dpll_data	= &dpll_disp_dd,
-	.init		= &omap2_init_dpll_parent,
-	.ops		= &clkops_null,
-	.recalc		= &omap3_dpll_recalc,
-	.round_rate	= &omap2_dpll_round_rate,
-	.set_rate	= &omap3_noncore_dpll_set_rate,
-};
-
-/*
- * TODO: Add clksel here (sys_clkin, CORE_CLKOUTM6, PER_CLKOUTM2
- * and ALT_CLK1/2)
- */
-static const struct clksel dpll_disp_m2_div[] = {
-	{ .parent = &dpll_disp_ck, .rates = div31_1to31_rates },
-	{ .parent = NULL },
-};
-
-static struct clk dpll_disp_m2_ck = {
-	.name		= "dpll_disp_m2_ck",
-	.parent		= &dpll_disp_ck,
-	.clksel		= dpll_disp_m2_div,
-	.clksel_reg	= AM33XX_CM_DIV_M2_DPLL_DISP,
-	.clksel_mask	= AM33XX_DPLL_CLKOUT_DIV_MASK,
-	.ops		= &clkops_null,
-	.recalc		= &omap2_clksel_recalc,
-	.round_rate	= &omap2_clksel_round_rate,
-	.set_rate	= &omap2_clksel_set_rate,
-};
-
-/* DPLL_PER */
-static struct dpll_data dpll_per_dd = {
-	.mult_div1_reg	= AM33XX_CM_CLKSEL_DPLL_PERIPH,
-	.clk_bypass	= &sys_clkin_ck,
-	.clk_ref	= &sys_clkin_ck,
-	.control_reg	= AM33XX_CM_CLKMODE_DPLL_PER,
-	.modes		= (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
-	.idlest_reg	= AM33XX_CM_IDLEST_DPLL_PER,
-	.mult_mask	= AM33XX_DPLL_MULT_PERIPH_MASK,
-	.div1_mask	= AM33XX_DPLL_PER_DIV_MASK,
-	.enable_mask	= AM33XX_DPLL_EN_MASK,
-	.idlest_mask	= AM33XX_ST_DPLL_CLK_MASK,
-	.max_multiplier	= AM33XX_MAX_DPLL_MULT,
-	.max_divider	= AM33XX_MAX_DPLL_DIV,
-	.min_divider	= 1,
-	.flags		= DPLL_J_TYPE,
-};
-
-/* CLKDCOLDO */
-static struct clk dpll_per_ck = {
-	.name		= "dpll_per_ck",
-	.parent		= &sys_clkin_ck,
-	.dpll_data	= &dpll_per_dd,
-	.init		= &omap2_init_dpll_parent,
-	.ops		= &clkops_null,
-	.recalc		= &omap3_dpll_recalc,
-	.round_rate	= &omap2_dpll_round_rate,
-	.set_rate	= &omap3_noncore_dpll_set_rate,
-};
-
-/* CLKOUT: fdpll/M2 */
-static const struct clksel dpll_per_m2_div[] = {
-	{ .parent = &dpll_per_ck, .rates = div31_1to31_rates },
-	{ .parent = NULL },
-};
-
-static struct clk dpll_per_m2_ck = {
-	.name		= "dpll_per_m2_ck",
-	.parent		= &dpll_per_ck,
-	.clksel		= dpll_per_m2_div,
-	.clksel_reg	= AM33XX_CM_DIV_M2_DPLL_PER,
-	.clksel_mask	= AM33XX_DPLL_CLKOUT_DIV_MASK,
-	.ops		= &clkops_null,
-	.recalc		= &omap2_clksel_recalc,
-	.round_rate	= &omap2_clksel_round_rate,
-	.set_rate	= &omap2_clksel_set_rate,
-};
-
-static struct clk dpll_per_m2_div4_wkupdm_ck = {
-	.name		= "dpll_per_m2_div4_wkupdm_ck",
-	.clkdm_name	= "l4_wkup_clkdm",
-	.parent		= &dpll_per_m2_ck,
-	.fixed_div	= 4,
-	.ops		= &clkops_null,
-	.recalc		= &omap_fixed_divisor_recalc,
-};
-
-static struct clk dpll_per_m2_div4_ck = {
-	.name		= "dpll_per_m2_div4_ck",
-	.clkdm_name	= "l4ls_clkdm",
-	.parent		= &dpll_per_m2_ck,
-	.fixed_div	= 4,
-	.ops		= &clkops_null,
-	.recalc		= &omap_fixed_divisor_recalc,
-};
-
-static struct clk l3_gclk = {
-	.name		= "l3_gclk",
-	.clkdm_name	= "l3_clkdm",
-	.parent		= &dpll_core_m4_ck,
-	.ops		= &clkops_null,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk dpll_core_m4_div2_ck = {
-	.name		= "dpll_core_m4_div2_ck",
-	.clkdm_name	= "l4_wkup_clkdm",
-	.parent		= &dpll_core_m4_ck,
-	.ops		= &clkops_null,
-	.fixed_div	= 2,
-	.recalc		= &omap_fixed_divisor_recalc,
-};
-
-static struct clk l4_rtc_gclk = {
-	.name		= "l4_rtc_gclk",
-	.parent		= &dpll_core_m4_ck,
-	.ops		= &clkops_null,
-	.fixed_div	= 2,
-	.recalc		= &omap_fixed_divisor_recalc,
-};
-
-static struct clk clk_24mhz = {
-	.name		= "clk_24mhz",
-	.parent		= &dpll_per_m2_ck,
-	.fixed_div	= 8,
-	.ops		= &clkops_null,
-	.recalc		= &omap_fixed_divisor_recalc,
-};
-
-/*
- * Below clock nodes describes clockdomains derived out
- * of core clock.
- */
-static struct clk l4hs_gclk = {
-	.name		= "l4hs_gclk",
-	.clkdm_name	= "l4hs_clkdm",
-	.parent		= &dpll_core_m4_ck,
-	.ops		= &clkops_null,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk l3s_gclk = {
-	.name		= "l3s_gclk",
-	.clkdm_name	= "l3s_clkdm",
-	.parent		= &dpll_core_m4_div2_ck,
-	.ops		= &clkops_null,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk l4fw_gclk = {
-	.name		= "l4fw_gclk",
-	.clkdm_name	= "l4fw_clkdm",
-	.parent		= &dpll_core_m4_div2_ck,
-	.ops		= &clkops_null,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk l4ls_gclk = {
-	.name		= "l4ls_gclk",
-	.clkdm_name	= "l4ls_clkdm",
-	.parent		= &dpll_core_m4_div2_ck,
-	.ops		= &clkops_null,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk sysclk_div_ck = {
-	.name		= "sysclk_div_ck",
-	.parent		= &dpll_core_m4_ck,
-	.ops		= &clkops_null,
-	.recalc		= &followparent_recalc,
-};
-
-/*
- * In order to match the clock domain with hwmod clockdomain entry,
- * separate clock nodes is required for the modules which are
- * directly getting their funtioncal clock from sys_clkin.
- */
-static struct clk adc_tsc_fck = {
-	.name		= "adc_tsc_fck",
-	.clkdm_name	= "l4_wkup_clkdm",
-	.parent		= &sys_clkin_ck,
-	.ops		= &clkops_null,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk dcan0_fck = {
-	.name		= "dcan0_fck",
-	.clkdm_name	= "l4ls_clkdm",
-	.parent		= &sys_clkin_ck,
-	.ops		= &clkops_null,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk dcan1_fck = {
-	.name		= "dcan1_fck",
-	.clkdm_name	= "l4ls_clkdm",
-	.parent		= &sys_clkin_ck,
-	.ops		= &clkops_null,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mcasp0_fck = {
-	.name		= "mcasp0_fck",
-	.clkdm_name	= "l3s_clkdm",
-	.parent		= &sys_clkin_ck,
-	.ops		= &clkops_null,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mcasp1_fck = {
-	.name		= "mcasp1_fck",
-	.clkdm_name	= "l3s_clkdm",
-	.parent		= &sys_clkin_ck,
-	.ops		= &clkops_null,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk smartreflex0_fck = {
-	.name		= "smartreflex0_fck",
-	.clkdm_name	= "l4_wkup_clkdm",
-	.parent		= &sys_clkin_ck,
-	.ops		= &clkops_null,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk smartreflex1_fck = {
-	.name		= "smartreflex1_fck",
-	.clkdm_name	= "l4_wkup_clkdm",
-	.parent		= &sys_clkin_ck,
-	.ops		= &clkops_null,
-	.recalc		= &followparent_recalc,
-};
-
-/*
- * Modules clock nodes
- *
- * The following clock leaf nodes are added for the moment because:
- *
- *  - hwmod data is not present for these modules, either hwmod
- *    control is not required or its not populated.
- *  - Driver code is not yet migrated to use hwmod/runtime pm
- *  - Modules outside kernel access (to disable them by default)
- *
- *     - debugss
- *     - mmu (gfx domain)
- *     - cefuse
- *     - usbotg_fck (its additional clock and not really a modulemode)
- *     - ieee5000
- */
-static struct clk debugss_ick = {
-	.name		= "debugss_ick",
-	.clkdm_name	= "l3_aon_clkdm",
-	.parent		= &dpll_core_m4_ck,
-	.ops		= &clkops_omap2_dflt,
-	.enable_reg	= AM33XX_CM_WKUP_DEBUGSS_CLKCTRL,
-	.enable_bit	= AM33XX_MODULEMODE_SWCTRL,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mmu_fck = {
-	.name		= "mmu_fck",
-	.clkdm_name	= "gfx_l3_clkdm",
-	.parent		= &dpll_core_m4_ck,
-	.ops		= &clkops_omap2_dflt,
-	.enable_reg	= AM33XX_CM_GFX_MMUDATA_CLKCTRL,
-	.enable_bit	= AM33XX_MODULEMODE_SWCTRL,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk cefuse_fck = {
-	.name		= "cefuse_fck",
-	.clkdm_name	= "l4_cefuse_clkdm",
-	.parent		= &sys_clkin_ck,
-	.enable_reg	= AM33XX_CM_CEFUSE_CEFUSE_CLKCTRL,
-	.enable_bit	= AM33XX_MODULEMODE_SWCTRL,
-	.ops		= &clkops_omap2_dflt,
-	.recalc		= &followparent_recalc,
-};
-
-/*
- * clkdiv32 is generated from fixed division of 732.4219
- */
-static struct clk clkdiv32k_ick = {
-	.name		= "clkdiv32k_ick",
-	.clkdm_name	= "clk_24mhz_clkdm",
-	.rate		= 32768,
-	.parent		= &clk_24mhz,
-	.enable_reg	= AM33XX_CM_PER_CLKDIV32K_CLKCTRL,
-	.enable_bit	= AM33XX_MODULEMODE_SWCTRL,
-	.ops		= &clkops_omap2_dflt,
-};
-
-static struct clk usbotg_fck = {
-	.name		= "usbotg_fck",
-	.clkdm_name	= "l3s_clkdm",
-	.parent		= &dpll_per_ck,
-	.enable_reg	= AM33XX_CM_CLKDCOLDO_DPLL_PER,
-	.enable_bit	= AM33XX_ST_DPLL_CLKDCOLDO_SHIFT,
-	.ops		= &clkops_omap2_dflt,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk ieee5000_fck = {
-	.name		= "ieee5000_fck",
-	.clkdm_name	= "l3s_clkdm",
-	.parent		= &dpll_core_m4_div2_ck,
-	.enable_reg	= AM33XX_CM_PER_IEEE5000_CLKCTRL,
-	.enable_bit	= AM33XX_MODULEMODE_SWCTRL,
-	.ops		= &clkops_omap2_dflt,
-	.recalc		= &followparent_recalc,
-};
-
-/* Timers */
-static const struct clksel timer1_clkmux_sel[] = {
-	{ .parent = &sys_clkin_ck, .rates = div_1_0_rates },
-	{ .parent = &clkdiv32k_ick, .rates = div_1_1_rates },
-	{ .parent = &tclkin_ck, .rates = div_1_2_rates },
-	{ .parent = &clk_rc32k_ck, .rates = div_1_3_rates },
-	{ .parent = &clk_32768_ck, .rates = div_1_4_rates },
-	{ .parent = NULL },
-};
-
-static struct clk timer1_fck = {
-	.name		= "timer1_fck",
-	.clkdm_name	= "l4ls_clkdm",
-	.parent		= &sys_clkin_ck,
-	.init		= &omap2_init_clksel_parent,
-	.clksel		= timer1_clkmux_sel,
-	.clksel_reg	= AM33XX_CLKSEL_TIMER1MS_CLK,
-	.clksel_mask	= AM33XX_CLKSEL_0_2_MASK,
-	.ops		= &clkops_null,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static const struct clksel timer2_to_7_clk_sel[] = {
-	{ .parent = &tclkin_ck, .rates = div_1_0_rates },
-	{ .parent = &sys_clkin_ck, .rates = div_1_1_rates },
-	{ .parent = &clkdiv32k_ick, .rates = div_1_2_rates },
-	{ .parent = NULL },
-};
-
-static struct clk timer2_fck = {
-	.name		= "timer2_fck",
-	.clkdm_name	= "l4ls_clkdm",
-	.parent		= &sys_clkin_ck,
-	.init		= &omap2_init_clksel_parent,
-	.clksel		= timer2_to_7_clk_sel,
-	.clksel_reg	= AM33XX_CLKSEL_TIMER2_CLK,
-	.clksel_mask	= AM33XX_CLKSEL_0_1_MASK,
-	.ops		= &clkops_null,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk timer3_fck = {
-	.name		= "timer3_fck",
-	.clkdm_name	= "l4ls_clkdm",
-	.parent		= &sys_clkin_ck,
-	.init		= &am33xx_init_timer_parent,
-	.clksel		= timer2_to_7_clk_sel,
-	.clksel_reg	= AM33XX_CLKSEL_TIMER3_CLK,
-	.clksel_mask	= AM33XX_CLKSEL_0_1_MASK,
-	.ops		= &clkops_null,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk timer4_fck = {
-	.name		= "timer4_fck",
-	.clkdm_name	= "l4ls_clkdm",
-	.parent		= &sys_clkin_ck,
-	.init		= &omap2_init_clksel_parent,
-	.clksel		= timer2_to_7_clk_sel,
-	.clksel_reg	= AM33XX_CLKSEL_TIMER4_CLK,
-	.clksel_mask	= AM33XX_CLKSEL_0_1_MASK,
-	.ops		= &clkops_null,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk timer5_fck = {
-	.name		= "timer5_fck",
-	.clkdm_name	= "l4ls_clkdm",
-	.parent		= &sys_clkin_ck,
-	.init		= &omap2_init_clksel_parent,
-	.clksel		= timer2_to_7_clk_sel,
-	.clksel_reg	= AM33XX_CLKSEL_TIMER5_CLK,
-	.clksel_mask	= AM33XX_CLKSEL_0_1_MASK,
-	.ops		= &clkops_null,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk timer6_fck = {
-	.name		= "timer6_fck",
-	.clkdm_name	= "l4ls_clkdm",
-	.parent		= &sys_clkin_ck,
-	.init		= &am33xx_init_timer_parent,
-	.clksel		= timer2_to_7_clk_sel,
-	.clksel_reg	= AM33XX_CLKSEL_TIMER6_CLK,
-	.clksel_mask	= AM33XX_CLKSEL_0_1_MASK,
-	.ops		= &clkops_null,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk timer7_fck = {
-	.name		= "timer7_fck",
-	.clkdm_name	= "l4ls_clkdm",
-	.parent		= &sys_clkin_ck,
-	.init		= &omap2_init_clksel_parent,
-	.clksel		= timer2_to_7_clk_sel,
-	.clksel_reg	= AM33XX_CLKSEL_TIMER7_CLK,
-	.clksel_mask	= AM33XX_CLKSEL_0_1_MASK,
-	.ops		= &clkops_null,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk cpsw_125mhz_gclk = {
-	.name		= "cpsw_125mhz_gclk",
-	.clkdm_name	= "cpsw_125mhz_clkdm",
-	.parent		= &dpll_core_m5_ck,
-	.ops		= &clkops_null,
-	.fixed_div	= 2,
-	.recalc		= &omap_fixed_divisor_recalc,
-};
-
-static const struct clksel cpsw_cpts_rft_clkmux_sel[] = {
-	{ .parent = &dpll_core_m5_ck, .rates = div_1_0_rates },
-	{ .parent = &dpll_core_m4_ck, .rates = div_1_1_rates },
-	{ .parent = NULL },
-};
-
-static struct clk cpsw_cpts_rft_clk = {
-	.name		= "cpsw_cpts_rft_clk",
-	.clkdm_name	= "cpsw_125mhz_clkdm",
-	.parent		= &dpll_core_m5_ck,
-	.clksel		= cpsw_cpts_rft_clkmux_sel,
-	.clksel_reg	= AM33XX_CM_CPTS_RFT_CLKSEL,
-	.clksel_mask	= AM33XX_CLKSEL_0_0_MASK,
-	.ops		= &clkops_null,
-	.recalc		= &followparent_recalc,
-};
-
-/* gpio */
-static const struct clksel gpio0_dbclk_mux_sel[] = {
-	{ .parent = &clk_rc32k_ck, .rates = div_1_0_rates },
-	{ .parent = &clk_32768_ck, .rates = div_1_1_rates },
-	{ .parent = &clkdiv32k_ick, .rates = div_1_2_rates },
-	{ .parent = NULL },
-};
-
-static struct clk gpio0_dbclk_mux_ck = {
-	.name		= "gpio0_dbclk_mux_ck",
-	.clkdm_name	= "l4_wkup_clkdm",
-	.parent		= &clk_rc32k_ck,
-	.init		= &omap2_init_clksel_parent,
-	.clksel		= gpio0_dbclk_mux_sel,
-	.clksel_reg	= AM33XX_CLKSEL_GPIO0_DBCLK,
-	.clksel_mask	= AM33XX_CLKSEL_0_1_MASK,
-	.ops		= &clkops_null,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk gpio0_dbclk = {
-	.name		= "gpio0_dbclk",
-	.clkdm_name	= "l4_wkup_clkdm",
-	.parent		= &gpio0_dbclk_mux_ck,
-	.enable_reg	= AM33XX_CM_WKUP_GPIO0_CLKCTRL,
-	.enable_bit	= AM33XX_OPTFCLKEN_GPIO0_GDBCLK_SHIFT,
-	.ops		= &clkops_omap2_dflt,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpio1_dbclk = {
-	.name		= "gpio1_dbclk",
-	.clkdm_name	= "l4ls_clkdm",
-	.parent		= &clkdiv32k_ick,
-	.enable_reg	= AM33XX_CM_PER_GPIO1_CLKCTRL,
-	.enable_bit	= AM33XX_OPTFCLKEN_GPIO_1_GDBCLK_SHIFT,
-	.ops		= &clkops_omap2_dflt,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpio2_dbclk = {
-	.name		= "gpio2_dbclk",
-	.clkdm_name	= "l4ls_clkdm",
-	.parent		= &clkdiv32k_ick,
-	.enable_reg	= AM33XX_CM_PER_GPIO2_CLKCTRL,
-	.enable_bit	= AM33XX_OPTFCLKEN_GPIO_2_GDBCLK_SHIFT,
-	.ops		= &clkops_omap2_dflt,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpio3_dbclk = {
-	.name		= "gpio3_dbclk",
-	.clkdm_name	= "l4ls_clkdm",
-	.parent		= &clkdiv32k_ick,
-	.enable_reg	= AM33XX_CM_PER_GPIO3_CLKCTRL,
-	.enable_bit	= AM33XX_OPTFCLKEN_GPIO_3_GDBCLK_SHIFT,
-	.ops		= &clkops_omap2_dflt,
-	.recalc		= &followparent_recalc,
-};
-
-static const struct clksel pruss_ocp_clk_mux_sel[] = {
-	{ .parent = &l3_gclk, .rates = div_1_0_rates },
-	{ .parent = &dpll_disp_m2_ck, .rates = div_1_1_rates },
-	{ .parent = NULL },
-};
-
-static struct clk pruss_ocp_gclk = {
-	.name		= "pruss_ocp_gclk",
-	.clkdm_name	= "pruss_ocp_clkdm",
-	.parent		= &l3_gclk,
-	.init		= &omap2_init_clksel_parent,
-	.clksel		= pruss_ocp_clk_mux_sel,
-	.clksel_reg	= AM33XX_CLKSEL_PRUSS_OCP_CLK,
-	.clksel_mask	= AM33XX_CLKSEL_0_0_MASK,
-	.ops		= &clkops_null,
-	.recalc		= &followparent_recalc,
-};
-
-static const struct clksel lcd_clk_mux_sel[] = {
-	{ .parent = &dpll_disp_m2_ck, .rates = div_1_0_rates },
-	{ .parent = &dpll_core_m5_ck, .rates = div_1_1_rates },
-	{ .parent = &dpll_per_m2_ck, .rates = div_1_2_rates },
-	{ .parent = NULL },
-};
-
-static struct clk lcd_gclk = {
-	.name		= "lcd_gclk",
-	.clkdm_name	= "lcdc_clkdm",
-	.parent		= &dpll_disp_m2_ck,
-	.init		= &omap2_init_clksel_parent,
-	.clksel		= lcd_clk_mux_sel,
-	.clksel_reg	= AM33XX_CLKSEL_LCDC_PIXEL_CLK,
-	.clksel_mask	= AM33XX_CLKSEL_0_1_MASK,
-	.ops		= &clkops_null,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mmc_clk = {
-	.name		= "mmc_clk",
-	.clkdm_name	= "l4ls_clkdm",
-	.parent		= &dpll_per_m2_ck,
-	.ops		= &clkops_null,
-	.fixed_div	= 2,
-	.recalc		= &omap_fixed_divisor_recalc,
-};
-
-static struct clk mmc2_fck = {
-	.name		= "mmc2_fck",
-	.clkdm_name	= "l3s_clkdm",
-	.parent		= &mmc_clk,
-	.ops		= &clkops_null,
-	.recalc		= &followparent_recalc,
-};
-
-static const struct clksel gfx_clksel_sel[] = {
-	{ .parent = &dpll_core_m4_ck, .rates = div_1_0_rates },
-	{ .parent = &dpll_per_m2_ck, .rates = div_1_1_rates },
-	{ .parent = NULL },
-};
-
-static struct clk gfx_fclk_clksel_ck = {
-	.name		= "gfx_fclk_clksel_ck",
-	.parent		= &dpll_core_m4_ck,
-	.clksel		= gfx_clksel_sel,
-	.ops		= &clkops_null,
-	.clksel_reg	= AM33XX_CLKSEL_GFX_FCLK,
-	.clksel_mask	= AM33XX_CLKSEL_GFX_FCLK_MASK,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static const struct clksel_rate div_1_0_2_1_rates[] = {
-	{ .div = 1, .val = 0, .flags = RATE_IN_AM33XX },
-	{ .div = 2, .val = 1, .flags = RATE_IN_AM33XX },
-	{ .div = 0 },
-};
-
-static const struct clksel gfx_div_sel[] = {
-	{ .parent = &gfx_fclk_clksel_ck, .rates = div_1_0_2_1_rates },
-	{ .parent = NULL },
-};
-
-static struct clk gfx_fck_div_ck = {
-	.name		= "gfx_fck_div_ck",
-	.clkdm_name	= "gfx_l3_clkdm",
-	.parent		= &gfx_fclk_clksel_ck,
-	.init		= &omap2_init_clksel_parent,
-	.clksel		= gfx_div_sel,
-	.clksel_reg	= AM33XX_CLKSEL_GFX_FCLK,
-	.clksel_mask	= AM33XX_CLKSEL_0_0_MASK,
-	.recalc		= &omap2_clksel_recalc,
-	.round_rate	= &omap2_clksel_round_rate,
-	.set_rate	= &omap2_clksel_set_rate,
-	.ops		= &clkops_null,
-};
-
-static const struct clksel sysclkout_pre_sel[] = {
-	{ .parent = &clk_32768_ck, .rates = div_1_0_rates },
-	{ .parent = &l3_gclk, .rates = div_1_1_rates },
-	{ .parent = &dpll_ddr_m2_ck, .rates = div_1_2_rates },
-	{ .parent = &dpll_per_m2_ck, .rates = div_1_3_rates },
-	{ .parent = &lcd_gclk, .rates = div_1_4_rates },
-	{ .parent = NULL },
-};
-
-static struct clk sysclkout_pre_ck = {
-	.name		= "sysclkout_pre_ck",
-	.parent		= &clk_32768_ck,
-	.init		= &omap2_init_clksel_parent,
-	.clksel		= sysclkout_pre_sel,
-	.clksel_reg	= AM33XX_CM_CLKOUT_CTRL,
-	.clksel_mask	= AM33XX_CLKOUT2SOURCE_MASK,
-	.ops		= &clkops_null,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-/* Divide by 8 clock rates with default clock is 1/1*/
-static const struct clksel_rate div8_rates[] = {
-	{ .div = 1, .val = 0, .flags = RATE_IN_AM33XX },
-	{ .div = 2, .val = 1, .flags = RATE_IN_AM33XX },
-	{ .div = 3, .val = 2, .flags = RATE_IN_AM33XX },
-	{ .div = 4, .val = 3, .flags = RATE_IN_AM33XX },
-	{ .div = 5, .val = 4, .flags = RATE_IN_AM33XX },
-	{ .div = 6, .val = 5, .flags = RATE_IN_AM33XX },
-	{ .div = 7, .val = 6, .flags = RATE_IN_AM33XX },
-	{ .div = 8, .val = 7, .flags = RATE_IN_AM33XX },
-	{ .div = 0 },
-};
-
-static const struct clksel clkout2_div[] = {
-	{ .parent = &sysclkout_pre_ck, .rates = div8_rates },
-	{ .parent = NULL },
-};
-
-static struct clk clkout2_ck = {
-	.name		= "clkout2_ck",
-	.parent		= &sysclkout_pre_ck,
-	.ops		= &clkops_omap2_dflt,
-	.clksel		= clkout2_div,
-	.clksel_reg	= AM33XX_CM_CLKOUT_CTRL,
-	.clksel_mask	= AM33XX_CLKOUT2DIV_MASK,
-	.enable_reg	= AM33XX_CM_CLKOUT_CTRL,
-	.enable_bit	= AM33XX_CLKOUT2EN_SHIFT,
-	.recalc		= &omap2_clksel_recalc,
-	.round_rate	= &omap2_clksel_round_rate,
-	.set_rate	= &omap2_clksel_set_rate,
-};
-
-static const struct clksel wdt_clkmux_sel[] = {
-	{ .parent = &clk_rc32k_ck, .rates = div_1_0_rates },
-	{ .parent = &clkdiv32k_ick, .rates = div_1_1_rates },
-	{ .parent = NULL },
-};
-
-static struct clk wdt1_fck = {
-	.name		= "wdt1_fck",
-	.clkdm_name	= "l4_wkup_clkdm",
-	.parent		= &clk_rc32k_ck,
-	.init		= &omap2_init_clksel_parent,
-	.clksel		= wdt_clkmux_sel,
-	.clksel_reg	= AM33XX_CLKSEL_WDT1_CLK,
-	.clksel_mask	= AM33XX_CLKSEL_0_1_MASK,
-	.ops		= &clkops_null,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-/*
- * clkdev
- */
-static struct omap_clk am33xx_clks[] = {
-	CLK(NULL,	"clk_32768_ck",		&clk_32768_ck,	CK_AM33XX),
-	CLK(NULL,	"clk_rc32k_ck",		&clk_rc32k_ck,	CK_AM33XX),
-	CLK(NULL,	"virt_19200000_ck",	&virt_19200000_ck,	CK_AM33XX),
-	CLK(NULL,	"virt_24000000_ck",	&virt_24000000_ck,	CK_AM33XX),
-	CLK(NULL,	"virt_25000000_ck",	&virt_25000000_ck,	CK_AM33XX),
-	CLK(NULL,	"virt_26000000_ck",	&virt_26000000_ck,	CK_AM33XX),
-	CLK(NULL,	"sys_clkin_ck",		&sys_clkin_ck,	CK_AM33XX),
-	CLK(NULL,	"tclkin_ck",		&tclkin_ck,	CK_AM33XX),
-	CLK(NULL,	"dpll_core_ck",		&dpll_core_ck,	CK_AM33XX),
-	CLK(NULL,	"dpll_core_x2_ck",	&dpll_core_x2_ck,	CK_AM33XX),
-	CLK(NULL,	"dpll_core_m4_ck",	&dpll_core_m4_ck,	CK_AM33XX),
-	CLK(NULL,	"dpll_core_m5_ck",	&dpll_core_m5_ck,	CK_AM33XX),
-	CLK(NULL,	"dpll_core_m6_ck",	&dpll_core_m6_ck,	CK_AM33XX),
-	CLK(NULL,	"dpll_mpu_ck",		&dpll_mpu_ck,	CK_AM33XX),
-	CLK("cpu0",	NULL,			&dpll_mpu_ck,		CK_AM33XX),
-	CLK(NULL,	"dpll_mpu_m2_ck",	&dpll_mpu_m2_ck,	CK_AM33XX),
-	CLK(NULL,	"dpll_ddr_ck",		&dpll_ddr_ck,	CK_AM33XX),
-	CLK(NULL,	"dpll_ddr_m2_ck",	&dpll_ddr_m2_ck,	CK_AM33XX),
-	CLK(NULL,	"dpll_ddr_m2_div2_ck",	&dpll_ddr_m2_div2_ck,	CK_AM33XX),
-	CLK(NULL,	"dpll_disp_ck",		&dpll_disp_ck,	CK_AM33XX),
-	CLK(NULL,	"dpll_disp_m2_ck",	&dpll_disp_m2_ck,	CK_AM33XX),
-	CLK(NULL,	"dpll_per_ck",		&dpll_per_ck,	CK_AM33XX),
-	CLK(NULL,	"dpll_per_m2_ck",	&dpll_per_m2_ck,	CK_AM33XX),
-	CLK(NULL,	"dpll_per_m2_div4_wkupdm_ck",	&dpll_per_m2_div4_wkupdm_ck,	CK_AM33XX),
-	CLK(NULL,	"dpll_per_m2_div4_ck",	&dpll_per_m2_div4_ck,	CK_AM33XX),
-	CLK(NULL,	"adc_tsc_fck",		&adc_tsc_fck,	CK_AM33XX),
-	CLK(NULL,	"cefuse_fck",		&cefuse_fck,	CK_AM33XX),
-	CLK(NULL,	"clkdiv32k_ick",	&clkdiv32k_ick,	CK_AM33XX),
-	CLK(NULL,	"dcan0_fck",		&dcan0_fck,	CK_AM33XX),
-	CLK("481cc000.d_can",	NULL,		&dcan0_fck,	CK_AM33XX),
-	CLK(NULL,	"dcan1_fck",		&dcan1_fck,	CK_AM33XX),
-	CLK("481d0000.d_can",	NULL,		&dcan1_fck,	CK_AM33XX),
-	CLK(NULL,	"debugss_ick",		&debugss_ick,	CK_AM33XX),
-	CLK(NULL,	"pruss_ocp_gclk",	&pruss_ocp_gclk,	CK_AM33XX),
-	CLK("davinci-mcasp.0",  NULL,           &mcasp0_fck,    CK_AM33XX),
-	CLK("davinci-mcasp.1",  NULL,           &mcasp1_fck,    CK_AM33XX),
-	CLK(NULL,	"mcasp0_fck",		&mcasp0_fck,	CK_AM33XX),
-	CLK(NULL,	"mcasp1_fck",		&mcasp1_fck,	CK_AM33XX),
-	CLK("NULL",	"mmc2_fck",		&mmc2_fck,	CK_AM33XX),
-	CLK(NULL,	"mmu_fck",		&mmu_fck,	CK_AM33XX),
-	CLK(NULL,	"smartreflex0_fck",	&smartreflex0_fck,	CK_AM33XX),
-	CLK(NULL,	"smartreflex1_fck",	&smartreflex1_fck,	CK_AM33XX),
-	CLK(NULL,	"timer1_fck",		&timer1_fck,	CK_AM33XX),
-	CLK(NULL,	"timer2_fck",		&timer2_fck,	CK_AM33XX),
-	CLK(NULL,	"timer3_fck",		&timer3_fck,	CK_AM33XX),
-	CLK(NULL,	"timer4_fck",		&timer4_fck,	CK_AM33XX),
-	CLK(NULL,	"timer5_fck",		&timer5_fck,	CK_AM33XX),
-	CLK(NULL,	"timer6_fck",		&timer6_fck,	CK_AM33XX),
-	CLK(NULL,	"timer7_fck",		&timer7_fck,	CK_AM33XX),
-	CLK(NULL,	"usbotg_fck",		&usbotg_fck,	CK_AM33XX),
-	CLK(NULL,	"ieee5000_fck",		&ieee5000_fck,	CK_AM33XX),
-	CLK(NULL,	"wdt1_fck",		&wdt1_fck,	CK_AM33XX),
-	CLK(NULL,	"l4_rtc_gclk",		&l4_rtc_gclk,	CK_AM33XX),
-	CLK(NULL,	"l3_gclk",		&l3_gclk,	CK_AM33XX),
-	CLK(NULL,	"dpll_core_m4_div2_ck",	&dpll_core_m4_div2_ck,	CK_AM33XX),
-	CLK(NULL,	"l4hs_gclk",		&l4hs_gclk,	CK_AM33XX),
-	CLK(NULL,	"l3s_gclk",		&l3s_gclk,	CK_AM33XX),
-	CLK(NULL,	"l4fw_gclk",		&l4fw_gclk,	CK_AM33XX),
-	CLK(NULL,	"l4ls_gclk",		&l4ls_gclk,	CK_AM33XX),
-	CLK(NULL,	"clk_24mhz",		&clk_24mhz,	CK_AM33XX),
-	CLK(NULL,	"sysclk_div_ck",	&sysclk_div_ck,	CK_AM33XX),
-	CLK(NULL,	"cpsw_125mhz_gclk",	&cpsw_125mhz_gclk,	CK_AM33XX),
-	CLK(NULL,	"cpsw_cpts_rft_clk",	&cpsw_cpts_rft_clk,	CK_AM33XX),
-	CLK(NULL,	"gpio0_dbclk_mux_ck",	&gpio0_dbclk_mux_ck,	CK_AM33XX),
-	CLK(NULL,	"gpio0_dbclk",		&gpio0_dbclk,	CK_AM33XX),
-	CLK(NULL,	"gpio1_dbclk",		&gpio1_dbclk,	CK_AM33XX),
-	CLK(NULL,	"gpio2_dbclk",		&gpio2_dbclk,	CK_AM33XX),
-	CLK(NULL,	"gpio3_dbclk",		&gpio3_dbclk,	CK_AM33XX),
-	CLK(NULL,	"lcd_gclk",		&lcd_gclk,	CK_AM33XX),
-	CLK(NULL,	"mmc_clk",		&mmc_clk,	CK_AM33XX),
-	CLK(NULL,	"gfx_fclk_clksel_ck",	&gfx_fclk_clksel_ck,	CK_AM33XX),
-	CLK(NULL,	"gfx_fck_div_ck",	&gfx_fck_div_ck,	CK_AM33XX),
-	CLK(NULL,	"sysclkout_pre_ck",	&sysclkout_pre_ck,	CK_AM33XX),
-	CLK(NULL,	"clkout2_ck",		&clkout2_ck,	CK_AM33XX),
-	CLK(NULL,	"timer_32k_ck",		&clkdiv32k_ick,	CK_AM33XX),
-	CLK(NULL,	"timer_sys_ck",		&sys_clkin_ck,	CK_AM33XX),
-};
-
-int __init am33xx_clk_init(void)
-{
-	struct omap_clk *c;
-	u32 cpu_clkflg;
-
-	if (soc_is_am33xx()) {
-		cpu_mask = RATE_IN_AM33XX;
-		cpu_clkflg = CK_AM33XX;
-	}
-
-	for (c = am33xx_clks; c < am33xx_clks + ARRAY_SIZE(am33xx_clks); c++)
-		clk_preinit(c->lk.clk);
-
-	for (c = am33xx_clks; c < am33xx_clks + ARRAY_SIZE(am33xx_clks); c++) {
-		if (c->cpu & cpu_clkflg) {
-			clkdev_add(&c->lk);
-			clk_register(c->lk.clk);
-			omap2_init_clk_clkdm(c->lk.clk);
-		}
-	}
-
-	recalculate_root_clocks();
-
-	/*
-	 * Only enable those clocks we will need, let the drivers
-	 * enable other clocks as necessary
-	 */
-	clk_enable_init_clocks();
-
-	return 0;
-}
diff --git a/arch/arm/mach-omap2/clock34xx.c b/arch/arm/mach-omap2/clock34xx.c
index e41819b..4596468 100644
--- a/arch/arm/mach-omap2/clock34xx.c
+++ b/arch/arm/mach-omap2/clock34xx.c
@@ -37,7 +37,7 @@
  * from the CM_{I,F}CLKEN bit.  Pass back the correct info via
  * @idlest_reg and @idlest_bit.  No return value.
  */
-static void omap3430es2_clk_ssi_find_idlest(struct clk *clk,
+static void omap3430es2_clk_ssi_find_idlest(struct clk_hw_omap *clk,
 					    void __iomem **idlest_reg,
 					    u8 *idlest_bit,
 					    u8 *idlest_val)
@@ -49,21 +49,16 @@
 	*idlest_bit = OMAP3430ES2_ST_SSI_IDLE_SHIFT;
 	*idlest_val = OMAP34XX_CM_IDLEST_VAL;
 }
-
-const struct clkops clkops_omap3430es2_ssi_wait = {
-	.enable		= omap2_dflt_clk_enable,
-	.disable	= omap2_dflt_clk_disable,
+const struct clk_hw_omap_ops clkhwops_omap3430es2_ssi_wait = {
 	.find_idlest	= omap3430es2_clk_ssi_find_idlest,
-	.find_companion = omap2_clk_dflt_find_companion,
+	.find_companion	= omap2_clk_dflt_find_companion,
 };
 
-const struct clkops clkops_omap3430es2_iclk_ssi_wait = {
-	.enable		= omap2_dflt_clk_enable,
-	.disable	= omap2_dflt_clk_disable,
-	.find_idlest	= omap3430es2_clk_ssi_find_idlest,
-	.find_companion = omap2_clk_dflt_find_companion,
+const struct clk_hw_omap_ops clkhwops_omap3430es2_iclk_ssi_wait = {
 	.allow_idle	= omap2_clkt_iclk_allow_idle,
 	.deny_idle	= omap2_clkt_iclk_deny_idle,
+	.find_idlest	= omap3430es2_clk_ssi_find_idlest,
+	.find_companion = omap2_clk_dflt_find_companion,
 };
 
 /**
@@ -80,7 +75,7 @@
  * default find_idlest code assumes that they are at the same
  * position.)  No return value.
  */
-static void omap3430es2_clk_dss_usbhost_find_idlest(struct clk *clk,
+static void omap3430es2_clk_dss_usbhost_find_idlest(struct clk_hw_omap *clk,
 						    void __iomem **idlest_reg,
 						    u8 *idlest_bit,
 						    u8 *idlest_val)
@@ -94,20 +89,16 @@
 	*idlest_val = OMAP34XX_CM_IDLEST_VAL;
 }
 
-const struct clkops clkops_omap3430es2_dss_usbhost_wait = {
-	.enable		= omap2_dflt_clk_enable,
-	.disable	= omap2_dflt_clk_disable,
+const struct clk_hw_omap_ops clkhwops_omap3430es2_dss_usbhost_wait = {
 	.find_idlest	= omap3430es2_clk_dss_usbhost_find_idlest,
-	.find_companion = omap2_clk_dflt_find_companion,
+	.find_companion	= omap2_clk_dflt_find_companion,
 };
 
-const struct clkops clkops_omap3430es2_iclk_dss_usbhost_wait = {
-	.enable		= omap2_dflt_clk_enable,
-	.disable	= omap2_dflt_clk_disable,
-	.find_idlest	= omap3430es2_clk_dss_usbhost_find_idlest,
-	.find_companion = omap2_clk_dflt_find_companion,
+const struct clk_hw_omap_ops clkhwops_omap3430es2_iclk_dss_usbhost_wait = {
 	.allow_idle	= omap2_clkt_iclk_allow_idle,
 	.deny_idle	= omap2_clkt_iclk_deny_idle,
+	.find_idlest	= omap3430es2_clk_dss_usbhost_find_idlest,
+	.find_companion	= omap2_clk_dflt_find_companion,
 };
 
 /**
@@ -121,7 +112,7 @@
  * shift from the CM_{I,F}CLKEN bit.  Pass back the correct info via
  * @idlest_reg and @idlest_bit.  No return value.
  */
-static void omap3430es2_clk_hsotgusb_find_idlest(struct clk *clk,
+static void omap3430es2_clk_hsotgusb_find_idlest(struct clk_hw_omap *clk,
 						 void __iomem **idlest_reg,
 						 u8 *idlest_bit,
 						 u8 *idlest_val)
@@ -134,18 +125,14 @@
 	*idlest_val = OMAP34XX_CM_IDLEST_VAL;
 }
 
-const struct clkops clkops_omap3430es2_hsotgusb_wait = {
-	.enable		= omap2_dflt_clk_enable,
-	.disable	= omap2_dflt_clk_disable,
-	.find_idlest	= omap3430es2_clk_hsotgusb_find_idlest,
-	.find_companion = omap2_clk_dflt_find_companion,
-};
-
-const struct clkops clkops_omap3430es2_iclk_hsotgusb_wait = {
-	.enable		= omap2_dflt_clk_enable,
-	.disable	= omap2_dflt_clk_disable,
-	.find_idlest	= omap3430es2_clk_hsotgusb_find_idlest,
-	.find_companion = omap2_clk_dflt_find_companion,
+const struct clk_hw_omap_ops clkhwops_omap3430es2_iclk_hsotgusb_wait = {
 	.allow_idle	= omap2_clkt_iclk_allow_idle,
 	.deny_idle	= omap2_clkt_iclk_deny_idle,
+	.find_idlest	= omap3430es2_clk_hsotgusb_find_idlest,
+	.find_companion	= omap2_clk_dflt_find_companion,
+};
+
+const struct clk_hw_omap_ops clkhwops_omap3430es2_hsotgusb_wait = {
+	.find_idlest	= omap3430es2_clk_hsotgusb_find_idlest,
+	.find_companion	= omap2_clk_dflt_find_companion,
 };
diff --git a/arch/arm/mach-omap2/clock3517.c b/arch/arm/mach-omap2/clock3517.c
index 622ea05..4d79ae2 100644
--- a/arch/arm/mach-omap2/clock3517.c
+++ b/arch/arm/mach-omap2/clock3517.c
@@ -47,7 +47,7 @@
  * in the enable register itsel at a bit offset of 4 from the enable
  * bit. A value of 1 indicates that clock is enabled.
  */
-static void am35xx_clk_find_idlest(struct clk *clk,
+static void am35xx_clk_find_idlest(struct clk_hw_omap *clk,
 					    void __iomem **idlest_reg,
 					    u8 *idlest_bit,
 					    u8 *idlest_val)
@@ -71,8 +71,9 @@
  * associate this type of code with per-module data structures to
  * avoid this issue, and remove the casts.  No return value.
  */
-static void am35xx_clk_find_companion(struct clk *clk, void __iomem **other_reg,
-					    u8 *other_bit)
+static void am35xx_clk_find_companion(struct clk_hw_omap *clk,
+				      void __iomem **other_reg,
+				      u8 *other_bit)
 {
 	*other_reg = (__force void __iomem *)(clk->enable_reg);
 	if (clk->enable_bit & AM35XX_IPSS_ICK_MASK)
@@ -80,10 +81,7 @@
 	else
 		*other_bit = clk->enable_bit - AM35XX_IPSS_ICK_FCK_OFFSET;
 }
-
-const struct clkops clkops_am35xx_ipss_module_wait = {
-	.enable		= omap2_dflt_clk_enable,
-	.disable	= omap2_dflt_clk_disable,
+const struct clk_hw_omap_ops clkhwops_am35xx_ipss_module_wait = {
 	.find_idlest	= am35xx_clk_find_idlest,
 	.find_companion	= am35xx_clk_find_companion,
 };
@@ -99,7 +97,7 @@
  * CM_{I,F}CLKEN bit.  Pass back the correct info via @idlest_reg
  * and @idlest_bit.  No return value.
  */
-static void am35xx_clk_ipss_find_idlest(struct clk *clk,
+static void am35xx_clk_ipss_find_idlest(struct clk_hw_omap *clk,
 					    void __iomem **idlest_reg,
 					    u8 *idlest_bit,
 					    u8 *idlest_val)
@@ -112,13 +110,9 @@
 	*idlest_val = OMAP34XX_CM_IDLEST_VAL;
 }
 
-const struct clkops clkops_am35xx_ipss_wait = {
-	.enable		= omap2_dflt_clk_enable,
-	.disable	= omap2_dflt_clk_disable,
-	.find_idlest	= am35xx_clk_ipss_find_idlest,
-	.find_companion	= omap2_clk_dflt_find_companion,
+const struct clk_hw_omap_ops clkhwops_am35xx_ipss_wait = {
 	.allow_idle	= omap2_clkt_iclk_allow_idle,
 	.deny_idle	= omap2_clkt_iclk_deny_idle,
+	.find_idlest	= am35xx_clk_ipss_find_idlest,
+	.find_companion	= omap2_clk_dflt_find_companion,
 };
-
-
diff --git a/arch/arm/mach-omap2/clock36xx.c b/arch/arm/mach-omap2/clock36xx.c
index 0e1e9e4..8f3bf4e 100644
--- a/arch/arm/mach-omap2/clock36xx.c
+++ b/arch/arm/mach-omap2/clock36xx.c
@@ -37,34 +37,32 @@
  * (Any other value different from the Read value) to the
  * corresponding CM_CLKSEL register will refresh the dividers.
  */
-static int omap36xx_pwrdn_clk_enable_with_hsdiv_restore(struct clk *clk)
+int omap36xx_pwrdn_clk_enable_with_hsdiv_restore(struct clk_hw *clk)
 {
+	struct clk_hw_omap *parent;
+	struct clk_hw *parent_hw;
 	u32 dummy_v, orig_v, clksel_shift;
 	int ret;
 
 	/* Clear PWRDN bit of HSDIVIDER */
 	ret = omap2_dflt_clk_enable(clk);
 
+	parent_hw = __clk_get_hw(__clk_get_parent(clk->clk));
+	parent = to_clk_hw_omap(parent_hw);
+
 	/* Restore the dividers */
 	if (!ret) {
-		clksel_shift = __ffs(clk->parent->clksel_mask);
-		orig_v = __raw_readl(clk->parent->clksel_reg);
+		clksel_shift = __ffs(parent->clksel_mask);
+		orig_v = __raw_readl(parent->clksel_reg);
 		dummy_v = orig_v;
 
 		/* Write any other value different from the Read value */
 		dummy_v ^= (1 << clksel_shift);
-		__raw_writel(dummy_v, clk->parent->clksel_reg);
+		__raw_writel(dummy_v, parent->clksel_reg);
 
 		/* Write the original divider */
-		__raw_writel(orig_v, clk->parent->clksel_reg);
+		__raw_writel(orig_v, parent->clksel_reg);
 	}
 
 	return ret;
 }
-
-const struct clkops clkops_omap36xx_pwrdn_with_hsdiv_wait_restore = {
-	.enable		= omap36xx_pwrdn_clk_enable_with_hsdiv_restore,
-	.disable	= omap2_dflt_clk_disable,
-	.find_companion	= omap2_clk_dflt_find_companion,
-	.find_idlest	= omap2_clk_dflt_find_idlest,
-};
diff --git a/arch/arm/mach-omap2/clock36xx.h b/arch/arm/mach-omap2/clock36xx.h
index a7dee5b..945bb7f 100644
--- a/arch/arm/mach-omap2/clock36xx.h
+++ b/arch/arm/mach-omap2/clock36xx.h
@@ -8,6 +8,6 @@
 #ifndef __ARCH_ARM_MACH_OMAP2_CLOCK36XX_H
 #define __ARCH_ARM_MACH_OMAP2_CLOCK36XX_H
 
-extern const struct clkops clkops_omap36xx_pwrdn_with_hsdiv_wait_restore;
+extern int omap36xx_pwrdn_clk_enable_with_hsdiv_restore(struct clk_hw *hw);
 
 #endif
diff --git a/arch/arm/mach-omap2/clock3xxx.c b/arch/arm/mach-omap2/clock3xxx.c
index 3e8aca2..4eacab8 100644
--- a/arch/arm/mach-omap2/clock3xxx.c
+++ b/arch/arm/mach-omap2/clock3xxx.c
@@ -38,8 +38,8 @@
 
 /* needed by omap3_core_dpll_m2_set_rate() */
 struct clk *sdrc_ick_p, *arm_fck_p;
-
-int omap3_dpll4_set_rate(struct clk *clk, unsigned long rate)
+int omap3_dpll4_set_rate(struct clk_hw *hw, unsigned long rate,
+				unsigned long parent_rate)
 {
 	/*
 	 * According to the 12-5 CDP code from TI, "Limitation 2.5"
@@ -51,7 +51,7 @@
 		return -EINVAL;
 	}
 
-	return omap3_noncore_dpll_set_rate(clk, rate);
+	return omap3_noncore_dpll_set_rate(hw, rate, parent_rate);
 }
 
 void __init omap3_clk_lock_dpll5(void)
diff --git a/arch/arm/mach-omap2/clock3xxx.h b/arch/arm/mach-omap2/clock3xxx.h
index 8bbeeaf..8cd4b0a 100644
--- a/arch/arm/mach-omap2/clock3xxx.h
+++ b/arch/arm/mach-omap2/clock3xxx.h
@@ -9,8 +9,10 @@
 #define __ARCH_ARM_MACH_OMAP2_CLOCK3XXX_H
 
 int omap3xxx_clk_init(void);
-int omap3_dpll4_set_rate(struct clk *clk, unsigned long rate);
-int omap3_core_dpll_m2_set_rate(struct clk *clk, unsigned long rate);
+int omap3_dpll4_set_rate(struct clk_hw *clk, unsigned long rate,
+					unsigned long parent_rate);
+int omap3_core_dpll_m2_set_rate(struct clk_hw *clk, unsigned long rate,
+					unsigned long parent_rate);
 void omap3_clk_lock_dpll5(void);
 
 extern struct clk *sdrc_ick_p;
diff --git a/arch/arm/mach-omap2/clock3xxx_data.c b/arch/arm/mach-omap2/clock3xxx_data.c
deleted file mode 100644
index 6cca199..0000000
--- a/arch/arm/mach-omap2/clock3xxx_data.c
+++ /dev/null
@@ -1,3613 +0,0 @@
-/*
- * OMAP3 clock data
- *
- * Copyright (C) 2007-2010, 2012 Texas Instruments, Inc.
- * Copyright (C) 2007-2011 Nokia Corporation
- *
- * Written by Paul Walmsley
- * With many device clock fixes by Kevin Hilman and Jouni Högander
- * DPLL bypass clock support added by Roman Tereshonkov
- *
- */
-
-/*
- * Virtual clocks are introduced as convenient tools.
- * They are sources for other clocks and not supposed
- * to be requested from drivers directly.
- */
-
-#include <linux/kernel.h>
-#include <linux/clk.h>
-#include <linux/list.h>
-#include <linux/io.h>
-
-#include "soc.h"
-#include "iomap.h"
-#include "clock.h"
-#include "clock3xxx.h"
-#include "clock34xx.h"
-#include "clock36xx.h"
-#include "clock3517.h"
-#include "cm3xxx.h"
-#include "cm-regbits-34xx.h"
-#include "prm2xxx_3xxx.h"
-#include "prm-regbits-34xx.h"
-#include "control.h"
-
-/*
- * clocks
- */
-
-#define OMAP_CM_REGADDR		OMAP34XX_CM_REGADDR
-
-/* Maximum DPLL multiplier, divider values for OMAP3 */
-#define OMAP3_MAX_DPLL_MULT		2047
-#define OMAP3630_MAX_JTYPE_DPLL_MULT	4095
-#define OMAP3_MAX_DPLL_DIV		128
-
-/*
- * DPLL1 supplies clock to the MPU.
- * DPLL2 supplies clock to the IVA2.
- * DPLL3 supplies CORE domain clocks.
- * DPLL4 supplies peripheral clocks.
- * DPLL5 supplies other peripheral clocks (USBHOST, USIM).
- */
-
-/* Forward declarations for DPLL bypass clocks */
-static struct clk dpll1_fck;
-static struct clk dpll2_fck;
-
-/* PRM CLOCKS */
-
-/* According to timer32k.c, this is a 32768Hz clock, not a 32000Hz clock. */
-static struct clk omap_32k_fck = {
-	.name		= "omap_32k_fck",
-	.ops		= &clkops_null,
-	.rate		= 32768,
-};
-
-static struct clk secure_32k_fck = {
-	.name		= "secure_32k_fck",
-	.ops		= &clkops_null,
-	.rate		= 32768,
-};
-
-/* Virtual source clocks for osc_sys_ck */
-static struct clk virt_12m_ck = {
-	.name		= "virt_12m_ck",
-	.ops		= &clkops_null,
-	.rate		= 12000000,
-};
-
-static struct clk virt_13m_ck = {
-	.name		= "virt_13m_ck",
-	.ops		= &clkops_null,
-	.rate		= 13000000,
-};
-
-static struct clk virt_16_8m_ck = {
-	.name		= "virt_16_8m_ck",
-	.ops		= &clkops_null,
-	.rate		= 16800000,
-};
-
-static struct clk virt_38_4m_ck = {
-	.name		= "virt_38_4m_ck",
-	.ops		= &clkops_null,
-	.rate		= 38400000,
-};
-
-static const struct clksel_rate osc_sys_12m_rates[] = {
-	{ .div = 1, .val = 0, .flags = RATE_IN_3XXX },
-	{ .div = 0 }
-};
-
-static const struct clksel_rate osc_sys_13m_rates[] = {
-	{ .div = 1, .val = 1, .flags = RATE_IN_3XXX },
-	{ .div = 0 }
-};
-
-static const struct clksel_rate osc_sys_16_8m_rates[] = {
-	{ .div = 1, .val = 5, .flags = RATE_IN_3430ES2PLUS_36XX },
-	{ .div = 0 }
-};
-
-static const struct clksel_rate osc_sys_19_2m_rates[] = {
-	{ .div = 1, .val = 2, .flags = RATE_IN_3XXX },
-	{ .div = 0 }
-};
-
-static const struct clksel_rate osc_sys_26m_rates[] = {
-	{ .div = 1, .val = 3, .flags = RATE_IN_3XXX },
-	{ .div = 0 }
-};
-
-static const struct clksel_rate osc_sys_38_4m_rates[] = {
-	{ .div = 1, .val = 4, .flags = RATE_IN_3XXX },
-	{ .div = 0 }
-};
-
-static const struct clksel osc_sys_clksel[] = {
-	{ .parent = &virt_12m_ck,   .rates = osc_sys_12m_rates },
-	{ .parent = &virt_13m_ck,   .rates = osc_sys_13m_rates },
-	{ .parent = &virt_16_8m_ck, .rates = osc_sys_16_8m_rates },
-	{ .parent = &virt_19200000_ck, .rates = osc_sys_19_2m_rates },
-	{ .parent = &virt_26000000_ck,   .rates = osc_sys_26m_rates },
-	{ .parent = &virt_38_4m_ck, .rates = osc_sys_38_4m_rates },
-	{ .parent = NULL },
-};
-
-/* Oscillator clock */
-/* 12, 13, 16.8, 19.2, 26, or 38.4 MHz */
-static struct clk osc_sys_ck = {
-	.name		= "osc_sys_ck",
-	.ops		= &clkops_null,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP3430_PRM_CLKSEL,
-	.clksel_mask	= OMAP3430_SYS_CLKIN_SEL_MASK,
-	.clksel		= osc_sys_clksel,
-	/* REVISIT: deal with autoextclkmode? */
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static const struct clksel_rate div2_rates[] = {
-	{ .div = 1, .val = 1, .flags = RATE_IN_3XXX },
-	{ .div = 2, .val = 2, .flags = RATE_IN_3XXX },
-	{ .div = 0 }
-};
-
-static const struct clksel sys_clksel[] = {
-	{ .parent = &osc_sys_ck, .rates = div2_rates },
-	{ .parent = NULL }
-};
-
-/* Latency: this clock is only enabled after PRM_CLKSETUP.SETUP_TIME */
-/* Feeds DPLLs - divided first by PRM_CLKSRC_CTRL.SYSCLKDIV? */
-static struct clk sys_ck = {
-	.name		= "sys_ck",
-	.ops		= &clkops_null,
-	.parent		= &osc_sys_ck,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP3430_PRM_CLKSRC_CTRL,
-	.clksel_mask	= OMAP_SYSCLKDIV_MASK,
-	.clksel		= sys_clksel,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk sys_altclk = {
-	.name		= "sys_altclk",
-	.ops		= &clkops_null,
-};
-
-/* Optional external clock input for some McBSPs */
-static struct clk mcbsp_clks = {
-	.name		= "mcbsp_clks",
-	.ops		= &clkops_null,
-};
-
-/* PRM EXTERNAL CLOCK OUTPUT */
-
-static struct clk sys_clkout1 = {
-	.name		= "sys_clkout1",
-	.ops		= &clkops_omap2_dflt,
-	.parent		= &osc_sys_ck,
-	.enable_reg	= OMAP3430_PRM_CLKOUT_CTRL,
-	.enable_bit	= OMAP3430_CLKOUT_EN_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-/* DPLLS */
-
-/* CM CLOCKS */
-
-static const struct clksel_rate div16_dpll_rates[] = {
-	{ .div = 1, .val = 1, .flags = RATE_IN_3XXX },
-	{ .div = 2, .val = 2, .flags = RATE_IN_3XXX },
-	{ .div = 3, .val = 3, .flags = RATE_IN_3XXX },
-	{ .div = 4, .val = 4, .flags = RATE_IN_3XXX },
-	{ .div = 5, .val = 5, .flags = RATE_IN_3XXX },
-	{ .div = 6, .val = 6, .flags = RATE_IN_3XXX },
-	{ .div = 7, .val = 7, .flags = RATE_IN_3XXX },
-	{ .div = 8, .val = 8, .flags = RATE_IN_3XXX },
-	{ .div = 9, .val = 9, .flags = RATE_IN_3XXX },
-	{ .div = 10, .val = 10, .flags = RATE_IN_3XXX },
-	{ .div = 11, .val = 11, .flags = RATE_IN_3XXX },
-	{ .div = 12, .val = 12, .flags = RATE_IN_3XXX },
-	{ .div = 13, .val = 13, .flags = RATE_IN_3XXX },
-	{ .div = 14, .val = 14, .flags = RATE_IN_3XXX },
-	{ .div = 15, .val = 15, .flags = RATE_IN_3XXX },
-	{ .div = 16, .val = 16, .flags = RATE_IN_3XXX },
-	{ .div = 0 }
-};
-
-static const struct clksel_rate dpll4_rates[] = {
-	{ .div = 1, .val = 1, .flags = RATE_IN_3XXX },
-	{ .div = 2, .val = 2, .flags = RATE_IN_3XXX },
-	{ .div = 3, .val = 3, .flags = RATE_IN_3XXX },
-	{ .div = 4, .val = 4, .flags = RATE_IN_3XXX },
-	{ .div = 5, .val = 5, .flags = RATE_IN_3XXX },
-	{ .div = 6, .val = 6, .flags = RATE_IN_3XXX },
-	{ .div = 7, .val = 7, .flags = RATE_IN_3XXX },
-	{ .div = 8, .val = 8, .flags = RATE_IN_3XXX },
-	{ .div = 9, .val = 9, .flags = RATE_IN_3XXX },
-	{ .div = 10, .val = 10, .flags = RATE_IN_3XXX },
-	{ .div = 11, .val = 11, .flags = RATE_IN_3XXX },
-	{ .div = 12, .val = 12, .flags = RATE_IN_3XXX },
-	{ .div = 13, .val = 13, .flags = RATE_IN_3XXX },
-	{ .div = 14, .val = 14, .flags = RATE_IN_3XXX },
-	{ .div = 15, .val = 15, .flags = RATE_IN_3XXX },
-	{ .div = 16, .val = 16, .flags = RATE_IN_3XXX },
-	{ .div = 17, .val = 17, .flags = RATE_IN_36XX },
-	{ .div = 18, .val = 18, .flags = RATE_IN_36XX },
-	{ .div = 19, .val = 19, .flags = RATE_IN_36XX },
-	{ .div = 20, .val = 20, .flags = RATE_IN_36XX },
-	{ .div = 21, .val = 21, .flags = RATE_IN_36XX },
-	{ .div = 22, .val = 22, .flags = RATE_IN_36XX },
-	{ .div = 23, .val = 23, .flags = RATE_IN_36XX },
-	{ .div = 24, .val = 24, .flags = RATE_IN_36XX },
-	{ .div = 25, .val = 25, .flags = RATE_IN_36XX },
-	{ .div = 26, .val = 26, .flags = RATE_IN_36XX },
-	{ .div = 27, .val = 27, .flags = RATE_IN_36XX },
-	{ .div = 28, .val = 28, .flags = RATE_IN_36XX },
-	{ .div = 29, .val = 29, .flags = RATE_IN_36XX },
-	{ .div = 30, .val = 30, .flags = RATE_IN_36XX },
-	{ .div = 31, .val = 31, .flags = RATE_IN_36XX },
-	{ .div = 32, .val = 32, .flags = RATE_IN_36XX },
-	{ .div = 0 }
-};
-
-/* DPLL1 */
-/* MPU clock source */
-/* Type: DPLL */
-static struct dpll_data dpll1_dd = {
-	.mult_div1_reg	= OMAP_CM_REGADDR(MPU_MOD, OMAP3430_CM_CLKSEL1_PLL),
-	.mult_mask	= OMAP3430_MPU_DPLL_MULT_MASK,
-	.div1_mask	= OMAP3430_MPU_DPLL_DIV_MASK,
-	.clk_bypass	= &dpll1_fck,
-	.clk_ref	= &sys_ck,
-	.freqsel_mask	= OMAP3430_MPU_DPLL_FREQSEL_MASK,
-	.control_reg	= OMAP_CM_REGADDR(MPU_MOD, OMAP3430_CM_CLKEN_PLL),
-	.enable_mask	= OMAP3430_EN_MPU_DPLL_MASK,
-	.modes		= (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
-	.auto_recal_bit	= OMAP3430_EN_MPU_DPLL_DRIFTGUARD_SHIFT,
-	.recal_en_bit	= OMAP3430_MPU_DPLL_RECAL_EN_SHIFT,
-	.recal_st_bit	= OMAP3430_MPU_DPLL_ST_SHIFT,
-	.autoidle_reg	= OMAP_CM_REGADDR(MPU_MOD, OMAP3430_CM_AUTOIDLE_PLL),
-	.autoidle_mask	= OMAP3430_AUTO_MPU_DPLL_MASK,
-	.idlest_reg	= OMAP_CM_REGADDR(MPU_MOD, OMAP3430_CM_IDLEST_PLL),
-	.idlest_mask	= OMAP3430_ST_MPU_CLK_MASK,
-	.max_multiplier = OMAP3_MAX_DPLL_MULT,
-	.min_divider	= 1,
-	.max_divider	= OMAP3_MAX_DPLL_DIV,
-};
-
-static struct clk dpll1_ck = {
-	.name		= "dpll1_ck",
-	.ops		= &clkops_omap3_noncore_dpll_ops,
-	.parent		= &sys_ck,
-	.dpll_data	= &dpll1_dd,
-	.round_rate	= &omap2_dpll_round_rate,
-	.set_rate	= &omap3_noncore_dpll_set_rate,
-	.clkdm_name	= "dpll1_clkdm",
-	.recalc		= &omap3_dpll_recalc,
-};
-
-/*
- * This virtual clock provides the CLKOUTX2 output from the DPLL if the
- * DPLL isn't bypassed.
- */
-static struct clk dpll1_x2_ck = {
-	.name		= "dpll1_x2_ck",
-	.ops		= &clkops_null,
-	.parent		= &dpll1_ck,
-	.clkdm_name	= "dpll1_clkdm",
-	.recalc		= &omap3_clkoutx2_recalc,
-};
-
-/* On DPLL1, unlike other DPLLs, the divider is downstream from CLKOUTX2 */
-static const struct clksel div16_dpll1_x2m2_clksel[] = {
-	{ .parent = &dpll1_x2_ck, .rates = div16_dpll_rates },
-	{ .parent = NULL }
-};
-
-/*
- * Does not exist in the TRM - needed to separate the M2 divider from
- * bypass selection in mpu_ck
- */
-static struct clk dpll1_x2m2_ck = {
-	.name		= "dpll1_x2m2_ck",
-	.ops		= &clkops_null,
-	.parent		= &dpll1_x2_ck,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(MPU_MOD, OMAP3430_CM_CLKSEL2_PLL),
-	.clksel_mask	= OMAP3430_MPU_DPLL_CLKOUT_DIV_MASK,
-	.clksel		= div16_dpll1_x2m2_clksel,
-	.clkdm_name	= "dpll1_clkdm",
-	.recalc		= &omap2_clksel_recalc,
-};
-
-/* DPLL2 */
-/* IVA2 clock source */
-/* Type: DPLL */
-
-static struct dpll_data dpll2_dd = {
-	.mult_div1_reg	= OMAP_CM_REGADDR(OMAP3430_IVA2_MOD, OMAP3430_CM_CLKSEL1_PLL),
-	.mult_mask	= OMAP3430_IVA2_DPLL_MULT_MASK,
-	.div1_mask	= OMAP3430_IVA2_DPLL_DIV_MASK,
-	.clk_bypass	= &dpll2_fck,
-	.clk_ref	= &sys_ck,
-	.freqsel_mask	= OMAP3430_IVA2_DPLL_FREQSEL_MASK,
-	.control_reg	= OMAP_CM_REGADDR(OMAP3430_IVA2_MOD, OMAP3430_CM_CLKEN_PLL),
-	.enable_mask	= OMAP3430_EN_IVA2_DPLL_MASK,
-	.modes		= (1 << DPLL_LOW_POWER_STOP) | (1 << DPLL_LOCKED) |
-				(1 << DPLL_LOW_POWER_BYPASS),
-	.auto_recal_bit	= OMAP3430_EN_IVA2_DPLL_DRIFTGUARD_SHIFT,
-	.recal_en_bit	= OMAP3430_PRM_IRQENABLE_MPU_IVA2_DPLL_RECAL_EN_SHIFT,
-	.recal_st_bit	= OMAP3430_PRM_IRQSTATUS_MPU_IVA2_DPLL_ST_SHIFT,
-	.autoidle_reg	= OMAP_CM_REGADDR(OMAP3430_IVA2_MOD, OMAP3430_CM_AUTOIDLE_PLL),
-	.autoidle_mask	= OMAP3430_AUTO_IVA2_DPLL_MASK,
-	.idlest_reg	= OMAP_CM_REGADDR(OMAP3430_IVA2_MOD, OMAP3430_CM_IDLEST_PLL),
-	.idlest_mask	= OMAP3430_ST_IVA2_CLK_MASK,
-	.max_multiplier = OMAP3_MAX_DPLL_MULT,
-	.min_divider	= 1,
-	.max_divider	= OMAP3_MAX_DPLL_DIV,
-};
-
-static struct clk dpll2_ck = {
-	.name		= "dpll2_ck",
-	.ops		= &clkops_omap3_noncore_dpll_ops,
-	.parent		= &sys_ck,
-	.dpll_data	= &dpll2_dd,
-	.round_rate	= &omap2_dpll_round_rate,
-	.set_rate	= &omap3_noncore_dpll_set_rate,
-	.clkdm_name	= "dpll2_clkdm",
-	.recalc		= &omap3_dpll_recalc,
-};
-
-static const struct clksel div16_dpll2_m2x2_clksel[] = {
-	{ .parent = &dpll2_ck, .rates = div16_dpll_rates },
-	{ .parent = NULL }
-};
-
-/*
- * The TRM is conflicted on whether IVA2 clock comes from DPLL2 CLKOUT
- * or CLKOUTX2. CLKOUT seems most plausible.
- */
-static struct clk dpll2_m2_ck = {
-	.name		= "dpll2_m2_ck",
-	.ops		= &clkops_null,
-	.parent		= &dpll2_ck,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(OMAP3430_IVA2_MOD,
-					  OMAP3430_CM_CLKSEL2_PLL),
-	.clksel_mask	= OMAP3430_IVA2_DPLL_CLKOUT_DIV_MASK,
-	.clksel		= div16_dpll2_m2x2_clksel,
-	.clkdm_name	= "dpll2_clkdm",
-	.recalc		= &omap2_clksel_recalc,
-};
-
-/*
- * DPLL3
- * Source clock for all interfaces and for some device fclks
- * REVISIT: Also supports fast relock bypass - not included below
- */
-static struct dpll_data dpll3_dd = {
-	.mult_div1_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1),
-	.mult_mask	= OMAP3430_CORE_DPLL_MULT_MASK,
-	.div1_mask	= OMAP3430_CORE_DPLL_DIV_MASK,
-	.clk_bypass	= &sys_ck,
-	.clk_ref	= &sys_ck,
-	.freqsel_mask	= OMAP3430_CORE_DPLL_FREQSEL_MASK,
-	.control_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
-	.enable_mask	= OMAP3430_EN_CORE_DPLL_MASK,
-	.auto_recal_bit	= OMAP3430_EN_CORE_DPLL_DRIFTGUARD_SHIFT,
-	.recal_en_bit	= OMAP3430_CORE_DPLL_RECAL_EN_SHIFT,
-	.recal_st_bit	= OMAP3430_CORE_DPLL_ST_SHIFT,
-	.autoidle_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_AUTOIDLE),
-	.autoidle_mask	= OMAP3430_AUTO_CORE_DPLL_MASK,
-	.idlest_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST),
-	.idlest_mask	= OMAP3430_ST_CORE_CLK_MASK,
-	.max_multiplier = OMAP3_MAX_DPLL_MULT,
-	.min_divider	= 1,
-	.max_divider	= OMAP3_MAX_DPLL_DIV,
-};
-
-static struct clk dpll3_ck = {
-	.name		= "dpll3_ck",
-	.ops		= &clkops_omap3_core_dpll_ops,
-	.parent		= &sys_ck,
-	.dpll_data	= &dpll3_dd,
-	.round_rate	= &omap2_dpll_round_rate,
-	.clkdm_name	= "dpll3_clkdm",
-	.recalc		= &omap3_dpll_recalc,
-};
-
-/*
- * This virtual clock provides the CLKOUTX2 output from the DPLL if the
- * DPLL isn't bypassed
- */
-static struct clk dpll3_x2_ck = {
-	.name		= "dpll3_x2_ck",
-	.ops		= &clkops_null,
-	.parent		= &dpll3_ck,
-	.clkdm_name	= "dpll3_clkdm",
-	.recalc		= &omap3_clkoutx2_recalc,
-};
-
-static const struct clksel_rate div31_dpll3_rates[] = {
-	{ .div = 1, .val = 1, .flags = RATE_IN_3XXX },
-	{ .div = 2, .val = 2, .flags = RATE_IN_3XXX },
-	{ .div = 3, .val = 3, .flags = RATE_IN_3430ES2PLUS_36XX },
-	{ .div = 4, .val = 4, .flags = RATE_IN_3430ES2PLUS_36XX },
-	{ .div = 5, .val = 5, .flags = RATE_IN_3430ES2PLUS_36XX },
-	{ .div = 6, .val = 6, .flags = RATE_IN_3430ES2PLUS_36XX },
-	{ .div = 7, .val = 7, .flags = RATE_IN_3430ES2PLUS_36XX },
-	{ .div = 8, .val = 8, .flags = RATE_IN_3430ES2PLUS_36XX },
-	{ .div = 9, .val = 9, .flags = RATE_IN_3430ES2PLUS_36XX },
-	{ .div = 10, .val = 10, .flags = RATE_IN_3430ES2PLUS_36XX },
-	{ .div = 11, .val = 11, .flags = RATE_IN_3430ES2PLUS_36XX },
-	{ .div = 12, .val = 12, .flags = RATE_IN_3430ES2PLUS_36XX },
-	{ .div = 13, .val = 13, .flags = RATE_IN_3430ES2PLUS_36XX },
-	{ .div = 14, .val = 14, .flags = RATE_IN_3430ES2PLUS_36XX },
-	{ .div = 15, .val = 15, .flags = RATE_IN_3430ES2PLUS_36XX },
-	{ .div = 16, .val = 16, .flags = RATE_IN_3430ES2PLUS_36XX },
-	{ .div = 17, .val = 17, .flags = RATE_IN_3430ES2PLUS_36XX },
-	{ .div = 18, .val = 18, .flags = RATE_IN_3430ES2PLUS_36XX },
-	{ .div = 19, .val = 19, .flags = RATE_IN_3430ES2PLUS_36XX },
-	{ .div = 20, .val = 20, .flags = RATE_IN_3430ES2PLUS_36XX },
-	{ .div = 21, .val = 21, .flags = RATE_IN_3430ES2PLUS_36XX },
-	{ .div = 22, .val = 22, .flags = RATE_IN_3430ES2PLUS_36XX },
-	{ .div = 23, .val = 23, .flags = RATE_IN_3430ES2PLUS_36XX },
-	{ .div = 24, .val = 24, .flags = RATE_IN_3430ES2PLUS_36XX },
-	{ .div = 25, .val = 25, .flags = RATE_IN_3430ES2PLUS_36XX },
-	{ .div = 26, .val = 26, .flags = RATE_IN_3430ES2PLUS_36XX },
-	{ .div = 27, .val = 27, .flags = RATE_IN_3430ES2PLUS_36XX },
-	{ .div = 28, .val = 28, .flags = RATE_IN_3430ES2PLUS_36XX },
-	{ .div = 29, .val = 29, .flags = RATE_IN_3430ES2PLUS_36XX },
-	{ .div = 30, .val = 30, .flags = RATE_IN_3430ES2PLUS_36XX },
-	{ .div = 31, .val = 31, .flags = RATE_IN_3430ES2PLUS_36XX },
-	{ .div = 0 },
-};
-
-static const struct clksel div31_dpll3m2_clksel[] = {
-	{ .parent = &dpll3_ck, .rates = div31_dpll3_rates },
-	{ .parent = NULL }
-};
-
-/* DPLL3 output M2 - primary control point for CORE speed */
-static struct clk dpll3_m2_ck = {
-	.name		= "dpll3_m2_ck",
-	.ops		= &clkops_null,
-	.parent		= &dpll3_ck,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1),
-	.clksel_mask	= OMAP3430_CORE_DPLL_CLKOUT_DIV_MASK,
-	.clksel		= div31_dpll3m2_clksel,
-	.clkdm_name	= "dpll3_clkdm",
-	.round_rate	= &omap2_clksel_round_rate,
-	.set_rate	= &omap3_core_dpll_m2_set_rate,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk core_ck = {
-	.name		= "core_ck",
-	.ops		= &clkops_null,
-	.parent		= &dpll3_m2_ck,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk dpll3_m2x2_ck = {
-	.name		= "dpll3_m2x2_ck",
-	.ops		= &clkops_null,
-	.parent		= &dpll3_m2_ck,
-	.clkdm_name	= "dpll3_clkdm",
-	.recalc		= &omap3_clkoutx2_recalc,
-};
-
-/* The PWRDN bit is apparently only available on 3430ES2 and above */
-static const struct clksel div16_dpll3_clksel[] = {
-	{ .parent = &dpll3_ck, .rates = div16_dpll_rates },
-	{ .parent = NULL }
-};
-
-/* This virtual clock is the source for dpll3_m3x2_ck */
-static struct clk dpll3_m3_ck = {
-	.name		= "dpll3_m3_ck",
-	.ops		= &clkops_null,
-	.parent		= &dpll3_ck,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(OMAP3430_EMU_MOD, CM_CLKSEL1),
-	.clksel_mask	= OMAP3430_DIV_DPLL3_MASK,
-	.clksel		= div16_dpll3_clksel,
-	.clkdm_name	= "dpll3_clkdm",
-	.recalc		= &omap2_clksel_recalc,
-};
-
-/* The PWRDN bit is apparently only available on 3430ES2 and above */
-static struct clk dpll3_m3x2_ck = {
-	.name		= "dpll3_m3x2_ck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &dpll3_m3_ck,
-	.enable_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
-	.enable_bit	= OMAP3430_PWRDN_EMU_CORE_SHIFT,
-	.flags		= INVERT_ENABLE,
-	.clkdm_name	= "dpll3_clkdm",
-	.recalc		= &omap3_clkoutx2_recalc,
-};
-
-static struct clk emu_core_alwon_ck = {
-	.name		= "emu_core_alwon_ck",
-	.ops		= &clkops_null,
-	.parent		= &dpll3_m3x2_ck,
-	.clkdm_name	= "dpll3_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-/* DPLL4 */
-/* Supplies 96MHz, 54Mhz TV DAC, DSS fclk, CAM sensor clock, emul trace clk */
-/* Type: DPLL */
-static struct dpll_data dpll4_dd;
-
-static struct dpll_data dpll4_dd_34xx __initdata = {
-	.mult_div1_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL2),
-	.mult_mask	= OMAP3430_PERIPH_DPLL_MULT_MASK,
-	.div1_mask	= OMAP3430_PERIPH_DPLL_DIV_MASK,
-	.clk_bypass	= &sys_ck,
-	.clk_ref	= &sys_ck,
-	.freqsel_mask	= OMAP3430_PERIPH_DPLL_FREQSEL_MASK,
-	.control_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
-	.enable_mask	= OMAP3430_EN_PERIPH_DPLL_MASK,
-	.modes		= (1 << DPLL_LOW_POWER_STOP) | (1 << DPLL_LOCKED),
-	.auto_recal_bit	= OMAP3430_EN_PERIPH_DPLL_DRIFTGUARD_SHIFT,
-	.recal_en_bit	= OMAP3430_PERIPH_DPLL_RECAL_EN_SHIFT,
-	.recal_st_bit	= OMAP3430_PERIPH_DPLL_ST_SHIFT,
-	.autoidle_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_AUTOIDLE),
-	.autoidle_mask	= OMAP3430_AUTO_PERIPH_DPLL_MASK,
-	.idlest_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST),
-	.idlest_mask	= OMAP3430_ST_PERIPH_CLK_MASK,
-	.max_multiplier = OMAP3_MAX_DPLL_MULT,
-	.min_divider	= 1,
-	.max_divider	= OMAP3_MAX_DPLL_DIV,
-};
-
-static struct dpll_data dpll4_dd_3630 __initdata = {
-	.mult_div1_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL2),
-	.mult_mask	= OMAP3630_PERIPH_DPLL_MULT_MASK,
-	.div1_mask	= OMAP3430_PERIPH_DPLL_DIV_MASK,
-	.clk_bypass	= &sys_ck,
-	.clk_ref	= &sys_ck,
-	.control_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
-	.enable_mask	= OMAP3430_EN_PERIPH_DPLL_MASK,
-	.modes		= (1 << DPLL_LOW_POWER_STOP) | (1 << DPLL_LOCKED),
-	.auto_recal_bit	= OMAP3430_EN_PERIPH_DPLL_DRIFTGUARD_SHIFT,
-	.recal_en_bit	= OMAP3430_PERIPH_DPLL_RECAL_EN_SHIFT,
-	.recal_st_bit	= OMAP3430_PERIPH_DPLL_ST_SHIFT,
-	.autoidle_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_AUTOIDLE),
-	.autoidle_mask	= OMAP3430_AUTO_PERIPH_DPLL_MASK,
-	.idlest_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST),
-	.idlest_mask	= OMAP3430_ST_PERIPH_CLK_MASK,
-	.dco_mask	= OMAP3630_PERIPH_DPLL_DCO_SEL_MASK,
-	.sddiv_mask	= OMAP3630_PERIPH_DPLL_SD_DIV_MASK,
-	.max_multiplier = OMAP3630_MAX_JTYPE_DPLL_MULT,
-	.min_divider	= 1,
-	.max_divider	= OMAP3_MAX_DPLL_DIV,
-	.flags		= DPLL_J_TYPE
-};
-
-static struct clk dpll4_ck = {
-	.name		= "dpll4_ck",
-	.ops		= &clkops_omap3_noncore_dpll_ops,
-	.parent		= &sys_ck,
-	.dpll_data	= &dpll4_dd,
-	.round_rate	= &omap2_dpll_round_rate,
-	.set_rate	= &omap3_dpll4_set_rate,
-	.clkdm_name	= "dpll4_clkdm",
-	.recalc		= &omap3_dpll_recalc,
-};
-
-/*
- * This virtual clock provides the CLKOUTX2 output from the DPLL if the
- * DPLL isn't bypassed --
- * XXX does this serve any downstream clocks?
- */
-static struct clk dpll4_x2_ck = {
-	.name		= "dpll4_x2_ck",
-	.ops		= &clkops_null,
-	.parent		= &dpll4_ck,
-	.clkdm_name	= "dpll4_clkdm",
-	.recalc		= &omap3_clkoutx2_recalc,
-};
-
-static const struct clksel dpll4_clksel[] = {
-	{ .parent = &dpll4_ck, .rates = dpll4_rates },
-	{ .parent = NULL }
-};
-
-/* This virtual clock is the source for dpll4_m2x2_ck */
-static struct clk dpll4_m2_ck = {
-	.name		= "dpll4_m2_ck",
-	.ops		= &clkops_null,
-	.parent		= &dpll4_ck,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(PLL_MOD, OMAP3430_CM_CLKSEL3),
-	.clksel_mask	= OMAP3630_DIV_96M_MASK,
-	.clksel		= dpll4_clksel,
-	.clkdm_name	= "dpll4_clkdm",
-	.recalc		= &omap2_clksel_recalc,
-};
-
-/* The PWRDN bit is apparently only available on 3430ES2 and above */
-static struct clk dpll4_m2x2_ck = {
-	.name		= "dpll4_m2x2_ck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &dpll4_m2_ck,
-	.enable_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
-	.enable_bit	= OMAP3430_PWRDN_96M_SHIFT,
-	.flags		= INVERT_ENABLE,
-	.clkdm_name	= "dpll4_clkdm",
-	.recalc		= &omap3_clkoutx2_recalc,
-};
-
-/*
- * DPLL4 generates DPLL4_M2X2_CLK which is then routed into the PRM as
- * PRM_96M_ALWON_(F)CLK.  Two clocks then emerge from the PRM:
- * 96M_ALWON_FCLK (called "omap_96m_alwon_fck" below) and
- * CM_96K_(F)CLK.
- */
-
-/* Adding 192MHz Clock node needed by SGX */
-static struct clk omap_192m_alwon_fck = {
-	.name		= "omap_192m_alwon_fck",
-	.ops		= &clkops_null,
-	.parent		= &dpll4_m2x2_ck,
-	.recalc		= &followparent_recalc,
-};
-
-static const struct clksel_rate omap_96m_alwon_fck_rates[] = {
-	{ .div = 1, .val = 1, .flags = RATE_IN_36XX },
-	{ .div = 2, .val = 2, .flags = RATE_IN_36XX },
-	{ .div = 0 }
-};
-
-static const struct clksel omap_96m_alwon_fck_clksel[] = {
-	{ .parent = &omap_192m_alwon_fck, .rates = omap_96m_alwon_fck_rates },
-	{ .parent = NULL }
-};
-
-static const struct clksel_rate omap_96m_dpll_rates[] = {
-	{ .div = 1, .val = 0, .flags = RATE_IN_3XXX },
-	{ .div = 0 }
-};
-
-static const struct clksel_rate omap_96m_sys_rates[] = {
-	{ .div = 1, .val = 1, .flags = RATE_IN_3XXX },
-	{ .div = 0 }
-};
-
-static struct clk omap_96m_alwon_fck = {
-	.name		= "omap_96m_alwon_fck",
-	.ops		= &clkops_null,
-	.parent		= &dpll4_m2x2_ck,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk omap_96m_alwon_fck_3630 = {
-	.name		= "omap_96m_alwon_fck",
-	.parent		= &omap_192m_alwon_fck,
-	.init		= &omap2_init_clksel_parent,
-	.ops		= &clkops_null,
-	.recalc		= &omap2_clksel_recalc,
-	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL),
-	.clksel_mask	= OMAP3630_CLKSEL_96M_MASK,
-	.clksel		= omap_96m_alwon_fck_clksel
-};
-
-static struct clk cm_96m_fck = {
-	.name		= "cm_96m_fck",
-	.ops		= &clkops_null,
-	.parent		= &omap_96m_alwon_fck,
-	.recalc		= &followparent_recalc,
-};
-
-static const struct clksel omap_96m_fck_clksel[] = {
-	{ .parent = &cm_96m_fck, .rates = omap_96m_dpll_rates },
-	{ .parent = &sys_ck,	 .rates = omap_96m_sys_rates },
-	{ .parent = NULL }
-};
-
-static struct clk omap_96m_fck = {
-	.name		= "omap_96m_fck",
-	.ops		= &clkops_null,
-	.parent		= &sys_ck,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1),
-	.clksel_mask	= OMAP3430_SOURCE_96M_MASK,
-	.clksel		= omap_96m_fck_clksel,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-/* This virtual clock is the source for dpll4_m3x2_ck */
-static struct clk dpll4_m3_ck = {
-	.name		= "dpll4_m3_ck",
-	.ops		= &clkops_null,
-	.parent		= &dpll4_ck,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_CLKSEL),
-	.clksel_mask	= OMAP3630_CLKSEL_TV_MASK,
-	.clksel		= dpll4_clksel,
-	.clkdm_name	= "dpll4_clkdm",
-	.recalc		= &omap2_clksel_recalc,
-};
-
-/* The PWRDN bit is apparently only available on 3430ES2 and above */
-static struct clk dpll4_m3x2_ck = {
-	.name		= "dpll4_m3x2_ck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &dpll4_m3_ck,
-	.enable_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
-	.enable_bit	= OMAP3430_PWRDN_TV_SHIFT,
-	.flags		= INVERT_ENABLE,
-	.clkdm_name	= "dpll4_clkdm",
-	.recalc		= &omap3_clkoutx2_recalc,
-};
-
-static const struct clksel_rate omap_54m_d4m3x2_rates[] = {
-	{ .div = 1, .val = 0, .flags = RATE_IN_3XXX },
-	{ .div = 0 }
-};
-
-static const struct clksel_rate omap_54m_alt_rates[] = {
-	{ .div = 1, .val = 1, .flags = RATE_IN_3XXX },
-	{ .div = 0 }
-};
-
-static const struct clksel omap_54m_clksel[] = {
-	{ .parent = &dpll4_m3x2_ck, .rates = omap_54m_d4m3x2_rates },
-	{ .parent = &sys_altclk,    .rates = omap_54m_alt_rates },
-	{ .parent = NULL }
-};
-
-static struct clk omap_54m_fck = {
-	.name		= "omap_54m_fck",
-	.ops		= &clkops_null,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1),
-	.clksel_mask	= OMAP3430_SOURCE_54M_MASK,
-	.clksel		= omap_54m_clksel,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static const struct clksel_rate omap_48m_cm96m_rates[] = {
-	{ .div = 2, .val = 0, .flags = RATE_IN_3XXX },
-	{ .div = 0 }
-};
-
-static const struct clksel_rate omap_48m_alt_rates[] = {
-	{ .div = 1, .val = 1, .flags = RATE_IN_3XXX },
-	{ .div = 0 }
-};
-
-static const struct clksel omap_48m_clksel[] = {
-	{ .parent = &cm_96m_fck, .rates = omap_48m_cm96m_rates },
-	{ .parent = &sys_altclk, .rates = omap_48m_alt_rates },
-	{ .parent = NULL }
-};
-
-static struct clk omap_48m_fck = {
-	.name		= "omap_48m_fck",
-	.ops		= &clkops_null,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1),
-	.clksel_mask	= OMAP3430_SOURCE_48M_MASK,
-	.clksel		= omap_48m_clksel,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk omap_12m_fck = {
-	.name		= "omap_12m_fck",
-	.ops		= &clkops_null,
-	.parent		= &omap_48m_fck,
-	.fixed_div	= 4,
-	.recalc		= &omap_fixed_divisor_recalc,
-};
-
-/* This virtual clock is the source for dpll4_m4x2_ck */
-static struct clk dpll4_m4_ck = {
-	.name		= "dpll4_m4_ck",
-	.ops		= &clkops_null,
-	.parent		= &dpll4_ck,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_CLKSEL),
-	.clksel_mask	= OMAP3630_CLKSEL_DSS1_MASK,
-	.clksel		= dpll4_clksel,
-	.clkdm_name	= "dpll4_clkdm",
-	.recalc		= &omap2_clksel_recalc,
-	.set_rate	= &omap2_clksel_set_rate,
-	.round_rate	= &omap2_clksel_round_rate,
-};
-
-/* The PWRDN bit is apparently only available on 3430ES2 and above */
-static struct clk dpll4_m4x2_ck = {
-	.name		= "dpll4_m4x2_ck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &dpll4_m4_ck,
-	.enable_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
-	.enable_bit	= OMAP3430_PWRDN_DSS1_SHIFT,
-	.flags		= INVERT_ENABLE,
-	.clkdm_name	= "dpll4_clkdm",
-	.recalc		= &omap3_clkoutx2_recalc,
-};
-
-/* This virtual clock is the source for dpll4_m5x2_ck */
-static struct clk dpll4_m5_ck = {
-	.name		= "dpll4_m5_ck",
-	.ops		= &clkops_null,
-	.parent		= &dpll4_ck,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(OMAP3430_CAM_MOD, CM_CLKSEL),
-	.clksel_mask	= OMAP3630_CLKSEL_CAM_MASK,
-	.clksel		= dpll4_clksel,
-	.clkdm_name	= "dpll4_clkdm",
-	.set_rate	= &omap2_clksel_set_rate,
-	.round_rate	= &omap2_clksel_round_rate,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-/* The PWRDN bit is apparently only available on 3430ES2 and above */
-static struct clk dpll4_m5x2_ck = {
-	.name		= "dpll4_m5x2_ck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &dpll4_m5_ck,
-	.enable_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
-	.enable_bit	= OMAP3430_PWRDN_CAM_SHIFT,
-	.flags		= INVERT_ENABLE,
-	.clkdm_name	= "dpll4_clkdm",
-	.recalc		= &omap3_clkoutx2_recalc,
-};
-
-/* This virtual clock is the source for dpll4_m6x2_ck */
-static struct clk dpll4_m6_ck = {
-	.name		= "dpll4_m6_ck",
-	.ops		= &clkops_null,
-	.parent		= &dpll4_ck,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(OMAP3430_EMU_MOD, CM_CLKSEL1),
-	.clksel_mask	= OMAP3630_DIV_DPLL4_MASK,
-	.clksel		= dpll4_clksel,
-	.clkdm_name	= "dpll4_clkdm",
-	.recalc		= &omap2_clksel_recalc,
-};
-
-/* The PWRDN bit is apparently only available on 3430ES2 and above */
-static struct clk dpll4_m6x2_ck = {
-	.name		= "dpll4_m6x2_ck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &dpll4_m6_ck,
-	.enable_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
-	.enable_bit	= OMAP3430_PWRDN_EMU_PERIPH_SHIFT,
-	.flags		= INVERT_ENABLE,
-	.clkdm_name	= "dpll4_clkdm",
-	.recalc		= &omap3_clkoutx2_recalc,
-};
-
-static struct clk emu_per_alwon_ck = {
-	.name		= "emu_per_alwon_ck",
-	.ops		= &clkops_null,
-	.parent		= &dpll4_m6x2_ck,
-	.clkdm_name	= "dpll4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-/* DPLL5 */
-/* Supplies 120MHz clock, USIM source clock */
-/* Type: DPLL */
-/* 3430ES2 only */
-static struct dpll_data dpll5_dd = {
-	.mult_div1_reg	= OMAP_CM_REGADDR(PLL_MOD, OMAP3430ES2_CM_CLKSEL4),
-	.mult_mask	= OMAP3430ES2_PERIPH2_DPLL_MULT_MASK,
-	.div1_mask	= OMAP3430ES2_PERIPH2_DPLL_DIV_MASK,
-	.clk_bypass	= &sys_ck,
-	.clk_ref	= &sys_ck,
-	.freqsel_mask	= OMAP3430ES2_PERIPH2_DPLL_FREQSEL_MASK,
-	.control_reg	= OMAP_CM_REGADDR(PLL_MOD, OMAP3430ES2_CM_CLKEN2),
-	.enable_mask	= OMAP3430ES2_EN_PERIPH2_DPLL_MASK,
-	.modes		= (1 << DPLL_LOW_POWER_STOP) | (1 << DPLL_LOCKED),
-	.auto_recal_bit	= OMAP3430ES2_EN_PERIPH2_DPLL_DRIFTGUARD_SHIFT,
-	.recal_en_bit	= OMAP3430ES2_SND_PERIPH_DPLL_RECAL_EN_SHIFT,
-	.recal_st_bit	= OMAP3430ES2_SND_PERIPH_DPLL_ST_SHIFT,
-	.autoidle_reg	= OMAP_CM_REGADDR(PLL_MOD, OMAP3430ES2_CM_AUTOIDLE2_PLL),
-	.autoidle_mask	= OMAP3430ES2_AUTO_PERIPH2_DPLL_MASK,
-	.idlest_reg	= OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST2),
-	.idlest_mask	= OMAP3430ES2_ST_PERIPH2_CLK_MASK,
-	.max_multiplier = OMAP3_MAX_DPLL_MULT,
-	.min_divider	= 1,
-	.max_divider	= OMAP3_MAX_DPLL_DIV,
-};
-
-static struct clk dpll5_ck = {
-	.name		= "dpll5_ck",
-	.ops		= &clkops_omap3_noncore_dpll_ops,
-	.parent		= &sys_ck,
-	.dpll_data	= &dpll5_dd,
-	.round_rate	= &omap2_dpll_round_rate,
-	.set_rate	= &omap3_noncore_dpll_set_rate,
-	.clkdm_name	= "dpll5_clkdm",
-	.recalc		= &omap3_dpll_recalc,
-};
-
-static const struct clksel div16_dpll5_clksel[] = {
-	{ .parent = &dpll5_ck, .rates = div16_dpll_rates },
-	{ .parent = NULL }
-};
-
-static struct clk dpll5_m2_ck = {
-	.name		= "dpll5_m2_ck",
-	.ops		= &clkops_null,
-	.parent		= &dpll5_ck,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(PLL_MOD, OMAP3430ES2_CM_CLKSEL5),
-	.clksel_mask	= OMAP3430ES2_DIV_120M_MASK,
-	.clksel		= div16_dpll5_clksel,
-	.clkdm_name	= "dpll5_clkdm",
-	.recalc		= &omap2_clksel_recalc,
-};
-
-/* CM EXTERNAL CLOCK OUTPUTS */
-
-static const struct clksel_rate clkout2_src_core_rates[] = {
-	{ .div = 1, .val = 0, .flags = RATE_IN_3XXX },
-	{ .div = 0 }
-};
-
-static const struct clksel_rate clkout2_src_sys_rates[] = {
-	{ .div = 1, .val = 1, .flags = RATE_IN_3XXX },
-	{ .div = 0 }
-};
-
-static const struct clksel_rate clkout2_src_96m_rates[] = {
-	{ .div = 1, .val = 2, .flags = RATE_IN_3XXX },
-	{ .div = 0 }
-};
-
-static const struct clksel_rate clkout2_src_54m_rates[] = {
-	{ .div = 1, .val = 3, .flags = RATE_IN_3XXX },
-	{ .div = 0 }
-};
-
-static const struct clksel clkout2_src_clksel[] = {
-	{ .parent = &core_ck,		.rates = clkout2_src_core_rates },
-	{ .parent = &sys_ck,		.rates = clkout2_src_sys_rates },
-	{ .parent = &cm_96m_fck,	.rates = clkout2_src_96m_rates },
-	{ .parent = &omap_54m_fck,	.rates = clkout2_src_54m_rates },
-	{ .parent = NULL }
-};
-
-static struct clk clkout2_src_ck = {
-	.name		= "clkout2_src_ck",
-	.ops		= &clkops_omap2_dflt,
-	.init		= &omap2_init_clksel_parent,
-	.enable_reg	= OMAP3430_CM_CLKOUT_CTRL,
-	.enable_bit	= OMAP3430_CLKOUT2_EN_SHIFT,
-	.clksel_reg	= OMAP3430_CM_CLKOUT_CTRL,
-	.clksel_mask	= OMAP3430_CLKOUT2SOURCE_MASK,
-	.clksel		= clkout2_src_clksel,
-	.clkdm_name	= "core_clkdm",
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static const struct clksel_rate sys_clkout2_rates[] = {
-	{ .div = 1, .val = 0, .flags = RATE_IN_3XXX },
-	{ .div = 2, .val = 1, .flags = RATE_IN_3XXX },
-	{ .div = 4, .val = 2, .flags = RATE_IN_3XXX },
-	{ .div = 8, .val = 3, .flags = RATE_IN_3XXX },
-	{ .div = 16, .val = 4, .flags = RATE_IN_3XXX },
-	{ .div = 0 },
-};
-
-static const struct clksel sys_clkout2_clksel[] = {
-	{ .parent = &clkout2_src_ck, .rates = sys_clkout2_rates },
-	{ .parent = NULL },
-};
-
-static struct clk sys_clkout2 = {
-	.name		= "sys_clkout2",
-	.ops		= &clkops_null,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP3430_CM_CLKOUT_CTRL,
-	.clksel_mask	= OMAP3430_CLKOUT2_DIV_MASK,
-	.clksel		= sys_clkout2_clksel,
-	.recalc		= &omap2_clksel_recalc,
-	.round_rate	= &omap2_clksel_round_rate,
-	.set_rate	= &omap2_clksel_set_rate
-};
-
-/* CM OUTPUT CLOCKS */
-
-static struct clk corex2_fck = {
-	.name		= "corex2_fck",
-	.ops		= &clkops_null,
-	.parent		= &dpll3_m2x2_ck,
-	.recalc		= &followparent_recalc,
-};
-
-/* DPLL power domain clock controls */
-
-static const struct clksel_rate div4_rates[] = {
-	{ .div = 1, .val = 1, .flags = RATE_IN_3XXX },
-	{ .div = 2, .val = 2, .flags = RATE_IN_3XXX },
-	{ .div = 4, .val = 4, .flags = RATE_IN_3XXX },
-	{ .div = 0 }
-};
-
-static const struct clksel div4_core_clksel[] = {
-	{ .parent = &core_ck, .rates = div4_rates },
-	{ .parent = NULL }
-};
-
-/*
- * REVISIT: Are these in DPLL power domain or CM power domain? docs
- * may be inconsistent here?
- */
-static struct clk dpll1_fck = {
-	.name		= "dpll1_fck",
-	.ops		= &clkops_null,
-	.parent		= &core_ck,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(MPU_MOD, OMAP3430_CM_CLKSEL1_PLL),
-	.clksel_mask	= OMAP3430_MPU_CLK_SRC_MASK,
-	.clksel		= div4_core_clksel,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk mpu_ck = {
-	.name		= "mpu_ck",
-	.ops		= &clkops_null,
-	.parent		= &dpll1_x2m2_ck,
-	.clkdm_name	= "mpu_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-/* arm_fck is divided by two when DPLL1 locked; otherwise, passthrough mpu_ck */
-static const struct clksel_rate arm_fck_rates[] = {
-	{ .div = 1, .val = 0, .flags = RATE_IN_3XXX },
-	{ .div = 2, .val = 1, .flags = RATE_IN_3XXX },
-	{ .div = 0 },
-};
-
-static const struct clksel arm_fck_clksel[] = {
-	{ .parent = &mpu_ck, .rates = arm_fck_rates },
-	{ .parent = NULL }
-};
-
-static struct clk arm_fck = {
-	.name		= "arm_fck",
-	.ops		= &clkops_null,
-	.parent		= &mpu_ck,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(MPU_MOD, OMAP3430_CM_IDLEST_PLL),
-	.clksel_mask	= OMAP3430_ST_MPU_CLK_MASK,
-	.clksel		= arm_fck_clksel,
-	.clkdm_name	= "mpu_clkdm",
-	.recalc		= &omap2_clksel_recalc,
-};
-
-/* XXX What about neon_clkdm ? */
-
-/*
- * REVISIT: This clock is never specifically defined in the 3430 TRM,
- * although it is referenced - so this is a guess
- */
-static struct clk emu_mpu_alwon_ck = {
-	.name		= "emu_mpu_alwon_ck",
-	.ops		= &clkops_null,
-	.parent		= &mpu_ck,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk dpll2_fck = {
-	.name		= "dpll2_fck",
-	.ops		= &clkops_null,
-	.parent		= &core_ck,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(OMAP3430_IVA2_MOD, OMAP3430_CM_CLKSEL1_PLL),
-	.clksel_mask	= OMAP3430_IVA2_CLK_SRC_MASK,
-	.clksel		= div4_core_clksel,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk iva2_ck = {
-	.name		= "iva2_ck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &dpll2_m2_ck,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_IVA2_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430_CM_FCLKEN_IVA2_EN_IVA2_SHIFT,
-	.clkdm_name	= "iva2_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-/* Common interface clocks */
-
-static const struct clksel div2_core_clksel[] = {
-	{ .parent = &core_ck, .rates = div2_rates },
-	{ .parent = NULL }
-};
-
-static struct clk l3_ick = {
-	.name		= "l3_ick",
-	.ops		= &clkops_null,
-	.parent		= &core_ck,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL),
-	.clksel_mask	= OMAP3430_CLKSEL_L3_MASK,
-	.clksel		= div2_core_clksel,
-	.clkdm_name	= "core_l3_clkdm",
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static const struct clksel div2_l3_clksel[] = {
-	{ .parent = &l3_ick, .rates = div2_rates },
-	{ .parent = NULL }
-};
-
-static struct clk l4_ick = {
-	.name		= "l4_ick",
-	.ops		= &clkops_null,
-	.parent		= &l3_ick,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL),
-	.clksel_mask	= OMAP3430_CLKSEL_L4_MASK,
-	.clksel		= div2_l3_clksel,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &omap2_clksel_recalc,
-
-};
-
-static const struct clksel div2_l4_clksel[] = {
-	{ .parent = &l4_ick, .rates = div2_rates },
-	{ .parent = NULL }
-};
-
-static struct clk rm_ick = {
-	.name		= "rm_ick",
-	.ops		= &clkops_null,
-	.parent		= &l4_ick,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_CLKSEL),
-	.clksel_mask	= OMAP3430_CLKSEL_RM_MASK,
-	.clksel		= div2_l4_clksel,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-/* GFX power domain */
-
-/* GFX clocks are in 3430ES1 only. 3430ES2 and later uses the SGX instead */
-
-static const struct clksel gfx_l3_clksel[] = {
-	{ .parent = &l3_ick, .rates = gfx_l3_rates },
-	{ .parent = NULL }
-};
-
-/*
- * Virtual parent clock for gfx_l3_ick and gfx_l3_fck
- * This interface clock does not have a CM_AUTOIDLE bit
- */
-static struct clk gfx_l3_ck = {
-	.name		= "gfx_l3_ck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &l3_ick,
-	.enable_reg	= OMAP_CM_REGADDR(GFX_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP_EN_GFX_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gfx_l3_fck = {
-	.name		= "gfx_l3_fck",
-	.ops		= &clkops_null,
-	.parent		= &gfx_l3_ck,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(GFX_MOD, CM_CLKSEL),
-	.clksel_mask	= OMAP_CLKSEL_GFX_MASK,
-	.clksel		= gfx_l3_clksel,
-	.clkdm_name	= "gfx_3430es1_clkdm",
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk gfx_l3_ick = {
-	.name		= "gfx_l3_ick",
-	.ops		= &clkops_null,
-	.parent		= &gfx_l3_ck,
-	.clkdm_name	= "gfx_3430es1_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gfx_cg1_ck = {
-	.name		= "gfx_cg1_ck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &gfx_l3_fck, /* REVISIT: correct? */
-	.enable_reg	= OMAP_CM_REGADDR(GFX_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430ES1_EN_2D_SHIFT,
-	.clkdm_name	= "gfx_3430es1_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gfx_cg2_ck = {
-	.name		= "gfx_cg2_ck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &gfx_l3_fck, /* REVISIT: correct? */
-	.enable_reg	= OMAP_CM_REGADDR(GFX_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430ES1_EN_3D_SHIFT,
-	.clkdm_name	= "gfx_3430es1_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-/* SGX power domain - 3430ES2 only */
-
-static const struct clksel_rate sgx_core_rates[] = {
-	{ .div = 2, .val = 5, .flags = RATE_IN_36XX },
-	{ .div = 3, .val = 0, .flags = RATE_IN_3XXX },
-	{ .div = 4, .val = 1, .flags = RATE_IN_3XXX },
-	{ .div = 6, .val = 2, .flags = RATE_IN_3XXX },
-	{ .div = 0 },
-};
-
-static const struct clksel_rate sgx_192m_rates[] = {
-	{ .div = 1,  .val = 4, .flags = RATE_IN_36XX },
-	{ .div = 0 },
-};
-
-static const struct clksel_rate sgx_corex2_rates[] = {
-	{ .div = 3, .val = 6, .flags = RATE_IN_36XX },
-	{ .div = 5, .val = 7, .flags = RATE_IN_36XX },
-	{ .div = 0 },
-};
-
-static const struct clksel_rate sgx_96m_rates[] = {
-	{ .div = 1,  .val = 3, .flags = RATE_IN_3XXX },
-	{ .div = 0 },
-};
-
-static const struct clksel sgx_clksel[] = {
-	{ .parent = &core_ck,	 .rates = sgx_core_rates },
-	{ .parent = &cm_96m_fck, .rates = sgx_96m_rates },
-	{ .parent = &omap_192m_alwon_fck, .rates = sgx_192m_rates },
-	{ .parent = &corex2_fck, .rates = sgx_corex2_rates },
-	{ .parent = NULL }
-};
-
-static struct clk sgx_fck = {
-	.name		= "sgx_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.init		= &omap2_init_clksel_parent,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430ES2_SGX_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430ES2_CM_FCLKEN_SGX_EN_SGX_SHIFT,
-	.clksel_reg	= OMAP_CM_REGADDR(OMAP3430ES2_SGX_MOD, CM_CLKSEL),
-	.clksel_mask	= OMAP3430ES2_CLKSEL_SGX_MASK,
-	.clksel		= sgx_clksel,
-	.clkdm_name	= "sgx_clkdm",
-	.recalc		= &omap2_clksel_recalc,
-	.set_rate	= &omap2_clksel_set_rate,
-	.round_rate	= &omap2_clksel_round_rate
-};
-
-/* This interface clock does not have a CM_AUTOIDLE bit */
-static struct clk sgx_ick = {
-	.name		= "sgx_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &l3_ick,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430ES2_SGX_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430ES2_CM_ICLKEN_SGX_EN_SGX_SHIFT,
-	.clkdm_name	= "sgx_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-/* CORE power domain */
-
-static struct clk d2d_26m_fck = {
-	.name		= "d2d_26m_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &sys_ck,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP3430ES1_EN_D2D_SHIFT,
-	.clkdm_name	= "d2d_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk modem_fck = {
-	.name		= "modem_fck",
-	.ops		= &clkops_omap2_mdmclk_dflt_wait,
-	.parent		= &sys_ck,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP3430_EN_MODEM_SHIFT,
-	.clkdm_name	= "d2d_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk sad2d_ick = {
-	.name		= "sad2d_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &l3_ick,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430_EN_SAD2D_SHIFT,
-	.clkdm_name	= "d2d_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mad2d_ick = {
-	.name		= "mad2d_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &l3_ick,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN3),
-	.enable_bit	= OMAP3430_EN_MAD2D_SHIFT,
-	.clkdm_name	= "d2d_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static const struct clksel omap343x_gpt_clksel[] = {
-	{ .parent = &omap_32k_fck, .rates = gpt_32k_rates },
-	{ .parent = &sys_ck,	   .rates = gpt_sys_rates },
-	{ .parent = NULL}
-};
-
-static struct clk gpt10_fck = {
-	.name		= "gpt10_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &sys_ck,
-	.init		= &omap2_init_clksel_parent,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP3430_EN_GPT10_SHIFT,
-	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL),
-	.clksel_mask	= OMAP3430_CLKSEL_GPT10_MASK,
-	.clksel		= omap343x_gpt_clksel,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk gpt11_fck = {
-	.name		= "gpt11_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &sys_ck,
-	.init		= &omap2_init_clksel_parent,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP3430_EN_GPT11_SHIFT,
-	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL),
-	.clksel_mask	= OMAP3430_CLKSEL_GPT11_MASK,
-	.clksel		= omap343x_gpt_clksel,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk cpefuse_fck = {
-	.name		= "cpefuse_fck",
-	.ops		= &clkops_omap2_dflt,
-	.parent		= &sys_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP3430ES2_CM_FCLKEN3),
-	.enable_bit	= OMAP3430ES2_EN_CPEFUSE_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk ts_fck = {
-	.name		= "ts_fck",
-	.ops		= &clkops_omap2_dflt,
-	.parent		= &omap_32k_fck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP3430ES2_CM_FCLKEN3),
-	.enable_bit	= OMAP3430ES2_EN_TS_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk usbtll_fck = {
-	.name		= "usbtll_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &dpll5_m2_ck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, OMAP3430ES2_CM_FCLKEN3),
-	.enable_bit	= OMAP3430ES2_EN_USBTLL_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-/* CORE 96M FCLK-derived clocks */
-
-static struct clk core_96m_fck = {
-	.name		= "core_96m_fck",
-	.ops		= &clkops_null,
-	.parent		= &omap_96m_fck,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mmchs3_fck = {
-	.name		= "mmchs3_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &core_96m_fck,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP3430ES2_EN_MMC3_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mmchs2_fck = {
-	.name		= "mmchs2_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &core_96m_fck,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP3430_EN_MMC2_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mspro_fck = {
-	.name		= "mspro_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &core_96m_fck,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP3430_EN_MSPRO_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mmchs1_fck = {
-	.name		= "mmchs1_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &core_96m_fck,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP3430_EN_MMC1_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk i2c3_fck = {
-	.name		= "i2c3_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &core_96m_fck,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP3430_EN_I2C3_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk i2c2_fck = {
-	.name		= "i2c2_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &core_96m_fck,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP3430_EN_I2C2_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk i2c1_fck = {
-	.name		= "i2c1_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &core_96m_fck,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP3430_EN_I2C1_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-/*
- * MCBSP 1 & 5 get their 96MHz clock from core_96m_fck;
- * MCBSP 2, 3, 4 get their 96MHz clock from per_96m_fck.
- */
-static const struct clksel_rate common_mcbsp_96m_rates[] = {
-	{ .div = 1, .val = 0, .flags = RATE_IN_3XXX },
-	{ .div = 0 }
-};
-
-static const struct clksel_rate common_mcbsp_mcbsp_rates[] = {
-	{ .div = 1, .val = 1, .flags = RATE_IN_3XXX },
-	{ .div = 0 }
-};
-
-static const struct clksel mcbsp_15_clksel[] = {
-	{ .parent = &core_96m_fck, .rates = common_mcbsp_96m_rates },
-	{ .parent = &mcbsp_clks,   .rates = common_mcbsp_mcbsp_rates },
-	{ .parent = NULL }
-};
-
-static struct clk mcbsp5_fck = {
-	.name		= "mcbsp5_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.init		= &omap2_init_clksel_parent,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP3430_EN_MCBSP5_SHIFT,
-	.clksel_reg	= OMAP343X_CTRL_REGADDR(OMAP343X_CONTROL_DEVCONF1),
-	.clksel_mask	= OMAP2_MCBSP5_CLKS_MASK,
-	.clksel		= mcbsp_15_clksel,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk mcbsp1_fck = {
-	.name		= "mcbsp1_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.init		= &omap2_init_clksel_parent,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP3430_EN_MCBSP1_SHIFT,
-	.clksel_reg	= OMAP343X_CTRL_REGADDR(OMAP2_CONTROL_DEVCONF0),
-	.clksel_mask	= OMAP2_MCBSP1_CLKS_MASK,
-	.clksel		= mcbsp_15_clksel,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &omap2_clksel_recalc,
-};
-
-/* CORE_48M_FCK-derived clocks */
-
-static struct clk core_48m_fck = {
-	.name		= "core_48m_fck",
-	.ops		= &clkops_null,
-	.parent		= &omap_48m_fck,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mcspi4_fck = {
-	.name		= "mcspi4_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &core_48m_fck,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP3430_EN_MCSPI4_SHIFT,
-	.recalc		= &followparent_recalc,
-	.clkdm_name	= "core_l4_clkdm",
-};
-
-static struct clk mcspi3_fck = {
-	.name		= "mcspi3_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &core_48m_fck,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP3430_EN_MCSPI3_SHIFT,
-	.recalc		= &followparent_recalc,
-	.clkdm_name	= "core_l4_clkdm",
-};
-
-static struct clk mcspi2_fck = {
-	.name		= "mcspi2_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &core_48m_fck,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP3430_EN_MCSPI2_SHIFT,
-	.recalc		= &followparent_recalc,
-	.clkdm_name	= "core_l4_clkdm",
-};
-
-static struct clk mcspi1_fck = {
-	.name		= "mcspi1_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &core_48m_fck,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP3430_EN_MCSPI1_SHIFT,
-	.recalc		= &followparent_recalc,
-	.clkdm_name	= "core_l4_clkdm",
-};
-
-static struct clk uart2_fck = {
-	.name		= "uart2_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &core_48m_fck,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP3430_EN_UART2_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk uart1_fck = {
-	.name		= "uart1_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &core_48m_fck,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP3430_EN_UART1_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk fshostusb_fck = {
-	.name		= "fshostusb_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &core_48m_fck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP3430ES1_EN_FSHOSTUSB_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-/* CORE_12M_FCK based clocks */
-
-static struct clk core_12m_fck = {
-	.name		= "core_12m_fck",
-	.ops		= &clkops_null,
-	.parent		= &omap_12m_fck,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk hdq_fck = {
-	.name		= "hdq_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &core_12m_fck,
-	.clkdm_name	= "core_l4_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP3430_EN_HDQ_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-/* DPLL3-derived clock */
-
-static const struct clksel_rate ssi_ssr_corex2_rates[] = {
-	{ .div = 1, .val = 1, .flags = RATE_IN_3XXX },
-	{ .div = 2, .val = 2, .flags = RATE_IN_3XXX },
-	{ .div = 3, .val = 3, .flags = RATE_IN_3XXX },
-	{ .div = 4, .val = 4, .flags = RATE_IN_3XXX },
-	{ .div = 6, .val = 6, .flags = RATE_IN_3XXX },
-	{ .div = 8, .val = 8, .flags = RATE_IN_3XXX },
-	{ .div = 0 }
-};
-
-static const struct clksel ssi_ssr_clksel[] = {
-	{ .parent = &corex2_fck, .rates = ssi_ssr_corex2_rates },
-	{ .parent = NULL }
-};
-
-static struct clk ssi_ssr_fck_3430es1 = {
-	.name		= "ssi_ssr_fck",
-	.ops		= &clkops_omap2_dflt,
-	.init		= &omap2_init_clksel_parent,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP3430_EN_SSI_SHIFT,
-	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL),
-	.clksel_mask	= OMAP3430_CLKSEL_SSI_MASK,
-	.clksel		= ssi_ssr_clksel,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk ssi_ssr_fck_3430es2 = {
-	.name		= "ssi_ssr_fck",
-	.ops		= &clkops_omap3430es2_ssi_wait,
-	.init		= &omap2_init_clksel_parent,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= OMAP3430_EN_SSI_SHIFT,
-	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL),
-	.clksel_mask	= OMAP3430_CLKSEL_SSI_MASK,
-	.clksel		= ssi_ssr_clksel,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk ssi_sst_fck_3430es1 = {
-	.name		= "ssi_sst_fck",
-	.ops		= &clkops_null,
-	.parent		= &ssi_ssr_fck_3430es1,
-	.fixed_div	= 2,
-	.recalc		= &omap_fixed_divisor_recalc,
-};
-
-static struct clk ssi_sst_fck_3430es2 = {
-	.name		= "ssi_sst_fck",
-	.ops		= &clkops_null,
-	.parent		= &ssi_ssr_fck_3430es2,
-	.fixed_div	= 2,
-	.recalc		= &omap_fixed_divisor_recalc,
-};
-
-
-
-/* CORE_L3_ICK based clocks */
-
-/*
- * XXX must add clk_enable/clk_disable for these if standard code won't
- * handle it
- */
-static struct clk core_l3_ick = {
-	.name		= "core_l3_ick",
-	.ops		= &clkops_null,
-	.parent		= &l3_ick,
-	.clkdm_name	= "core_l3_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk hsotgusb_ick_3430es1 = {
-	.name		= "hsotgusb_ick",
-	.ops		= &clkops_omap2_iclk_dflt,
-	.parent		= &core_l3_ick,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430_EN_HSOTGUSB_SHIFT,
-	.clkdm_name	= "core_l3_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk hsotgusb_ick_3430es2 = {
-	.name		= "hsotgusb_ick",
-	.ops		= &clkops_omap3430es2_iclk_hsotgusb_wait,
-	.parent		= &core_l3_ick,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430_EN_HSOTGUSB_SHIFT,
-	.clkdm_name	= "core_l3_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-/* This interface clock does not have a CM_AUTOIDLE bit */
-static struct clk sdrc_ick = {
-	.name		= "sdrc_ick",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &core_l3_ick,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430_EN_SDRC_SHIFT,
-	.flags		= ENABLE_ON_INIT,
-	.clkdm_name	= "core_l3_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpmc_fck = {
-	.name		= "gpmc_fck",
-	.ops		= &clkops_null,
-	.parent		= &core_l3_ick,
-	.flags		= ENABLE_ON_INIT, /* huh? */
-	.clkdm_name	= "core_l3_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-/* SECURITY_L3_ICK based clocks */
-
-static struct clk security_l3_ick = {
-	.name		= "security_l3_ick",
-	.ops		= &clkops_null,
-	.parent		= &l3_ick,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk pka_ick = {
-	.name		= "pka_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &security_l3_ick,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
-	.enable_bit	= OMAP3430_EN_PKA_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-/* CORE_L4_ICK based clocks */
-
-static struct clk core_l4_ick = {
-	.name		= "core_l4_ick",
-	.ops		= &clkops_null,
-	.parent		= &l4_ick,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk usbtll_ick = {
-	.name		= "usbtll_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &core_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN3),
-	.enable_bit	= OMAP3430ES2_EN_USBTLL_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mmchs3_ick = {
-	.name		= "mmchs3_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &core_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430ES2_EN_MMC3_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-/* Intersystem Communication Registers - chassis mode only */
-static struct clk icr_ick = {
-	.name		= "icr_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &core_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430_EN_ICR_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk aes2_ick = {
-	.name		= "aes2_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &core_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430_EN_AES2_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk sha12_ick = {
-	.name		= "sha12_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &core_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430_EN_SHA12_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk des2_ick = {
-	.name		= "des2_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &core_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430_EN_DES2_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mmchs2_ick = {
-	.name		= "mmchs2_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &core_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430_EN_MMC2_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mmchs1_ick = {
-	.name		= "mmchs1_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &core_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430_EN_MMC1_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mspro_ick = {
-	.name		= "mspro_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &core_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430_EN_MSPRO_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk hdq_ick = {
-	.name		= "hdq_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &core_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430_EN_HDQ_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mcspi4_ick = {
-	.name		= "mcspi4_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &core_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430_EN_MCSPI4_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mcspi3_ick = {
-	.name		= "mcspi3_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &core_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430_EN_MCSPI3_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mcspi2_ick = {
-	.name		= "mcspi2_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &core_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430_EN_MCSPI2_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mcspi1_ick = {
-	.name		= "mcspi1_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &core_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430_EN_MCSPI1_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk i2c3_ick = {
-	.name		= "i2c3_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &core_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430_EN_I2C3_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk i2c2_ick = {
-	.name		= "i2c2_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &core_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430_EN_I2C2_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk i2c1_ick = {
-	.name		= "i2c1_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &core_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430_EN_I2C1_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk uart2_ick = {
-	.name		= "uart2_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &core_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430_EN_UART2_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk uart1_ick = {
-	.name		= "uart1_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &core_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430_EN_UART1_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpt11_ick = {
-	.name		= "gpt11_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &core_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430_EN_GPT11_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpt10_ick = {
-	.name		= "gpt10_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &core_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430_EN_GPT10_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mcbsp5_ick = {
-	.name		= "mcbsp5_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &core_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430_EN_MCBSP5_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mcbsp1_ick = {
-	.name		= "mcbsp1_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &core_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430_EN_MCBSP1_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk fac_ick = {
-	.name		= "fac_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &core_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430ES1_EN_FAC_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mailboxes_ick = {
-	.name		= "mailboxes_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &core_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430_EN_MAILBOXES_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk omapctrl_ick = {
-	.name		= "omapctrl_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &core_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430_EN_OMAPCTRL_SHIFT,
-	.flags		= ENABLE_ON_INIT,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-/* SSI_L4_ICK based clocks */
-
-static struct clk ssi_l4_ick = {
-	.name		= "ssi_l4_ick",
-	.ops		= &clkops_null,
-	.parent		= &l4_ick,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk ssi_ick_3430es1 = {
-	.name		= "ssi_ick",
-	.ops		= &clkops_omap2_iclk_dflt,
-	.parent		= &ssi_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430_EN_SSI_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk ssi_ick_3430es2 = {
-	.name		= "ssi_ick",
-	.ops		= &clkops_omap3430es2_iclk_ssi_wait,
-	.parent		= &ssi_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430_EN_SSI_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-/* REVISIT: Technically the TRM claims that this is CORE_CLK based,
- * but l4_ick makes more sense to me */
-
-static const struct clksel usb_l4_clksel[] = {
-	{ .parent = &l4_ick, .rates = div2_rates },
-	{ .parent = NULL },
-};
-
-static struct clk usb_l4_ick = {
-	.name		= "usb_l4_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &l4_ick,
-	.init		= &omap2_init_clksel_parent,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= OMAP3430ES1_EN_FSHOSTUSB_SHIFT,
-	.clksel_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL),
-	.clksel_mask	= OMAP3430ES1_CLKSEL_FSHOSTUSB_MASK,
-	.clksel		= usb_l4_clksel,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &omap2_clksel_recalc,
-};
-
-/* SECURITY_L4_ICK2 based clocks */
-
-static struct clk security_l4_ick2 = {
-	.name		= "security_l4_ick2",
-	.ops		= &clkops_null,
-	.parent		= &l4_ick,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk aes1_ick = {
-	.name		= "aes1_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &security_l4_ick2,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
-	.enable_bit	= OMAP3430_EN_AES1_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk rng_ick = {
-	.name		= "rng_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &security_l4_ick2,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
-	.enable_bit	= OMAP3430_EN_RNG_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk sha11_ick = {
-	.name		= "sha11_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &security_l4_ick2,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
-	.enable_bit	= OMAP3430_EN_SHA11_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk des1_ick = {
-	.name		= "des1_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &security_l4_ick2,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
-	.enable_bit	= OMAP3430_EN_DES1_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-/* DSS */
-static struct clk dss1_alwon_fck_3430es1 = {
-	.name		= "dss1_alwon_fck",
-	.ops		= &clkops_omap2_dflt,
-	.parent		= &dpll4_m4x2_ck,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430_EN_DSS1_SHIFT,
-	.clkdm_name	= "dss_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk dss1_alwon_fck_3430es2 = {
-	.name		= "dss1_alwon_fck",
-	.ops		= &clkops_omap3430es2_dss_usbhost_wait,
-	.parent		= &dpll4_m4x2_ck,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430_EN_DSS1_SHIFT,
-	.clkdm_name	= "dss_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk dss_tv_fck = {
-	.name		= "dss_tv_fck",
-	.ops		= &clkops_omap2_dflt,
-	.parent		= &omap_54m_fck,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430_EN_TV_SHIFT,
-	.clkdm_name	= "dss_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk dss_96m_fck = {
-	.name		= "dss_96m_fck",
-	.ops		= &clkops_omap2_dflt,
-	.parent		= &omap_96m_fck,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430_EN_TV_SHIFT,
-	.clkdm_name	= "dss_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk dss2_alwon_fck = {
-	.name		= "dss2_alwon_fck",
-	.ops		= &clkops_omap2_dflt,
-	.parent		= &sys_ck,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430_EN_DSS2_SHIFT,
-	.clkdm_name	= "dss_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk dss_ick_3430es1 = {
-	/* Handles both L3 and L4 clocks */
-	.name		= "dss_ick",
-	.ops		= &clkops_omap2_iclk_dflt,
-	.parent		= &l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430_CM_ICLKEN_DSS_EN_DSS_SHIFT,
-	.clkdm_name	= "dss_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk dss_ick_3430es2 = {
-	/* Handles both L3 and L4 clocks */
-	.name		= "dss_ick",
-	.ops		= &clkops_omap3430es2_iclk_dss_usbhost_wait,
-	.parent		= &l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430_CM_ICLKEN_DSS_EN_DSS_SHIFT,
-	.clkdm_name	= "dss_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-/* CAM */
-
-static struct clk cam_mclk = {
-	.name		= "cam_mclk",
-	.ops		= &clkops_omap2_dflt,
-	.parent		= &dpll4_m5x2_ck,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_CAM_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430_EN_CAM_SHIFT,
-	.clkdm_name	= "cam_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk cam_ick = {
-	/* Handles both L3 and L4 clocks */
-	.name		= "cam_ick",
-	.ops		= &clkops_omap2_iclk_dflt,
-	.parent		= &l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_CAM_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430_EN_CAM_SHIFT,
-	.clkdm_name	= "cam_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk csi2_96m_fck = {
-	.name		= "csi2_96m_fck",
-	.ops		= &clkops_omap2_dflt,
-	.parent		= &core_96m_fck,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_CAM_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430_EN_CSI2_SHIFT,
-	.clkdm_name	= "cam_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-/* USBHOST - 3430ES2 only */
-
-static struct clk usbhost_120m_fck = {
-	.name		= "usbhost_120m_fck",
-	.ops		= &clkops_omap2_dflt,
-	.parent		= &dpll5_m2_ck,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430ES2_USBHOST_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430ES2_EN_USBHOST2_SHIFT,
-	.clkdm_name	= "usbhost_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk usbhost_48m_fck = {
-	.name		= "usbhost_48m_fck",
-	.ops		= &clkops_omap3430es2_dss_usbhost_wait,
-	.parent		= &omap_48m_fck,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430ES2_USBHOST_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430ES2_EN_USBHOST1_SHIFT,
-	.clkdm_name	= "usbhost_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk usbhost_ick = {
-	/* Handles both L3 and L4 clocks */
-	.name		= "usbhost_ick",
-	.ops		= &clkops_omap3430es2_iclk_dss_usbhost_wait,
-	.parent		= &l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430ES2_USBHOST_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430ES2_EN_USBHOST_SHIFT,
-	.clkdm_name	= "usbhost_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-/* WKUP */
-
-static const struct clksel_rate usim_96m_rates[] = {
-	{ .div = 2,  .val = 3, .flags = RATE_IN_3XXX },
-	{ .div = 4,  .val = 4, .flags = RATE_IN_3XXX },
-	{ .div = 8,  .val = 5, .flags = RATE_IN_3XXX },
-	{ .div = 10, .val = 6, .flags = RATE_IN_3XXX },
-	{ .div = 0 },
-};
-
-static const struct clksel_rate usim_120m_rates[] = {
-	{ .div = 4,  .val = 7,	.flags = RATE_IN_3XXX },
-	{ .div = 8,  .val = 8,	.flags = RATE_IN_3XXX },
-	{ .div = 16, .val = 9,	.flags = RATE_IN_3XXX },
-	{ .div = 20, .val = 10, .flags = RATE_IN_3XXX },
-	{ .div = 0 },
-};
-
-static const struct clksel usim_clksel[] = {
-	{ .parent = &omap_96m_fck,	.rates = usim_96m_rates },
-	{ .parent = &dpll5_m2_ck,	.rates = usim_120m_rates },
-	{ .parent = &sys_ck,		.rates = div2_rates },
-	{ .parent = NULL },
-};
-
-/* 3430ES2 only */
-static struct clk usim_fck = {
-	.name		= "usim_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.init		= &omap2_init_clksel_parent,
-	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430ES2_EN_USIMOCP_SHIFT,
-	.clksel_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_CLKSEL),
-	.clksel_mask	= OMAP3430ES2_CLKSEL_USIMOCP_MASK,
-	.clksel		= usim_clksel,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-/* XXX should gpt1's clksel have wkup_32k_fck as the 32k opt? */
-static struct clk gpt1_fck = {
-	.name		= "gpt1_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.init		= &omap2_init_clksel_parent,
-	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430_EN_GPT1_SHIFT,
-	.clksel_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_CLKSEL),
-	.clksel_mask	= OMAP3430_CLKSEL_GPT1_MASK,
-	.clksel		= omap343x_gpt_clksel,
-	.clkdm_name	= "wkup_clkdm",
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk wkup_32k_fck = {
-	.name		= "wkup_32k_fck",
-	.ops		= &clkops_null,
-	.parent		= &omap_32k_fck,
-	.clkdm_name	= "wkup_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpio1_dbck = {
-	.name		= "gpio1_dbck",
-	.ops		= &clkops_omap2_dflt,
-	.parent		= &wkup_32k_fck,
-	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430_EN_GPIO1_SHIFT,
-	.clkdm_name	= "wkup_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk wdt2_fck = {
-	.name		= "wdt2_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &wkup_32k_fck,
-	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430_EN_WDT2_SHIFT,
-	.clkdm_name	= "wkup_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk wkup_l4_ick = {
-	.name		= "wkup_l4_ick",
-	.ops		= &clkops_null,
-	.parent		= &sys_ck,
-	.clkdm_name	= "wkup_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-/* 3430ES2 only */
-/* Never specifically named in the TRM, so we have to infer a likely name */
-static struct clk usim_ick = {
-	.name		= "usim_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &wkup_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430ES2_EN_USIMOCP_SHIFT,
-	.clkdm_name	= "wkup_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk wdt2_ick = {
-	.name		= "wdt2_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &wkup_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430_EN_WDT2_SHIFT,
-	.clkdm_name	= "wkup_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk wdt1_ick = {
-	.name		= "wdt1_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &wkup_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430_EN_WDT1_SHIFT,
-	.clkdm_name	= "wkup_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpio1_ick = {
-	.name		= "gpio1_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &wkup_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430_EN_GPIO1_SHIFT,
-	.clkdm_name	= "wkup_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk omap_32ksync_ick = {
-	.name		= "omap_32ksync_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &wkup_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430_EN_32KSYNC_SHIFT,
-	.clkdm_name	= "wkup_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-/* XXX This clock no longer exists in 3430 TRM rev F */
-static struct clk gpt12_ick = {
-	.name		= "gpt12_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &wkup_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430_EN_GPT12_SHIFT,
-	.clkdm_name	= "wkup_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpt1_ick = {
-	.name		= "gpt1_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &wkup_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430_EN_GPT1_SHIFT,
-	.clkdm_name	= "wkup_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-
-
-/* PER clock domain */
-
-static struct clk per_96m_fck = {
-	.name		= "per_96m_fck",
-	.ops		= &clkops_null,
-	.parent		= &omap_96m_alwon_fck,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk per_48m_fck = {
-	.name		= "per_48m_fck",
-	.ops		= &clkops_null,
-	.parent		= &omap_48m_fck,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk uart3_fck = {
-	.name		= "uart3_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &per_48m_fck,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430_EN_UART3_SHIFT,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk uart4_fck = {
-	.name		= "uart4_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &per_48m_fck,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3630_EN_UART4_SHIFT,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk uart4_fck_am35xx = {
-	.name		= "uart4_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &core_48m_fck,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
-	.enable_bit	= AM35XX_EN_UART4_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpt2_fck = {
-	.name		= "gpt2_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.init		= &omap2_init_clksel_parent,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430_EN_GPT2_SHIFT,
-	.clksel_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_CLKSEL),
-	.clksel_mask	= OMAP3430_CLKSEL_GPT2_MASK,
-	.clksel		= omap343x_gpt_clksel,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk gpt3_fck = {
-	.name		= "gpt3_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.init		= &omap2_init_clksel_parent,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430_EN_GPT3_SHIFT,
-	.clksel_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_CLKSEL),
-	.clksel_mask	= OMAP3430_CLKSEL_GPT3_MASK,
-	.clksel		= omap343x_gpt_clksel,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk gpt4_fck = {
-	.name		= "gpt4_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.init		= &omap2_init_clksel_parent,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430_EN_GPT4_SHIFT,
-	.clksel_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_CLKSEL),
-	.clksel_mask	= OMAP3430_CLKSEL_GPT4_MASK,
-	.clksel		= omap343x_gpt_clksel,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk gpt5_fck = {
-	.name		= "gpt5_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.init		= &omap2_init_clksel_parent,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430_EN_GPT5_SHIFT,
-	.clksel_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_CLKSEL),
-	.clksel_mask	= OMAP3430_CLKSEL_GPT5_MASK,
-	.clksel		= omap343x_gpt_clksel,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk gpt6_fck = {
-	.name		= "gpt6_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.init		= &omap2_init_clksel_parent,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430_EN_GPT6_SHIFT,
-	.clksel_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_CLKSEL),
-	.clksel_mask	= OMAP3430_CLKSEL_GPT6_MASK,
-	.clksel		= omap343x_gpt_clksel,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk gpt7_fck = {
-	.name		= "gpt7_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.init		= &omap2_init_clksel_parent,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430_EN_GPT7_SHIFT,
-	.clksel_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_CLKSEL),
-	.clksel_mask	= OMAP3430_CLKSEL_GPT7_MASK,
-	.clksel		= omap343x_gpt_clksel,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk gpt8_fck = {
-	.name		= "gpt8_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.init		= &omap2_init_clksel_parent,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430_EN_GPT8_SHIFT,
-	.clksel_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_CLKSEL),
-	.clksel_mask	= OMAP3430_CLKSEL_GPT8_MASK,
-	.clksel		= omap343x_gpt_clksel,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk gpt9_fck = {
-	.name		= "gpt9_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.init		= &omap2_init_clksel_parent,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430_EN_GPT9_SHIFT,
-	.clksel_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_CLKSEL),
-	.clksel_mask	= OMAP3430_CLKSEL_GPT9_MASK,
-	.clksel		= omap343x_gpt_clksel,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk per_32k_alwon_fck = {
-	.name		= "per_32k_alwon_fck",
-	.ops		= &clkops_null,
-	.parent		= &omap_32k_fck,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpio6_dbck = {
-	.name		= "gpio6_dbck",
-	.ops		= &clkops_omap2_dflt,
-	.parent		= &per_32k_alwon_fck,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430_EN_GPIO6_SHIFT,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpio5_dbck = {
-	.name		= "gpio5_dbck",
-	.ops		= &clkops_omap2_dflt,
-	.parent		= &per_32k_alwon_fck,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430_EN_GPIO5_SHIFT,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpio4_dbck = {
-	.name		= "gpio4_dbck",
-	.ops		= &clkops_omap2_dflt,
-	.parent		= &per_32k_alwon_fck,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430_EN_GPIO4_SHIFT,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpio3_dbck = {
-	.name		= "gpio3_dbck",
-	.ops		= &clkops_omap2_dflt,
-	.parent		= &per_32k_alwon_fck,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430_EN_GPIO3_SHIFT,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpio2_dbck = {
-	.name		= "gpio2_dbck",
-	.ops		= &clkops_omap2_dflt,
-	.parent		= &per_32k_alwon_fck,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430_EN_GPIO2_SHIFT,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk wdt3_fck = {
-	.name		= "wdt3_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &per_32k_alwon_fck,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430_EN_WDT3_SHIFT,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk per_l4_ick = {
-	.name		= "per_l4_ick",
-	.ops		= &clkops_null,
-	.parent		= &l4_ick,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpio6_ick = {
-	.name		= "gpio6_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &per_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430_EN_GPIO6_SHIFT,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpio5_ick = {
-	.name		= "gpio5_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &per_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430_EN_GPIO5_SHIFT,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpio4_ick = {
-	.name		= "gpio4_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &per_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430_EN_GPIO4_SHIFT,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpio3_ick = {
-	.name		= "gpio3_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &per_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430_EN_GPIO3_SHIFT,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpio2_ick = {
-	.name		= "gpio2_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &per_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430_EN_GPIO2_SHIFT,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk wdt3_ick = {
-	.name		= "wdt3_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &per_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430_EN_WDT3_SHIFT,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk uart3_ick = {
-	.name		= "uart3_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &per_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430_EN_UART3_SHIFT,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk uart4_ick = {
-	.name		= "uart4_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &per_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3630_EN_UART4_SHIFT,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpt9_ick = {
-	.name		= "gpt9_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &per_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430_EN_GPT9_SHIFT,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpt8_ick = {
-	.name		= "gpt8_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &per_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430_EN_GPT8_SHIFT,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpt7_ick = {
-	.name		= "gpt7_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &per_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430_EN_GPT7_SHIFT,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpt6_ick = {
-	.name		= "gpt6_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &per_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430_EN_GPT6_SHIFT,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpt5_ick = {
-	.name		= "gpt5_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &per_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430_EN_GPT5_SHIFT,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpt4_ick = {
-	.name		= "gpt4_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &per_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430_EN_GPT4_SHIFT,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpt3_ick = {
-	.name		= "gpt3_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &per_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430_EN_GPT3_SHIFT,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpt2_ick = {
-	.name		= "gpt2_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &per_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430_EN_GPT2_SHIFT,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mcbsp2_ick = {
-	.name		= "mcbsp2_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &per_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430_EN_MCBSP2_SHIFT,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mcbsp3_ick = {
-	.name		= "mcbsp3_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &per_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430_EN_MCBSP3_SHIFT,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mcbsp4_ick = {
-	.name		= "mcbsp4_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &per_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
-	.enable_bit	= OMAP3430_EN_MCBSP4_SHIFT,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static const struct clksel mcbsp_234_clksel[] = {
-	{ .parent = &per_96m_fck,  .rates = common_mcbsp_96m_rates },
-	{ .parent = &mcbsp_clks,   .rates = common_mcbsp_mcbsp_rates },
-	{ .parent = NULL }
-};
-
-static struct clk mcbsp2_fck = {
-	.name		= "mcbsp2_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.init		= &omap2_init_clksel_parent,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430_EN_MCBSP2_SHIFT,
-	.clksel_reg	= OMAP343X_CTRL_REGADDR(OMAP2_CONTROL_DEVCONF0),
-	.clksel_mask	= OMAP2_MCBSP2_CLKS_MASK,
-	.clksel		= mcbsp_234_clksel,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk mcbsp3_fck = {
-	.name		= "mcbsp3_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.init		= &omap2_init_clksel_parent,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430_EN_MCBSP3_SHIFT,
-	.clksel_reg	= OMAP343X_CTRL_REGADDR(OMAP343X_CONTROL_DEVCONF1),
-	.clksel_mask	= OMAP2_MCBSP3_CLKS_MASK,
-	.clksel		= mcbsp_234_clksel,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk mcbsp4_fck = {
-	.name		= "mcbsp4_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.init		= &omap2_init_clksel_parent,
-	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430_EN_MCBSP4_SHIFT,
-	.clksel_reg	= OMAP343X_CTRL_REGADDR(OMAP343X_CONTROL_DEVCONF1),
-	.clksel_mask	= OMAP2_MCBSP4_CLKS_MASK,
-	.clksel		= mcbsp_234_clksel,
-	.clkdm_name	= "per_clkdm",
-	.recalc		= &omap2_clksel_recalc,
-};
-
-/* EMU clocks */
-
-/* More information: ARM Cortex-A8 Technical Reference Manual, sect 10.1 */
-
-static const struct clksel_rate emu_src_sys_rates[] = {
-	{ .div = 1, .val = 0, .flags = RATE_IN_3XXX },
-	{ .div = 0 },
-};
-
-static const struct clksel_rate emu_src_core_rates[] = {
-	{ .div = 1, .val = 1, .flags = RATE_IN_3XXX },
-	{ .div = 0 },
-};
-
-static const struct clksel_rate emu_src_per_rates[] = {
-	{ .div = 1, .val = 2, .flags = RATE_IN_3XXX },
-	{ .div = 0 },
-};
-
-static const struct clksel_rate emu_src_mpu_rates[] = {
-	{ .div = 1, .val = 3, .flags = RATE_IN_3XXX },
-	{ .div = 0 },
-};
-
-static const struct clksel emu_src_clksel[] = {
-	{ .parent = &sys_ck,		.rates = emu_src_sys_rates },
-	{ .parent = &emu_core_alwon_ck, .rates = emu_src_core_rates },
-	{ .parent = &emu_per_alwon_ck,	.rates = emu_src_per_rates },
-	{ .parent = &emu_mpu_alwon_ck,	.rates = emu_src_mpu_rates },
-	{ .parent = NULL },
-};
-
-/*
- * Like the clkout_src clocks, emu_src_clk is a virtual clock, existing only
- * to switch the source of some of the EMU clocks.
- * XXX Are there CLKEN bits for these EMU clks?
- */
-static struct clk emu_src_ck = {
-	.name		= "emu_src_ck",
-	.ops		= &clkops_null,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(OMAP3430_EMU_MOD, CM_CLKSEL1),
-	.clksel_mask	= OMAP3430_MUX_CTRL_MASK,
-	.clksel		= emu_src_clksel,
-	.clkdm_name	= "emu_clkdm",
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static const struct clksel_rate pclk_emu_rates[] = {
-	{ .div = 2, .val = 2, .flags = RATE_IN_3XXX },
-	{ .div = 3, .val = 3, .flags = RATE_IN_3XXX },
-	{ .div = 4, .val = 4, .flags = RATE_IN_3XXX },
-	{ .div = 6, .val = 6, .flags = RATE_IN_3XXX },
-	{ .div = 0 },
-};
-
-static const struct clksel pclk_emu_clksel[] = {
-	{ .parent = &emu_src_ck, .rates = pclk_emu_rates },
-	{ .parent = NULL },
-};
-
-static struct clk pclk_fck = {
-	.name		= "pclk_fck",
-	.ops		= &clkops_null,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(OMAP3430_EMU_MOD, CM_CLKSEL1),
-	.clksel_mask	= OMAP3430_CLKSEL_PCLK_MASK,
-	.clksel		= pclk_emu_clksel,
-	.clkdm_name	= "emu_clkdm",
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static const struct clksel_rate pclkx2_emu_rates[] = {
-	{ .div = 1, .val = 1, .flags = RATE_IN_3XXX },
-	{ .div = 2, .val = 2, .flags = RATE_IN_3XXX },
-	{ .div = 3, .val = 3, .flags = RATE_IN_3XXX },
-	{ .div = 0 },
-};
-
-static const struct clksel pclkx2_emu_clksel[] = {
-	{ .parent = &emu_src_ck, .rates = pclkx2_emu_rates },
-	{ .parent = NULL },
-};
-
-static struct clk pclkx2_fck = {
-	.name		= "pclkx2_fck",
-	.ops		= &clkops_null,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(OMAP3430_EMU_MOD, CM_CLKSEL1),
-	.clksel_mask	= OMAP3430_CLKSEL_PCLKX2_MASK,
-	.clksel		= pclkx2_emu_clksel,
-	.clkdm_name	= "emu_clkdm",
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static const struct clksel atclk_emu_clksel[] = {
-	{ .parent = &emu_src_ck, .rates = div2_rates },
-	{ .parent = NULL },
-};
-
-static struct clk atclk_fck = {
-	.name		= "atclk_fck",
-	.ops		= &clkops_null,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(OMAP3430_EMU_MOD, CM_CLKSEL1),
-	.clksel_mask	= OMAP3430_CLKSEL_ATCLK_MASK,
-	.clksel		= atclk_emu_clksel,
-	.clkdm_name	= "emu_clkdm",
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk traceclk_src_fck = {
-	.name		= "traceclk_src_fck",
-	.ops		= &clkops_null,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(OMAP3430_EMU_MOD, CM_CLKSEL1),
-	.clksel_mask	= OMAP3430_TRACE_MUX_CTRL_MASK,
-	.clksel		= emu_src_clksel,
-	.clkdm_name	= "emu_clkdm",
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static const struct clksel_rate traceclk_rates[] = {
-	{ .div = 1, .val = 1, .flags = RATE_IN_3XXX },
-	{ .div = 2, .val = 2, .flags = RATE_IN_3XXX },
-	{ .div = 4, .val = 4, .flags = RATE_IN_3XXX },
-	{ .div = 0 },
-};
-
-static const struct clksel traceclk_clksel[] = {
-	{ .parent = &traceclk_src_fck, .rates = traceclk_rates },
-	{ .parent = NULL },
-};
-
-static struct clk traceclk_fck = {
-	.name		= "traceclk_fck",
-	.ops		= &clkops_null,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP_CM_REGADDR(OMAP3430_EMU_MOD, CM_CLKSEL1),
-	.clksel_mask	= OMAP3430_CLKSEL_TRACECLK_MASK,
-	.clksel		= traceclk_clksel,
-	.clkdm_name	= "emu_clkdm",
-	.recalc		= &omap2_clksel_recalc,
-};
-
-/* SR clocks */
-
-/* SmartReflex fclk (VDD1) */
-static struct clk sr1_fck = {
-	.name		= "sr1_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &sys_ck,
-	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430_EN_SR1_SHIFT,
-	.clkdm_name	= "wkup_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-/* SmartReflex fclk (VDD2) */
-static struct clk sr2_fck = {
-	.name		= "sr2_fck",
-	.ops		= &clkops_omap2_dflt_wait,
-	.parent		= &sys_ck,
-	.enable_reg	= OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN),
-	.enable_bit	= OMAP3430_EN_SR2_SHIFT,
-	.clkdm_name	= "wkup_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk sr_l4_ick = {
-	.name		= "sr_l4_ick",
-	.ops		= &clkops_null, /* RMK: missing? */
-	.parent		= &l4_ick,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-/* SECURE_32K_FCK clocks */
-
-static struct clk gpt12_fck = {
-	.name		= "gpt12_fck",
-	.ops		= &clkops_null,
-	.parent		= &secure_32k_fck,
-	.clkdm_name	= "wkup_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk wdt1_fck = {
-	.name		= "wdt1_fck",
-	.ops		= &clkops_null,
-	.parent		= &secure_32k_fck,
-	.clkdm_name	= "wkup_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-/* Clocks for AM35XX */
-static struct clk ipss_ick = {
-	.name		= "ipss_ick",
-	.ops		= &clkops_am35xx_ipss_wait,
-	.parent		= &core_l3_ick,
-	.clkdm_name	= "core_l3_clkdm",
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= AM35XX_EN_IPSS_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk emac_ick = {
-	.name		= "emac_ick",
-	.ops		= &clkops_am35xx_ipss_module_wait,
-	.parent		= &ipss_ick,
-	.clkdm_name	= "core_l3_clkdm",
-	.enable_reg	= OMAP343X_CTRL_REGADDR(AM35XX_CONTROL_IPSS_CLK_CTRL),
-	.enable_bit	= AM35XX_CPGMAC_VBUSP_CLK_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk rmii_ck = {
-	.name		= "rmii_ck",
-	.ops		= &clkops_null,
-	.rate		= 50000000,
-};
-
-static struct clk emac_fck = {
-	.name		= "emac_fck",
-	.ops		= &clkops_omap2_dflt,
-	.parent		= &rmii_ck,
-	.enable_reg	= OMAP343X_CTRL_REGADDR(AM35XX_CONTROL_IPSS_CLK_CTRL),
-	.enable_bit	= AM35XX_CPGMAC_FCLK_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk hsotgusb_ick_am35xx = {
-	.name		= "hsotgusb_ick",
-	.ops		= &clkops_am35xx_ipss_module_wait,
-	.parent		= &ipss_ick,
-	.clkdm_name	= "core_l3_clkdm",
-	.enable_reg	= OMAP343X_CTRL_REGADDR(AM35XX_CONTROL_IPSS_CLK_CTRL),
-	.enable_bit	= AM35XX_USBOTG_VBUSP_CLK_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk hsotgusb_fck_am35xx = {
-	.name		= "hsotgusb_fck",
-	.ops		= &clkops_omap2_dflt,
-	.parent		= &sys_ck,
-	.clkdm_name	= "core_l3_clkdm",
-	.enable_reg	= OMAP343X_CTRL_REGADDR(AM35XX_CONTROL_IPSS_CLK_CTRL),
-	.enable_bit	= AM35XX_USBOTG_FCLK_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk hecc_ck = {
-	.name		= "hecc_ck",
-	.ops		= &clkops_am35xx_ipss_module_wait,
-	.parent		= &sys_ck,
-	.clkdm_name	= "core_l3_clkdm",
-	.enable_reg	= OMAP343X_CTRL_REGADDR(AM35XX_CONTROL_IPSS_CLK_CTRL),
-	.enable_bit	= AM35XX_HECC_VBUSP_CLK_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk vpfe_ick = {
-	.name		= "vpfe_ick",
-	.ops		= &clkops_am35xx_ipss_module_wait,
-	.parent		= &ipss_ick,
-	.clkdm_name	= "core_l3_clkdm",
-	.enable_reg	= OMAP343X_CTRL_REGADDR(AM35XX_CONTROL_IPSS_CLK_CTRL),
-	.enable_bit	= AM35XX_VPFE_VBUSP_CLK_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk pclk_ck = {
-	.name		= "pclk_ck",
-	.ops		= &clkops_null,
-	.rate		= 27000000,
-};
-
-static struct clk vpfe_fck = {
-	.name		= "vpfe_fck",
-	.ops		= &clkops_omap2_dflt,
-	.parent		= &pclk_ck,
-	.enable_reg	= OMAP343X_CTRL_REGADDR(AM35XX_CONTROL_IPSS_CLK_CTRL),
-	.enable_bit	= AM35XX_VPFE_FCLK_SHIFT,
-	.recalc		= &followparent_recalc,
-};
-
-/*
- * The UART1/2 functional clock acts as the functional clock for
- * UART4. No separate fclk control available.  XXX Well now we have a
- * uart4_fck that is apparently used as the UART4 functional clock,
- * but it also seems that uart1_fck or uart2_fck are still needed, at
- * least for UART4 softresets to complete.  This really needs
- * clarification.
- */
-static struct clk uart4_ick_am35xx = {
-	.name		= "uart4_ick",
-	.ops		= &clkops_omap2_iclk_dflt_wait,
-	.parent		= &core_l4_ick,
-	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
-	.enable_bit	= AM35XX_EN_UART4_SHIFT,
-	.clkdm_name	= "core_l4_clkdm",
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk dummy_apb_pclk = {
-	.name		= "apb_pclk",
-	.ops		= &clkops_null,
-};
-
-/*
- * clkdev
- */
-
-static struct omap_clk omap3xxx_clks[] = {
-	CLK(NULL,	"apb_pclk",	&dummy_apb_pclk,	CK_3XXX),
-	CLK(NULL,	"omap_32k_fck",	&omap_32k_fck,	CK_3XXX),
-	CLK(NULL,	"virt_12m_ck",	&virt_12m_ck,	CK_3XXX),
-	CLK(NULL,	"virt_13m_ck",	&virt_13m_ck,	CK_3XXX),
-	CLK(NULL,	"virt_16_8m_ck", &virt_16_8m_ck, CK_3430ES2PLUS | CK_AM35XX  | CK_36XX),
-	CLK(NULL,	"virt_19200000_ck", &virt_19200000_ck, CK_3XXX),
-	CLK(NULL,	"virt_26000000_ck",	&virt_26000000_ck,	CK_3XXX),
-	CLK(NULL,	"virt_38_4m_ck", &virt_38_4m_ck, CK_3XXX),
-	CLK(NULL,	"osc_sys_ck",	&osc_sys_ck,	CK_3XXX),
-	CLK("twl",	"fck",		&osc_sys_ck,	CK_3XXX),
-	CLK(NULL,	"sys_ck",	&sys_ck,	CK_3XXX),
-	CLK(NULL,	"sys_altclk",	&sys_altclk,	CK_3XXX),
-	CLK(NULL,	"mcbsp_clks",	&mcbsp_clks,	CK_3XXX),
-	CLK(NULL,	"sys_clkout1",	&sys_clkout1,	CK_3XXX),
-	CLK(NULL,	"dpll1_ck",	&dpll1_ck,	CK_3XXX),
-	CLK(NULL,	"dpll1_x2_ck",	&dpll1_x2_ck,	CK_3XXX),
-	CLK(NULL,	"dpll1_x2m2_ck", &dpll1_x2m2_ck, CK_3XXX),
-	CLK(NULL,	"dpll2_ck",	&dpll2_ck,	CK_34XX | CK_36XX),
-	CLK(NULL,	"dpll2_m2_ck",	&dpll2_m2_ck,	CK_34XX | CK_36XX),
-	CLK(NULL,	"dpll3_ck",	&dpll3_ck,	CK_3XXX),
-	CLK(NULL,	"core_ck",	&core_ck,	CK_3XXX),
-	CLK(NULL,	"dpll3_x2_ck",	&dpll3_x2_ck,	CK_3XXX),
-	CLK(NULL,	"dpll3_m2_ck",	&dpll3_m2_ck,	CK_3XXX),
-	CLK(NULL,	"dpll3_m2x2_ck", &dpll3_m2x2_ck, CK_3XXX),
-	CLK(NULL,	"dpll3_m3_ck",	&dpll3_m3_ck,	CK_3XXX),
-	CLK(NULL,	"dpll3_m3x2_ck", &dpll3_m3x2_ck, CK_3XXX),
-	CLK(NULL,	"emu_core_alwon_ck", &emu_core_alwon_ck, CK_3XXX),
-	CLK("etb",	"emu_core_alwon_ck", &emu_core_alwon_ck, CK_3XXX),
-	CLK(NULL,	"dpll4_ck",	&dpll4_ck,	CK_3XXX),
-	CLK(NULL,	"dpll4_x2_ck",	&dpll4_x2_ck,	CK_3XXX),
-	CLK(NULL,	"omap_192m_alwon_fck", &omap_192m_alwon_fck, CK_36XX),
-	CLK(NULL,	"omap_96m_alwon_fck", &omap_96m_alwon_fck, CK_3XXX),
-	CLK(NULL,	"omap_96m_alwon_fck_3630", &omap_96m_alwon_fck_3630, CK_36XX),
-	CLK(NULL,	"omap_96m_fck",	&omap_96m_fck,	CK_3XXX),
-	CLK(NULL,	"cm_96m_fck",	&cm_96m_fck,	CK_3XXX),
-	CLK(NULL,	"omap_54m_fck",	&omap_54m_fck,	CK_3XXX),
-	CLK(NULL,	"omap_48m_fck",	&omap_48m_fck,	CK_3XXX),
-	CLK(NULL,	"omap_12m_fck",	&omap_12m_fck,	CK_3XXX),
-	CLK(NULL,	"dpll4_m2_ck",	&dpll4_m2_ck,	CK_3XXX),
-	CLK(NULL,	"dpll4_m2x2_ck", &dpll4_m2x2_ck, CK_3XXX),
-	CLK(NULL,	"dpll4_m3_ck",	&dpll4_m3_ck,	CK_3XXX),
-	CLK(NULL,	"dpll4_m3x2_ck", &dpll4_m3x2_ck, CK_3XXX),
-	CLK(NULL,	"dpll4_m4_ck",	&dpll4_m4_ck,	CK_3XXX),
-	CLK(NULL,	"dpll4_m4x2_ck", &dpll4_m4x2_ck, CK_3XXX),
-	CLK(NULL,	"dpll4_m5_ck",	&dpll4_m5_ck,	CK_3XXX),
-	CLK(NULL,	"dpll4_m5x2_ck", &dpll4_m5x2_ck, CK_3XXX),
-	CLK(NULL,	"dpll4_m6_ck",	&dpll4_m6_ck,	CK_3XXX),
-	CLK(NULL,	"dpll4_m6x2_ck", &dpll4_m6x2_ck, CK_3XXX),
-	CLK(NULL,	"emu_per_alwon_ck", &emu_per_alwon_ck, CK_3XXX),
-	CLK("etb",	"emu_per_alwon_ck", &emu_per_alwon_ck, CK_3XXX),
-	CLK(NULL,	"dpll5_ck",	&dpll5_ck,	CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
-	CLK(NULL,	"dpll5_m2_ck",	&dpll5_m2_ck,	CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
-	CLK(NULL,	"clkout2_src_ck", &clkout2_src_ck, CK_3XXX),
-	CLK(NULL,	"sys_clkout2",	&sys_clkout2,	CK_3XXX),
-	CLK(NULL,	"corex2_fck",	&corex2_fck,	CK_3XXX),
-	CLK(NULL,	"dpll1_fck",	&dpll1_fck,	CK_3XXX),
-	CLK(NULL,	"mpu_ck",	&mpu_ck,	CK_3XXX),
-	CLK(NULL,	"arm_fck",	&arm_fck,	CK_3XXX),
-	CLK(NULL,	"emu_mpu_alwon_ck", &emu_mpu_alwon_ck, CK_3XXX),
-	CLK("etb",	"emu_mpu_alwon_ck", &emu_mpu_alwon_ck, CK_3XXX),
-	CLK(NULL,	"dpll2_fck",	&dpll2_fck,	CK_34XX | CK_36XX),
-	CLK(NULL,	"iva2_ck",	&iva2_ck,	CK_34XX | CK_36XX),
-	CLK(NULL,	"l3_ick",	&l3_ick,	CK_3XXX),
-	CLK(NULL,	"l4_ick",	&l4_ick,	CK_3XXX),
-	CLK(NULL,	"rm_ick",	&rm_ick,	CK_3XXX),
-	CLK(NULL,	"gfx_l3_ck",	&gfx_l3_ck,	CK_3430ES1),
-	CLK(NULL,	"gfx_l3_fck",	&gfx_l3_fck,	CK_3430ES1),
-	CLK(NULL,	"gfx_l3_ick",	&gfx_l3_ick,	CK_3430ES1),
-	CLK(NULL,	"gfx_cg1_ck",	&gfx_cg1_ck,	CK_3430ES1),
-	CLK(NULL,	"gfx_cg2_ck",	&gfx_cg2_ck,	CK_3430ES1),
-	CLK(NULL,	"sgx_fck",	&sgx_fck,	CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
-	CLK(NULL,	"sgx_ick",	&sgx_ick,	CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
-	CLK(NULL,	"d2d_26m_fck",	&d2d_26m_fck,	CK_3430ES1),
-	CLK(NULL,	"modem_fck",	&modem_fck,	CK_34XX | CK_36XX),
-	CLK(NULL,	"sad2d_ick",	&sad2d_ick,	CK_34XX | CK_36XX),
-	CLK(NULL,	"mad2d_ick",	&mad2d_ick,	CK_34XX | CK_36XX),
-	CLK(NULL,	"gpt10_fck",	&gpt10_fck,	CK_3XXX),
-	CLK(NULL,	"gpt11_fck",	&gpt11_fck,	CK_3XXX),
-	CLK(NULL,	"cpefuse_fck",	&cpefuse_fck,	CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
-	CLK(NULL,	"ts_fck",	&ts_fck,	CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
-	CLK(NULL,	"usbtll_fck",	&usbtll_fck,	CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
-	CLK("usbhs_omap",	"usbtll_fck",	&usbtll_fck,	CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
-	CLK("usbhs_tll",	"usbtll_fck",	&usbtll_fck,	CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
-	CLK(NULL,	"core_96m_fck",	&core_96m_fck,	CK_3XXX),
-	CLK(NULL,	"mmchs3_fck",	&mmchs3_fck,	CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
-	CLK(NULL,	"mmchs2_fck",	&mmchs2_fck,	CK_3XXX),
-	CLK(NULL,	"mspro_fck",	&mspro_fck,	CK_34XX | CK_36XX),
-	CLK(NULL,	"mmchs1_fck",	&mmchs1_fck,	CK_3XXX),
-	CLK(NULL,	"i2c3_fck",	&i2c3_fck,	CK_3XXX),
-	CLK(NULL,	"i2c2_fck",	&i2c2_fck,	CK_3XXX),
-	CLK(NULL,	"i2c1_fck",	&i2c1_fck,	CK_3XXX),
-	CLK(NULL,	"mcbsp5_fck",	&mcbsp5_fck,	CK_3XXX),
-	CLK(NULL,	"mcbsp1_fck",	&mcbsp1_fck,	CK_3XXX),
-	CLK(NULL,	"core_48m_fck",	&core_48m_fck,	CK_3XXX),
-	CLK(NULL,	"mcspi4_fck",	&mcspi4_fck,	CK_3XXX),
-	CLK(NULL,	"mcspi3_fck",	&mcspi3_fck,	CK_3XXX),
-	CLK(NULL,	"mcspi2_fck",	&mcspi2_fck,	CK_3XXX),
-	CLK(NULL,	"mcspi1_fck",	&mcspi1_fck,	CK_3XXX),
-	CLK(NULL,	"uart2_fck",	&uart2_fck,	CK_3XXX),
-	CLK(NULL,	"uart1_fck",	&uart1_fck,	CK_3XXX),
-	CLK(NULL,	"fshostusb_fck", &fshostusb_fck, CK_3430ES1),
-	CLK(NULL,	"core_12m_fck",	&core_12m_fck,	CK_3XXX),
-	CLK("omap_hdq.0",	"fck",	&hdq_fck,	CK_3XXX),
-	CLK(NULL,	"hdq_fck",	&hdq_fck,	CK_3XXX),
-	CLK(NULL,	"ssi_ssr_fck",	&ssi_ssr_fck_3430es1,	CK_3430ES1),
-	CLK(NULL,	"ssi_ssr_fck",	&ssi_ssr_fck_3430es2,	CK_3430ES2PLUS | CK_36XX),
-	CLK(NULL,	"ssi_sst_fck",	&ssi_sst_fck_3430es1,	CK_3430ES1),
-	CLK(NULL,	"ssi_sst_fck",	&ssi_sst_fck_3430es2,	CK_3430ES2PLUS | CK_36XX),
-	CLK(NULL,	"core_l3_ick",	&core_l3_ick,	CK_3XXX),
-	CLK("musb-omap2430",	"ick",	&hsotgusb_ick_3430es1,	CK_3430ES1),
-	CLK("musb-omap2430",	"ick",	&hsotgusb_ick_3430es2,	CK_3430ES2PLUS | CK_36XX),
-	CLK(NULL,	"hsotgusb_ick",	&hsotgusb_ick_3430es1,	CK_3430ES1),
-	CLK(NULL,	"hsotgusb_ick",	&hsotgusb_ick_3430es2,	CK_3430ES2PLUS | CK_36XX),
-	CLK(NULL,	"sdrc_ick",	&sdrc_ick,	CK_3XXX),
-	CLK(NULL,	"gpmc_fck",	&gpmc_fck,	CK_3XXX),
-	CLK(NULL,	"security_l3_ick", &security_l3_ick, CK_34XX | CK_36XX),
-	CLK(NULL,	"pka_ick",	&pka_ick,	CK_34XX | CK_36XX),
-	CLK(NULL,	"core_l4_ick",	&core_l4_ick,	CK_3XXX),
-	CLK(NULL,	"usbtll_ick",	&usbtll_ick,	CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
-	CLK("usbhs_omap",	"usbtll_ick",	&usbtll_ick,	CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
-	CLK("usbhs_tll",	"usbtll_ick",	&usbtll_ick,	CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
-	CLK("omap_hsmmc.2",	"ick",	&mmchs3_ick,	CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
-	CLK(NULL,	"mmchs3_ick",	&mmchs3_ick,	CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
-	CLK(NULL,	"icr_ick",	&icr_ick,	CK_34XX | CK_36XX),
-	CLK("omap-aes",	"ick",	&aes2_ick,	CK_34XX | CK_36XX),
-	CLK("omap-sham",	"ick",	&sha12_ick,	CK_34XX | CK_36XX),
-	CLK(NULL,	"des2_ick",	&des2_ick,	CK_34XX | CK_36XX),
-	CLK("omap_hsmmc.1",	"ick",	&mmchs2_ick,	CK_3XXX),
-	CLK("omap_hsmmc.0",	"ick",	&mmchs1_ick,	CK_3XXX),
-	CLK(NULL,	"mmchs2_ick",	&mmchs2_ick,	CK_3XXX),
-	CLK(NULL,	"mmchs1_ick",	&mmchs1_ick,	CK_3XXX),
-	CLK(NULL,	"mspro_ick",	&mspro_ick,	CK_34XX | CK_36XX),
-	CLK("omap_hdq.0", "ick",	&hdq_ick,	CK_3XXX),
-	CLK(NULL,	"hdq_ick",	&hdq_ick,	CK_3XXX),
-	CLK("omap2_mcspi.4", "ick",	&mcspi4_ick,	CK_3XXX),
-	CLK("omap2_mcspi.3", "ick",	&mcspi3_ick,	CK_3XXX),
-	CLK("omap2_mcspi.2", "ick",	&mcspi2_ick,	CK_3XXX),
-	CLK("omap2_mcspi.1", "ick",	&mcspi1_ick,	CK_3XXX),
-	CLK(NULL,	"mcspi4_ick",	&mcspi4_ick,	CK_3XXX),
-	CLK(NULL,	"mcspi3_ick",	&mcspi3_ick,	CK_3XXX),
-	CLK(NULL,	"mcspi2_ick",	&mcspi2_ick,	CK_3XXX),
-	CLK(NULL,	"mcspi1_ick",	&mcspi1_ick,	CK_3XXX),
-	CLK("omap_i2c.3", "ick",	&i2c3_ick,	CK_3XXX),
-	CLK("omap_i2c.2", "ick",	&i2c2_ick,	CK_3XXX),
-	CLK("omap_i2c.1", "ick",	&i2c1_ick,	CK_3XXX),
-	CLK(NULL,	"i2c3_ick",	&i2c3_ick,	CK_3XXX),
-	CLK(NULL,	"i2c2_ick",	&i2c2_ick,	CK_3XXX),
-	CLK(NULL,	"i2c1_ick",	&i2c1_ick,	CK_3XXX),
-	CLK(NULL,	"uart2_ick",	&uart2_ick,	CK_3XXX),
-	CLK(NULL,	"uart1_ick",	&uart1_ick,	CK_3XXX),
-	CLK(NULL,	"gpt11_ick",	&gpt11_ick,	CK_3XXX),
-	CLK(NULL,	"gpt10_ick",	&gpt10_ick,	CK_3XXX),
-	CLK("omap-mcbsp.5", "ick",	&mcbsp5_ick,	CK_3XXX),
-	CLK("omap-mcbsp.1", "ick",	&mcbsp1_ick,	CK_3XXX),
-	CLK(NULL,	"mcbsp5_ick",	&mcbsp5_ick,	CK_3XXX),
-	CLK(NULL,	"mcbsp1_ick",	&mcbsp1_ick,	CK_3XXX),
-	CLK(NULL,	"fac_ick",	&fac_ick,	CK_3430ES1),
-	CLK(NULL,	"mailboxes_ick", &mailboxes_ick, CK_34XX | CK_36XX),
-	CLK(NULL,	"omapctrl_ick",	&omapctrl_ick,	CK_3XXX),
-	CLK(NULL,	"ssi_l4_ick",	&ssi_l4_ick,	CK_34XX | CK_36XX),
-	CLK(NULL,	"ssi_ick",	&ssi_ick_3430es1,	CK_3430ES1),
-	CLK(NULL,	"ssi_ick",	&ssi_ick_3430es2,	CK_3430ES2PLUS | CK_36XX),
-	CLK(NULL,	"usb_l4_ick",	&usb_l4_ick,	CK_3430ES1),
-	CLK(NULL,	"security_l4_ick2", &security_l4_ick2, CK_34XX | CK_36XX),
-	CLK(NULL,	"aes1_ick",	&aes1_ick,	CK_34XX | CK_36XX),
-	CLK("omap_rng",	"ick",		&rng_ick,	CK_34XX | CK_36XX),
-	CLK(NULL,	"sha11_ick",	&sha11_ick,	CK_34XX | CK_36XX),
-	CLK(NULL,	"des1_ick",	&des1_ick,	CK_34XX | CK_36XX),
-	CLK(NULL,	"dss1_alwon_fck",		&dss1_alwon_fck_3430es1, CK_3430ES1),
-	CLK(NULL,	"dss1_alwon_fck",		&dss1_alwon_fck_3430es2, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
-	CLK(NULL,	"dss_tv_fck",	&dss_tv_fck,	CK_3XXX),
-	CLK(NULL,	"dss_96m_fck",	&dss_96m_fck,	CK_3XXX),
-	CLK(NULL,	"dss2_alwon_fck",	&dss2_alwon_fck, CK_3XXX),
-	CLK("omapdss_dss",	"ick",		&dss_ick_3430es1,	CK_3430ES1),
-	CLK(NULL,	"dss_ick",		&dss_ick_3430es1,	CK_3430ES1),
-	CLK("omapdss_dss",	"ick",		&dss_ick_3430es2,	CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
-	CLK(NULL,	"dss_ick",		&dss_ick_3430es2,	CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
-	CLK(NULL,	"cam_mclk",	&cam_mclk,	CK_34XX | CK_36XX),
-	CLK(NULL,	"cam_ick",	&cam_ick,	CK_34XX | CK_36XX),
-	CLK(NULL,	"csi2_96m_fck",	&csi2_96m_fck,	CK_34XX | CK_36XX),
-	CLK(NULL,	"usbhost_120m_fck", &usbhost_120m_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
-	CLK(NULL,	"usbhost_48m_fck", &usbhost_48m_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
-	CLK(NULL,	"usbhost_ick",	&usbhost_ick,	CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
-	CLK("usbhs_omap",	"usbhost_ick",	&usbhost_ick,	CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
-	CLK(NULL,	"utmi_p1_gfclk",	&dummy_ck,	CK_3XXX),
-	CLK(NULL,	"utmi_p2_gfclk",	&dummy_ck,	CK_3XXX),
-	CLK(NULL,	"xclk60mhsp1_ck",	&dummy_ck,	CK_3XXX),
-	CLK(NULL,	"xclk60mhsp2_ck",	&dummy_ck,	CK_3XXX),
-	CLK(NULL,	"usb_host_hs_utmi_p1_clk",	&dummy_ck,	CK_3XXX),
-	CLK(NULL,	"usb_host_hs_utmi_p2_clk",	&dummy_ck,	CK_3XXX),
-	CLK("usbhs_omap",	"usb_tll_hs_usb_ch0_clk",	&dummy_ck,	CK_3XXX),
-	CLK("usbhs_omap",	"usb_tll_hs_usb_ch1_clk",	&dummy_ck,	CK_3XXX),
-	CLK("usbhs_tll",	"usb_tll_hs_usb_ch0_clk",	&dummy_ck,	CK_3XXX),
-	CLK("usbhs_tll",	"usb_tll_hs_usb_ch1_clk",	&dummy_ck,	CK_3XXX),
-	CLK(NULL,	"init_60m_fclk",	&dummy_ck,	CK_3XXX),
-	CLK(NULL,	"usim_fck",	&usim_fck,	CK_3430ES2PLUS | CK_36XX),
-	CLK(NULL,	"gpt1_fck",	&gpt1_fck,	CK_3XXX),
-	CLK(NULL,	"wkup_32k_fck",	&wkup_32k_fck,	CK_3XXX),
-	CLK(NULL,	"gpio1_dbck",	&gpio1_dbck,	CK_3XXX),
-	CLK(NULL,	"wdt2_fck",		&wdt2_fck,	CK_3XXX),
-	CLK(NULL,	"wkup_l4_ick",	&wkup_l4_ick,	CK_34XX | CK_36XX),
-	CLK(NULL,	"usim_ick",	&usim_ick,	CK_3430ES2PLUS | CK_36XX),
-	CLK("omap_wdt",	"ick",		&wdt2_ick,	CK_3XXX),
-	CLK(NULL,	"wdt2_ick",	&wdt2_ick,	CK_3XXX),
-	CLK(NULL,	"wdt1_ick",	&wdt1_ick,	CK_3XXX),
-	CLK(NULL,	"gpio1_ick",	&gpio1_ick,	CK_3XXX),
-	CLK(NULL,	"omap_32ksync_ick", &omap_32ksync_ick, CK_3XXX),
-	CLK(NULL,	"gpt12_ick",	&gpt12_ick,	CK_3XXX),
-	CLK(NULL,	"gpt1_ick",	&gpt1_ick,	CK_3XXX),
-	CLK(NULL,	"per_96m_fck",	&per_96m_fck,	CK_3XXX),
-	CLK(NULL,	"per_48m_fck",	&per_48m_fck,	CK_3XXX),
-	CLK(NULL,	"uart3_fck",	&uart3_fck,	CK_3XXX),
-	CLK(NULL,	"uart4_fck",	&uart4_fck,	CK_36XX),
-	CLK(NULL,	"uart4_fck",	&uart4_fck_am35xx, CK_AM35XX),
-	CLK(NULL,	"gpt2_fck",	&gpt2_fck,	CK_3XXX),
-	CLK(NULL,	"gpt3_fck",	&gpt3_fck,	CK_3XXX),
-	CLK(NULL,	"gpt4_fck",	&gpt4_fck,	CK_3XXX),
-	CLK(NULL,	"gpt5_fck",	&gpt5_fck,	CK_3XXX),
-	CLK(NULL,	"gpt6_fck",	&gpt6_fck,	CK_3XXX),
-	CLK(NULL,	"gpt7_fck",	&gpt7_fck,	CK_3XXX),
-	CLK(NULL,	"gpt8_fck",	&gpt8_fck,	CK_3XXX),
-	CLK(NULL,	"gpt9_fck",	&gpt9_fck,	CK_3XXX),
-	CLK(NULL,	"per_32k_alwon_fck", &per_32k_alwon_fck, CK_3XXX),
-	CLK(NULL,	"gpio6_dbck",	&gpio6_dbck,	CK_3XXX),
-	CLK(NULL,	"gpio5_dbck",	&gpio5_dbck,	CK_3XXX),
-	CLK(NULL,	"gpio4_dbck",	&gpio4_dbck,	CK_3XXX),
-	CLK(NULL,	"gpio3_dbck",	&gpio3_dbck,	CK_3XXX),
-	CLK(NULL,	"gpio2_dbck",	&gpio2_dbck,	CK_3XXX),
-	CLK(NULL,	"wdt3_fck",	&wdt3_fck,	CK_3XXX),
-	CLK(NULL,	"per_l4_ick",	&per_l4_ick,	CK_3XXX),
-	CLK(NULL,	"gpio6_ick",	&gpio6_ick,	CK_3XXX),
-	CLK(NULL,	"gpio5_ick",	&gpio5_ick,	CK_3XXX),
-	CLK(NULL,	"gpio4_ick",	&gpio4_ick,	CK_3XXX),
-	CLK(NULL,	"gpio3_ick",	&gpio3_ick,	CK_3XXX),
-	CLK(NULL,	"gpio2_ick",	&gpio2_ick,	CK_3XXX),
-	CLK(NULL,	"wdt3_ick",	&wdt3_ick,	CK_3XXX),
-	CLK(NULL,	"uart3_ick",	&uart3_ick,	CK_3XXX),
-	CLK(NULL,	"uart4_ick",	&uart4_ick,	CK_36XX),
-	CLK(NULL,	"gpt9_ick",	&gpt9_ick,	CK_3XXX),
-	CLK(NULL,	"gpt8_ick",	&gpt8_ick,	CK_3XXX),
-	CLK(NULL,	"gpt7_ick",	&gpt7_ick,	CK_3XXX),
-	CLK(NULL,	"gpt6_ick",	&gpt6_ick,	CK_3XXX),
-	CLK(NULL,	"gpt5_ick",	&gpt5_ick,	CK_3XXX),
-	CLK(NULL,	"gpt4_ick",	&gpt4_ick,	CK_3XXX),
-	CLK(NULL,	"gpt3_ick",	&gpt3_ick,	CK_3XXX),
-	CLK(NULL,	"gpt2_ick",	&gpt2_ick,	CK_3XXX),
-	CLK("omap-mcbsp.2", "ick",	&mcbsp2_ick,	CK_3XXX),
-	CLK("omap-mcbsp.3", "ick",	&mcbsp3_ick,	CK_3XXX),
-	CLK("omap-mcbsp.4", "ick",	&mcbsp4_ick,	CK_3XXX),
-	CLK(NULL,	"mcbsp4_ick",	&mcbsp2_ick,	CK_3XXX),
-	CLK(NULL,	"mcbsp3_ick",	&mcbsp3_ick,	CK_3XXX),
-	CLK(NULL,	"mcbsp2_ick",	&mcbsp4_ick,	CK_3XXX),
-	CLK(NULL,	"mcbsp2_fck",	&mcbsp2_fck,	CK_3XXX),
-	CLK(NULL,	"mcbsp3_fck",	&mcbsp3_fck,	CK_3XXX),
-	CLK(NULL,	"mcbsp4_fck",	&mcbsp4_fck,	CK_3XXX),
-	CLK(NULL,	"emu_src_ck",	&emu_src_ck,	CK_3XXX),
-	CLK("etb",	"emu_src_ck",	&emu_src_ck,	CK_3XXX),
-	CLK(NULL,	"pclk_fck",	&pclk_fck,	CK_3XXX),
-	CLK(NULL,	"pclkx2_fck",	&pclkx2_fck,	CK_3XXX),
-	CLK(NULL,	"atclk_fck",	&atclk_fck,	CK_3XXX),
-	CLK(NULL,	"traceclk_src_fck", &traceclk_src_fck, CK_3XXX),
-	CLK(NULL,	"traceclk_fck",	&traceclk_fck,	CK_3XXX),
-	CLK(NULL,	"sr1_fck",	&sr1_fck,	CK_34XX | CK_36XX),
-	CLK(NULL,	"sr2_fck",	&sr2_fck,	CK_34XX | CK_36XX),
-	CLK(NULL,	"sr_l4_ick",	&sr_l4_ick,	CK_34XX | CK_36XX),
-	CLK(NULL,	"secure_32k_fck", &secure_32k_fck, CK_3XXX),
-	CLK(NULL,	"gpt12_fck",	&gpt12_fck,	CK_3XXX),
-	CLK(NULL,	"wdt1_fck",	&wdt1_fck,	CK_3XXX),
-	CLK(NULL,	"ipss_ick",	&ipss_ick,	CK_AM35XX),
-	CLK(NULL,	"rmii_ck",	&rmii_ck,	CK_AM35XX),
-	CLK(NULL,	"pclk_ck",	&pclk_ck,	CK_AM35XX),
-	CLK(NULL,	"emac_ick",	&emac_ick,	CK_AM35XX),
-	CLK(NULL,	"emac_fck",	&emac_fck,	CK_AM35XX),
-	CLK("davinci_emac.0",	NULL,	&emac_ick,	CK_AM35XX),
-	CLK("davinci_mdio.0",	NULL,	&emac_fck,	CK_AM35XX),
-	CLK(NULL,	"vpfe_ick",	&emac_ick,	CK_AM35XX),
-	CLK(NULL,	"vpfe_fck",	&emac_fck,	CK_AM35XX),
-	CLK("vpfe-capture",	"master",	&vpfe_ick,	CK_AM35XX),
-	CLK("vpfe-capture",	"slave",	&vpfe_fck,	CK_AM35XX),
-	CLK(NULL,	"hsotgusb_ick",		&hsotgusb_ick_am35xx,	CK_AM35XX),
-	CLK(NULL,	"hsotgusb_fck",		&hsotgusb_fck_am35xx,	CK_AM35XX),
-	CLK(NULL,	"hecc_ck",	&hecc_ck,	CK_AM35XX),
-	CLK(NULL,	"uart4_ick",	&uart4_ick_am35xx,	CK_AM35XX),
-	CLK(NULL,	"timer_32k_ck",	&omap_32k_fck,  CK_3XXX),
-	CLK(NULL,	"timer_sys_ck",	&sys_ck,	CK_3XXX),
-	CLK(NULL,	"cpufreq_ck",	&dpll1_ck,	CK_3XXX),
-};
-
-
-int __init omap3xxx_clk_init(void)
-{
-	struct omap_clk *c;
-	u32 cpu_clkflg = 0;
-
-	if (soc_is_am35xx()) {
-		cpu_mask = RATE_IN_34XX;
-		cpu_clkflg = CK_AM35XX;
-	} else if (cpu_is_omap3630()) {
-		cpu_mask = (RATE_IN_34XX | RATE_IN_36XX);
-		cpu_clkflg = CK_36XX;
-	} else if (cpu_is_ti816x()) {
-		cpu_mask = RATE_IN_TI816X;
-		cpu_clkflg = CK_TI816X;
-	} else if (soc_is_am33xx()) {
-		cpu_mask = RATE_IN_AM33XX;
-	} else if (cpu_is_ti814x()) {
-		cpu_mask = RATE_IN_TI814X;
-	} else if (cpu_is_omap34xx()) {
-		if (omap_rev() == OMAP3430_REV_ES1_0) {
-			cpu_mask = RATE_IN_3430ES1;
-			cpu_clkflg = CK_3430ES1;
-		} else {
-			/*
-			 * Assume that anything that we haven't matched yet
-			 * has 3430ES2-type clocks.
-			 */
-			cpu_mask = RATE_IN_3430ES2PLUS;
-			cpu_clkflg = CK_3430ES2PLUS;
-		}
-	} else {
-		WARN(1, "clock: could not identify OMAP3 variant\n");
-	}
-
-	if (omap3_has_192mhz_clk())
-		omap_96m_alwon_fck = omap_96m_alwon_fck_3630;
-
-	if (cpu_is_omap3630()) {
-		/*
-		 * XXX This type of dynamic rewriting of the clock tree is
-		 * deprecated and should be revised soon.
-		 *
-		 * For 3630: override clkops_omap2_dflt_wait for the
-		 * clocks affected from PWRDN reset Limitation
-		 */
-		dpll3_m3x2_ck.ops =
-				&clkops_omap36xx_pwrdn_with_hsdiv_wait_restore;
-		dpll4_m2x2_ck.ops =
-				&clkops_omap36xx_pwrdn_with_hsdiv_wait_restore;
-		dpll4_m3x2_ck.ops =
-				&clkops_omap36xx_pwrdn_with_hsdiv_wait_restore;
-		dpll4_m4x2_ck.ops =
-				&clkops_omap36xx_pwrdn_with_hsdiv_wait_restore;
-		dpll4_m5x2_ck.ops =
-				&clkops_omap36xx_pwrdn_with_hsdiv_wait_restore;
-		dpll4_m6x2_ck.ops =
-				&clkops_omap36xx_pwrdn_with_hsdiv_wait_restore;
-	}
-
-	/*
-	 * XXX This type of dynamic rewriting of the clock tree is
-	 * deprecated and should be revised soon.
-	 */
-	if (cpu_is_omap3630())
-		dpll4_dd = dpll4_dd_3630;
-	else
-		dpll4_dd = dpll4_dd_34xx;
-
-	for (c = omap3xxx_clks; c < omap3xxx_clks + ARRAY_SIZE(omap3xxx_clks);
-	     c++)
-		clk_preinit(c->lk.clk);
-
-	for (c = omap3xxx_clks; c < omap3xxx_clks + ARRAY_SIZE(omap3xxx_clks);
-	     c++)
-		if (c->cpu & cpu_clkflg) {
-			clkdev_add(&c->lk);
-			clk_register(c->lk.clk);
-			omap2_init_clk_clkdm(c->lk.clk);
-		}
-
-	/* Disable autoidle on all clocks; let the PM code enable it later */
-	omap_clk_disable_autoidle_all();
-
-	recalculate_root_clocks();
-
-	pr_info("Clocking rate (Crystal/Core/MPU): %ld.%01ld/%ld/%ld MHz\n",
-		(osc_sys_ck.rate / 1000000), (osc_sys_ck.rate / 100000) % 10,
-		(core_ck.rate / 1000000), (arm_fck.rate / 1000000));
-
-	/*
-	 * Only enable those clocks we will need, let the drivers
-	 * enable other clocks as necessary
-	 */
-	clk_enable_init_clocks();
-
-	/*
-	 * Lock DPLL5 -- here only until other device init code can
-	 * handle this
-	 */
-	if (!cpu_is_ti81xx() && (omap_rev() >= OMAP3430_REV_ES2_0))
-		omap3_clk_lock_dpll5();
-
-	/* Avoid sleeping during omap3_core_dpll_m2_set_rate() */
-	sdrc_ick_p = clk_get(NULL, "sdrc_ick");
-	arm_fck_p = clk_get(NULL, "arm_fck");
-
-	return 0;
-}
diff --git a/arch/arm/mach-omap2/clock44xx_data.c b/arch/arm/mach-omap2/clock44xx_data.c
deleted file mode 100644
index 2a450c9..0000000
--- a/arch/arm/mach-omap2/clock44xx_data.c
+++ /dev/null
@@ -1,3398 +0,0 @@
-/*
- * OMAP4 Clock data
- *
- * Copyright (C) 2009-2010 Texas Instruments, Inc.
- * Copyright (C) 2009-2010 Nokia Corporation
- *
- * Paul Walmsley (paul@pwsan.com)
- * Rajendra Nayak (rnayak@ti.com)
- * Benoit Cousson (b-cousson@ti.com)
- *
- * This file is automatically generated from the OMAP hardware databases.
- * We respectfully ask that any modifications to this file be coordinated
- * with the public linux-omap@vger.kernel.org mailing list and the
- * authors above to ensure that the autogeneration scripts are kept
- * up-to-date with the file contents.
- *
- * 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.
- *
- * XXX Some of the ES1 clocks have been removed/changed; once support
- * is added for discriminating clocks by ES level, these should be added back
- * in.
- */
-
-#include <linux/kernel.h>
-#include <linux/list.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-
-#include "soc.h"
-#include "iomap.h"
-#include "clock.h"
-#include "clock44xx.h"
-#include "cm1_44xx.h"
-#include "cm2_44xx.h"
-#include "cm-regbits-44xx.h"
-#include "prm44xx.h"
-#include "prm-regbits-44xx.h"
-#include "control.h"
-#include "scrm44xx.h"
-
-/* OMAP4 modulemode control */
-#define OMAP4430_MODULEMODE_HWCTRL			0
-#define OMAP4430_MODULEMODE_SWCTRL			1
-
-/* Root clocks */
-
-static struct clk extalt_clkin_ck = {
-	.name		= "extalt_clkin_ck",
-	.rate		= 59000000,
-	.ops		= &clkops_null,
-};
-
-static struct clk pad_clks_ck = {
-	.name		= "pad_clks_ck",
-	.rate		= 12000000,
-	.ops		= &clkops_omap2_dflt,
-	.enable_reg	= OMAP4430_CM_CLKSEL_ABE,
-	.enable_bit	= OMAP4430_PAD_CLKS_GATE_SHIFT,
-};
-
-static struct clk pad_slimbus_core_clks_ck = {
-	.name		= "pad_slimbus_core_clks_ck",
-	.rate		= 12000000,
-	.ops		= &clkops_null,
-};
-
-static struct clk secure_32k_clk_src_ck = {
-	.name		= "secure_32k_clk_src_ck",
-	.rate		= 32768,
-	.ops		= &clkops_null,
-};
-
-static struct clk slimbus_clk = {
-	.name		= "slimbus_clk",
-	.rate		= 12000000,
-	.ops		= &clkops_omap2_dflt,
-	.enable_reg	= OMAP4430_CM_CLKSEL_ABE,
-	.enable_bit	= OMAP4430_SLIMBUS_CLK_GATE_SHIFT,
-};
-
-static struct clk sys_32k_ck = {
-	.name		= "sys_32k_ck",
-	.clkdm_name	= "prm_clkdm",
-	.rate		= 32768,
-	.ops		= &clkops_null,
-};
-
-static struct clk virt_12000000_ck = {
-	.name		= "virt_12000000_ck",
-	.ops		= &clkops_null,
-	.rate		= 12000000,
-};
-
-static struct clk virt_13000000_ck = {
-	.name		= "virt_13000000_ck",
-	.ops		= &clkops_null,
-	.rate		= 13000000,
-};
-
-static struct clk virt_16800000_ck = {
-	.name		= "virt_16800000_ck",
-	.ops		= &clkops_null,
-	.rate		= 16800000,
-};
-
-static struct clk virt_27000000_ck = {
-	.name		= "virt_27000000_ck",
-	.ops		= &clkops_null,
-	.rate		= 27000000,
-};
-
-static struct clk virt_38400000_ck = {
-	.name		= "virt_38400000_ck",
-	.ops		= &clkops_null,
-	.rate		= 38400000,
-};
-
-static const struct clksel_rate div_1_5_rates[] = {
-	{ .div = 1, .val = 5, .flags = RATE_IN_4430 },
-	{ .div = 0 },
-};
-
-static const struct clksel_rate div_1_6_rates[] = {
-	{ .div = 1, .val = 6, .flags = RATE_IN_4430 },
-	{ .div = 0 },
-};
-
-static const struct clksel_rate div_1_7_rates[] = {
-	{ .div = 1, .val = 7, .flags = RATE_IN_4430 },
-	{ .div = 0 },
-};
-
-static const struct clksel sys_clkin_sel[] = {
-	{ .parent = &virt_12000000_ck, .rates = div_1_1_rates },
-	{ .parent = &virt_13000000_ck, .rates = div_1_2_rates },
-	{ .parent = &virt_16800000_ck, .rates = div_1_3_rates },
-	{ .parent = &virt_19200000_ck, .rates = div_1_4_rates },
-	{ .parent = &virt_26000000_ck, .rates = div_1_5_rates },
-	{ .parent = &virt_27000000_ck, .rates = div_1_6_rates },
-	{ .parent = &virt_38400000_ck, .rates = div_1_7_rates },
-	{ .parent = NULL },
-};
-
-static struct clk sys_clkin_ck = {
-	.name		= "sys_clkin_ck",
-	.rate		= 38400000,
-	.clksel		= sys_clkin_sel,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP4430_CM_SYS_CLKSEL,
-	.clksel_mask	= OMAP4430_SYS_CLKSEL_MASK,
-	.ops		= &clkops_null,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk tie_low_clock_ck = {
-	.name		= "tie_low_clock_ck",
-	.rate		= 0,
-	.ops		= &clkops_null,
-};
-
-static struct clk utmi_phy_clkout_ck = {
-	.name		= "utmi_phy_clkout_ck",
-	.rate		= 60000000,
-	.ops		= &clkops_null,
-};
-
-static struct clk xclk60mhsp1_ck = {
-	.name		= "xclk60mhsp1_ck",
-	.rate		= 60000000,
-	.ops		= &clkops_null,
-};
-
-static struct clk xclk60mhsp2_ck = {
-	.name		= "xclk60mhsp2_ck",
-	.rate		= 60000000,
-	.ops		= &clkops_null,
-};
-
-static struct clk xclk60motg_ck = {
-	.name		= "xclk60motg_ck",
-	.rate		= 60000000,
-	.ops		= &clkops_null,
-};
-
-/* Module clocks and DPLL outputs */
-
-static const struct clksel abe_dpll_bypass_clk_mux_sel[] = {
-	{ .parent = &sys_clkin_ck, .rates = div_1_0_rates },
-	{ .parent = &sys_32k_ck, .rates = div_1_1_rates },
-	{ .parent = NULL },
-};
-
-static struct clk abe_dpll_bypass_clk_mux_ck = {
-	.name		= "abe_dpll_bypass_clk_mux_ck",
-	.parent		= &sys_clkin_ck,
-	.ops		= &clkops_null,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk abe_dpll_refclk_mux_ck = {
-	.name		= "abe_dpll_refclk_mux_ck",
-	.parent		= &sys_clkin_ck,
-	.clksel		= abe_dpll_bypass_clk_mux_sel,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP4430_CM_ABE_PLL_REF_CLKSEL,
-	.clksel_mask	= OMAP4430_CLKSEL_0_0_MASK,
-	.ops		= &clkops_null,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-/* DPLL_ABE */
-static struct dpll_data dpll_abe_dd = {
-	.mult_div1_reg	= OMAP4430_CM_CLKSEL_DPLL_ABE,
-	.clk_bypass	= &abe_dpll_bypass_clk_mux_ck,
-	.clk_ref	= &abe_dpll_refclk_mux_ck,
-	.control_reg	= OMAP4430_CM_CLKMODE_DPLL_ABE,
-	.modes		= (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
-	.autoidle_reg	= OMAP4430_CM_AUTOIDLE_DPLL_ABE,
-	.idlest_reg	= OMAP4430_CM_IDLEST_DPLL_ABE,
-	.mult_mask	= OMAP4430_DPLL_MULT_MASK,
-	.div1_mask	= OMAP4430_DPLL_DIV_MASK,
-	.enable_mask	= OMAP4430_DPLL_EN_MASK,
-	.autoidle_mask	= OMAP4430_AUTO_DPLL_MODE_MASK,
-	.idlest_mask	= OMAP4430_ST_DPLL_CLK_MASK,
-	.max_multiplier	= 2047,
-	.max_divider	= 128,
-	.min_divider	= 1,
-};
-
-
-static struct clk dpll_abe_ck = {
-	.name		= "dpll_abe_ck",
-	.parent		= &abe_dpll_refclk_mux_ck,
-	.dpll_data	= &dpll_abe_dd,
-	.init		= &omap2_init_dpll_parent,
-	.ops		= &clkops_omap3_noncore_dpll_ops,
-	.recalc		= &omap4_dpll_regm4xen_recalc,
-	.round_rate	= &omap4_dpll_regm4xen_round_rate,
-	.set_rate	= &omap3_noncore_dpll_set_rate,
-};
-
-static struct clk dpll_abe_x2_ck = {
-	.name		= "dpll_abe_x2_ck",
-	.parent		= &dpll_abe_ck,
-	.clksel_reg	= OMAP4430_CM_DIV_M2_DPLL_ABE,
-	.flags		= CLOCK_CLKOUTX2,
-	.ops		= &clkops_omap4_dpllmx_ops,
-	.recalc		= &omap3_clkoutx2_recalc,
-};
-
-static const struct clksel dpll_abe_m2x2_div[] = {
-	{ .parent = &dpll_abe_x2_ck, .rates = div31_1to31_rates },
-	{ .parent = NULL },
-};
-
-static struct clk dpll_abe_m2x2_ck = {
-	.name		= "dpll_abe_m2x2_ck",
-	.parent		= &dpll_abe_x2_ck,
-	.clksel		= dpll_abe_m2x2_div,
-	.clksel_reg	= OMAP4430_CM_DIV_M2_DPLL_ABE,
-	.clksel_mask	= OMAP4430_DPLL_CLKOUT_DIV_MASK,
-	.ops		= &clkops_omap4_dpllmx_ops,
-	.recalc		= &omap2_clksel_recalc,
-	.round_rate	= &omap2_clksel_round_rate,
-	.set_rate	= &omap2_clksel_set_rate,
-};
-
-static struct clk abe_24m_fclk = {
-	.name		= "abe_24m_fclk",
-	.parent		= &dpll_abe_m2x2_ck,
-	.ops		= &clkops_null,
-	.fixed_div	= 8,
-	.recalc		= &omap_fixed_divisor_recalc,
-};
-
-static const struct clksel_rate div3_1to4_rates[] = {
-	{ .div = 1, .val = 0, .flags = RATE_IN_4430 },
-	{ .div = 2, .val = 1, .flags = RATE_IN_4430 },
-	{ .div = 4, .val = 2, .flags = RATE_IN_4430 },
-	{ .div = 0 },
-};
-
-static const struct clksel abe_clk_div[] = {
-	{ .parent = &dpll_abe_m2x2_ck, .rates = div3_1to4_rates },
-	{ .parent = NULL },
-};
-
-static struct clk abe_clk = {
-	.name		= "abe_clk",
-	.parent		= &dpll_abe_m2x2_ck,
-	.clksel		= abe_clk_div,
-	.clksel_reg	= OMAP4430_CM_CLKSEL_ABE,
-	.clksel_mask	= OMAP4430_CLKSEL_OPP_MASK,
-	.ops		= &clkops_null,
-	.recalc		= &omap2_clksel_recalc,
-	.round_rate	= &omap2_clksel_round_rate,
-	.set_rate	= &omap2_clksel_set_rate,
-};
-
-static const struct clksel_rate div2_1to2_rates[] = {
-	{ .div = 1, .val = 0, .flags = RATE_IN_4430 },
-	{ .div = 2, .val = 1, .flags = RATE_IN_4430 },
-	{ .div = 0 },
-};
-
-static const struct clksel aess_fclk_div[] = {
-	{ .parent = &abe_clk, .rates = div2_1to2_rates },
-	{ .parent = NULL },
-};
-
-static struct clk aess_fclk = {
-	.name		= "aess_fclk",
-	.parent		= &abe_clk,
-	.clksel		= aess_fclk_div,
-	.clksel_reg	= OMAP4430_CM1_ABE_AESS_CLKCTRL,
-	.clksel_mask	= OMAP4430_CLKSEL_AESS_FCLK_MASK,
-	.ops		= &clkops_null,
-	.recalc		= &omap2_clksel_recalc,
-	.round_rate	= &omap2_clksel_round_rate,
-	.set_rate	= &omap2_clksel_set_rate,
-};
-
-static struct clk dpll_abe_m3x2_ck = {
-	.name		= "dpll_abe_m3x2_ck",
-	.parent		= &dpll_abe_x2_ck,
-	.clksel		= dpll_abe_m2x2_div,
-	.clksel_reg	= OMAP4430_CM_DIV_M3_DPLL_ABE,
-	.clksel_mask	= OMAP4430_DPLL_CLKOUTHIF_DIV_MASK,
-	.ops		= &clkops_omap4_dpllmx_ops,
-	.recalc		= &omap2_clksel_recalc,
-	.round_rate	= &omap2_clksel_round_rate,
-	.set_rate	= &omap2_clksel_set_rate,
-};
-
-static const struct clksel core_hsd_byp_clk_mux_sel[] = {
-	{ .parent = &sys_clkin_ck, .rates = div_1_0_rates },
-	{ .parent = &dpll_abe_m3x2_ck, .rates = div_1_1_rates },
-	{ .parent = NULL },
-};
-
-static struct clk core_hsd_byp_clk_mux_ck = {
-	.name		= "core_hsd_byp_clk_mux_ck",
-	.parent		= &sys_clkin_ck,
-	.clksel		= core_hsd_byp_clk_mux_sel,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP4430_CM_CLKSEL_DPLL_CORE,
-	.clksel_mask	= OMAP4430_DPLL_BYP_CLKSEL_MASK,
-	.ops		= &clkops_null,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-/* DPLL_CORE */
-static struct dpll_data dpll_core_dd = {
-	.mult_div1_reg	= OMAP4430_CM_CLKSEL_DPLL_CORE,
-	.clk_bypass	= &core_hsd_byp_clk_mux_ck,
-	.clk_ref	= &sys_clkin_ck,
-	.control_reg	= OMAP4430_CM_CLKMODE_DPLL_CORE,
-	.modes		= (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
-	.autoidle_reg	= OMAP4430_CM_AUTOIDLE_DPLL_CORE,
-	.idlest_reg	= OMAP4430_CM_IDLEST_DPLL_CORE,
-	.mult_mask	= OMAP4430_DPLL_MULT_MASK,
-	.div1_mask	= OMAP4430_DPLL_DIV_MASK,
-	.enable_mask	= OMAP4430_DPLL_EN_MASK,
-	.autoidle_mask	= OMAP4430_AUTO_DPLL_MODE_MASK,
-	.idlest_mask	= OMAP4430_ST_DPLL_CLK_MASK,
-	.max_multiplier	= 2047,
-	.max_divider	= 128,
-	.min_divider	= 1,
-};
-
-
-static struct clk dpll_core_ck = {
-	.name		= "dpll_core_ck",
-	.parent		= &sys_clkin_ck,
-	.dpll_data	= &dpll_core_dd,
-	.init		= &omap2_init_dpll_parent,
-	.ops		= &clkops_omap3_core_dpll_ops,
-	.recalc		= &omap3_dpll_recalc,
-};
-
-static struct clk dpll_core_x2_ck = {
-	.name		= "dpll_core_x2_ck",
-	.parent		= &dpll_core_ck,
-	.flags		= CLOCK_CLKOUTX2,
-	.ops		= &clkops_null,
-	.recalc		= &omap3_clkoutx2_recalc,
-};
-
-static const struct clksel dpll_core_m6x2_div[] = {
-	{ .parent = &dpll_core_x2_ck, .rates = div31_1to31_rates },
-	{ .parent = NULL },
-};
-
-static struct clk dpll_core_m6x2_ck = {
-	.name		= "dpll_core_m6x2_ck",
-	.parent		= &dpll_core_x2_ck,
-	.clksel		= dpll_core_m6x2_div,
-	.clksel_reg	= OMAP4430_CM_DIV_M6_DPLL_CORE,
-	.clksel_mask	= OMAP4430_HSDIVIDER_CLKOUT3_DIV_MASK,
-	.ops		= &clkops_omap4_dpllmx_ops,
-	.recalc		= &omap2_clksel_recalc,
-	.round_rate	= &omap2_clksel_round_rate,
-	.set_rate	= &omap2_clksel_set_rate,
-};
-
-static const struct clksel dbgclk_mux_sel[] = {
-	{ .parent = &sys_clkin_ck, .rates = div_1_0_rates },
-	{ .parent = &dpll_core_m6x2_ck, .rates = div_1_1_rates },
-	{ .parent = NULL },
-};
-
-static struct clk dbgclk_mux_ck = {
-	.name		= "dbgclk_mux_ck",
-	.parent		= &sys_clkin_ck,
-	.ops		= &clkops_null,
-	.recalc		= &followparent_recalc,
-};
-
-static const struct clksel dpll_core_m2_div[] = {
-	{ .parent = &dpll_core_ck, .rates = div31_1to31_rates },
-	{ .parent = NULL },
-};
-
-static struct clk dpll_core_m2_ck = {
-	.name		= "dpll_core_m2_ck",
-	.parent		= &dpll_core_ck,
-	.clksel		= dpll_core_m2_div,
-	.clksel_reg	= OMAP4430_CM_DIV_M2_DPLL_CORE,
-	.clksel_mask	= OMAP4430_DPLL_CLKOUT_DIV_MASK,
-	.ops		= &clkops_omap4_dpllmx_ops,
-	.recalc		= &omap2_clksel_recalc,
-	.round_rate	= &omap2_clksel_round_rate,
-	.set_rate	= &omap2_clksel_set_rate,
-};
-
-static struct clk ddrphy_ck = {
-	.name		= "ddrphy_ck",
-	.parent		= &dpll_core_m2_ck,
-	.ops		= &clkops_null,
-	.clkdm_name	= "l3_emif_clkdm",
-	.fixed_div	= 2,
-	.recalc		= &omap_fixed_divisor_recalc,
-};
-
-static struct clk dpll_core_m5x2_ck = {
-	.name		= "dpll_core_m5x2_ck",
-	.parent		= &dpll_core_x2_ck,
-	.clksel		= dpll_core_m6x2_div,
-	.clksel_reg	= OMAP4430_CM_DIV_M5_DPLL_CORE,
-	.clksel_mask	= OMAP4430_HSDIVIDER_CLKOUT2_DIV_MASK,
-	.ops		= &clkops_omap4_dpllmx_ops,
-	.recalc		= &omap2_clksel_recalc,
-	.round_rate	= &omap2_clksel_round_rate,
-	.set_rate	= &omap2_clksel_set_rate,
-};
-
-static const struct clksel div_core_div[] = {
-	{ .parent = &dpll_core_m5x2_ck, .rates = div2_1to2_rates },
-	{ .parent = NULL },
-};
-
-static struct clk div_core_ck = {
-	.name		= "div_core_ck",
-	.parent		= &dpll_core_m5x2_ck,
-	.clksel		= div_core_div,
-	.clksel_reg	= OMAP4430_CM_CLKSEL_CORE,
-	.clksel_mask	= OMAP4430_CLKSEL_CORE_MASK,
-	.ops		= &clkops_null,
-	.recalc		= &omap2_clksel_recalc,
-	.round_rate	= &omap2_clksel_round_rate,
-	.set_rate	= &omap2_clksel_set_rate,
-};
-
-static const struct clksel_rate div4_1to8_rates[] = {
-	{ .div = 1, .val = 0, .flags = RATE_IN_4430 },
-	{ .div = 2, .val = 1, .flags = RATE_IN_4430 },
-	{ .div = 4, .val = 2, .flags = RATE_IN_4430 },
-	{ .div = 8, .val = 3, .flags = RATE_IN_4430 },
-	{ .div = 0 },
-};
-
-static const struct clksel div_iva_hs_clk_div[] = {
-	{ .parent = &dpll_core_m5x2_ck, .rates = div4_1to8_rates },
-	{ .parent = NULL },
-};
-
-static struct clk div_iva_hs_clk = {
-	.name		= "div_iva_hs_clk",
-	.parent		= &dpll_core_m5x2_ck,
-	.clksel		= div_iva_hs_clk_div,
-	.clksel_reg	= OMAP4430_CM_BYPCLK_DPLL_IVA,
-	.clksel_mask	= OMAP4430_CLKSEL_0_1_MASK,
-	.ops		= &clkops_null,
-	.recalc		= &omap2_clksel_recalc,
-	.round_rate	= &omap2_clksel_round_rate,
-	.set_rate	= &omap2_clksel_set_rate,
-};
-
-static struct clk div_mpu_hs_clk = {
-	.name		= "div_mpu_hs_clk",
-	.parent		= &dpll_core_m5x2_ck,
-	.clksel		= div_iva_hs_clk_div,
-	.clksel_reg	= OMAP4430_CM_BYPCLK_DPLL_MPU,
-	.clksel_mask	= OMAP4430_CLKSEL_0_1_MASK,
-	.ops		= &clkops_null,
-	.recalc		= &omap2_clksel_recalc,
-	.round_rate	= &omap2_clksel_round_rate,
-	.set_rate	= &omap2_clksel_set_rate,
-};
-
-static struct clk dpll_core_m4x2_ck = {
-	.name		= "dpll_core_m4x2_ck",
-	.parent		= &dpll_core_x2_ck,
-	.clksel		= dpll_core_m6x2_div,
-	.clksel_reg	= OMAP4430_CM_DIV_M4_DPLL_CORE,
-	.clksel_mask	= OMAP4430_HSDIVIDER_CLKOUT1_DIV_MASK,
-	.ops		= &clkops_omap4_dpllmx_ops,
-	.recalc		= &omap2_clksel_recalc,
-	.round_rate	= &omap2_clksel_round_rate,
-	.set_rate	= &omap2_clksel_set_rate,
-};
-
-static struct clk dll_clk_div_ck = {
-	.name		= "dll_clk_div_ck",
-	.parent		= &dpll_core_m4x2_ck,
-	.ops		= &clkops_null,
-	.fixed_div	= 2,
-	.recalc		= &omap_fixed_divisor_recalc,
-};
-
-static const struct clksel dpll_abe_m2_div[] = {
-	{ .parent = &dpll_abe_ck, .rates = div31_1to31_rates },
-	{ .parent = NULL },
-};
-
-static struct clk dpll_abe_m2_ck = {
-	.name		= "dpll_abe_m2_ck",
-	.parent		= &dpll_abe_ck,
-	.clksel		= dpll_abe_m2_div,
-	.clksel_reg	= OMAP4430_CM_DIV_M2_DPLL_ABE,
-	.clksel_mask	= OMAP4430_DPLL_CLKOUT_DIV_MASK,
-	.ops		= &clkops_omap4_dpllmx_ops,
-	.recalc		= &omap2_clksel_recalc,
-	.round_rate	= &omap2_clksel_round_rate,
-	.set_rate	= &omap2_clksel_set_rate,
-};
-
-static struct clk dpll_core_m3x2_ck = {
-	.name		= "dpll_core_m3x2_ck",
-	.parent		= &dpll_core_x2_ck,
-	.clksel		= dpll_core_m6x2_div,
-	.clksel_reg	= OMAP4430_CM_DIV_M3_DPLL_CORE,
-	.clksel_mask	= OMAP4430_DPLL_CLKOUTHIF_DIV_MASK,
-	.ops		= &clkops_omap2_dflt,
-	.recalc		= &omap2_clksel_recalc,
-	.round_rate	= &omap2_clksel_round_rate,
-	.set_rate	= &omap2_clksel_set_rate,
-	.enable_reg	= OMAP4430_CM_DIV_M3_DPLL_CORE,
-	.enable_bit	= OMAP4430_DPLL_CLKOUTHIF_GATE_CTRL_SHIFT,
-};
-
-static struct clk dpll_core_m7x2_ck = {
-	.name		= "dpll_core_m7x2_ck",
-	.parent		= &dpll_core_x2_ck,
-	.clksel		= dpll_core_m6x2_div,
-	.clksel_reg	= OMAP4430_CM_DIV_M7_DPLL_CORE,
-	.clksel_mask	= OMAP4430_HSDIVIDER_CLKOUT4_DIV_MASK,
-	.ops		= &clkops_omap4_dpllmx_ops,
-	.recalc		= &omap2_clksel_recalc,
-	.round_rate	= &omap2_clksel_round_rate,
-	.set_rate	= &omap2_clksel_set_rate,
-};
-
-static const struct clksel iva_hsd_byp_clk_mux_sel[] = {
-	{ .parent = &sys_clkin_ck, .rates = div_1_0_rates },
-	{ .parent = &div_iva_hs_clk, .rates = div_1_1_rates },
-	{ .parent = NULL },
-};
-
-static struct clk iva_hsd_byp_clk_mux_ck = {
-	.name		= "iva_hsd_byp_clk_mux_ck",
-	.parent		= &sys_clkin_ck,
-	.clksel		= iva_hsd_byp_clk_mux_sel,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP4430_CM_CLKSEL_DPLL_IVA,
-	.clksel_mask	= OMAP4430_DPLL_BYP_CLKSEL_MASK,
-	.ops		= &clkops_null,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-/* DPLL_IVA */
-static struct dpll_data dpll_iva_dd = {
-	.mult_div1_reg	= OMAP4430_CM_CLKSEL_DPLL_IVA,
-	.clk_bypass	= &iva_hsd_byp_clk_mux_ck,
-	.clk_ref	= &sys_clkin_ck,
-	.control_reg	= OMAP4430_CM_CLKMODE_DPLL_IVA,
-	.modes		= (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
-	.autoidle_reg	= OMAP4430_CM_AUTOIDLE_DPLL_IVA,
-	.idlest_reg	= OMAP4430_CM_IDLEST_DPLL_IVA,
-	.mult_mask	= OMAP4430_DPLL_MULT_MASK,
-	.div1_mask	= OMAP4430_DPLL_DIV_MASK,
-	.enable_mask	= OMAP4430_DPLL_EN_MASK,
-	.autoidle_mask	= OMAP4430_AUTO_DPLL_MODE_MASK,
-	.idlest_mask	= OMAP4430_ST_DPLL_CLK_MASK,
-	.max_multiplier	= 2047,
-	.max_divider	= 128,
-	.min_divider	= 1,
-};
-
-
-static struct clk dpll_iva_ck = {
-	.name		= "dpll_iva_ck",
-	.parent		= &sys_clkin_ck,
-	.dpll_data	= &dpll_iva_dd,
-	.init		= &omap2_init_dpll_parent,
-	.ops		= &clkops_omap3_noncore_dpll_ops,
-	.recalc		= &omap3_dpll_recalc,
-	.round_rate	= &omap2_dpll_round_rate,
-	.set_rate	= &omap3_noncore_dpll_set_rate,
-};
-
-static struct clk dpll_iva_x2_ck = {
-	.name		= "dpll_iva_x2_ck",
-	.parent		= &dpll_iva_ck,
-	.flags		= CLOCK_CLKOUTX2,
-	.ops		= &clkops_null,
-	.recalc		= &omap3_clkoutx2_recalc,
-};
-
-static const struct clksel dpll_iva_m4x2_div[] = {
-	{ .parent = &dpll_iva_x2_ck, .rates = div31_1to31_rates },
-	{ .parent = NULL },
-};
-
-static struct clk dpll_iva_m4x2_ck = {
-	.name		= "dpll_iva_m4x2_ck",
-	.parent		= &dpll_iva_x2_ck,
-	.clksel		= dpll_iva_m4x2_div,
-	.clksel_reg	= OMAP4430_CM_DIV_M4_DPLL_IVA,
-	.clksel_mask	= OMAP4430_HSDIVIDER_CLKOUT1_DIV_MASK,
-	.ops		= &clkops_omap4_dpllmx_ops,
-	.recalc		= &omap2_clksel_recalc,
-	.round_rate	= &omap2_clksel_round_rate,
-	.set_rate	= &omap2_clksel_set_rate,
-};
-
-static struct clk dpll_iva_m5x2_ck = {
-	.name		= "dpll_iva_m5x2_ck",
-	.parent		= &dpll_iva_x2_ck,
-	.clksel		= dpll_iva_m4x2_div,
-	.clksel_reg	= OMAP4430_CM_DIV_M5_DPLL_IVA,
-	.clksel_mask	= OMAP4430_HSDIVIDER_CLKOUT2_DIV_MASK,
-	.ops		= &clkops_omap4_dpllmx_ops,
-	.recalc		= &omap2_clksel_recalc,
-	.round_rate	= &omap2_clksel_round_rate,
-	.set_rate	= &omap2_clksel_set_rate,
-};
-
-/* DPLL_MPU */
-static struct dpll_data dpll_mpu_dd = {
-	.mult_div1_reg	= OMAP4430_CM_CLKSEL_DPLL_MPU,
-	.clk_bypass	= &div_mpu_hs_clk,
-	.clk_ref	= &sys_clkin_ck,
-	.control_reg	= OMAP4430_CM_CLKMODE_DPLL_MPU,
-	.modes		= (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
-	.autoidle_reg	= OMAP4430_CM_AUTOIDLE_DPLL_MPU,
-	.idlest_reg	= OMAP4430_CM_IDLEST_DPLL_MPU,
-	.mult_mask	= OMAP4430_DPLL_MULT_MASK,
-	.div1_mask	= OMAP4430_DPLL_DIV_MASK,
-	.enable_mask	= OMAP4430_DPLL_EN_MASK,
-	.autoidle_mask	= OMAP4430_AUTO_DPLL_MODE_MASK,
-	.idlest_mask	= OMAP4430_ST_DPLL_CLK_MASK,
-	.max_multiplier	= 2047,
-	.max_divider	= 128,
-	.min_divider	= 1,
-};
-
-
-static struct clk dpll_mpu_ck = {
-	.name		= "dpll_mpu_ck",
-	.parent		= &sys_clkin_ck,
-	.dpll_data	= &dpll_mpu_dd,
-	.init		= &omap2_init_dpll_parent,
-	.ops		= &clkops_omap3_noncore_dpll_ops,
-	.recalc		= &omap3_dpll_recalc,
-	.round_rate	= &omap2_dpll_round_rate,
-	.set_rate	= &omap3_noncore_dpll_set_rate,
-};
-
-static const struct clksel dpll_mpu_m2_div[] = {
-	{ .parent = &dpll_mpu_ck, .rates = div31_1to31_rates },
-	{ .parent = NULL },
-};
-
-static struct clk dpll_mpu_m2_ck = {
-	.name		= "dpll_mpu_m2_ck",
-	.parent		= &dpll_mpu_ck,
-	.clkdm_name	= "cm_clkdm",
-	.clksel		= dpll_mpu_m2_div,
-	.clksel_reg	= OMAP4430_CM_DIV_M2_DPLL_MPU,
-	.clksel_mask	= OMAP4430_DPLL_CLKOUT_DIV_MASK,
-	.ops		= &clkops_omap4_dpllmx_ops,
-	.recalc		= &omap2_clksel_recalc,
-	.round_rate	= &omap2_clksel_round_rate,
-	.set_rate	= &omap2_clksel_set_rate,
-};
-
-static struct clk per_hs_clk_div_ck = {
-	.name		= "per_hs_clk_div_ck",
-	.parent		= &dpll_abe_m3x2_ck,
-	.ops		= &clkops_null,
-	.fixed_div	= 2,
-	.recalc		= &omap_fixed_divisor_recalc,
-};
-
-static const struct clksel per_hsd_byp_clk_mux_sel[] = {
-	{ .parent = &sys_clkin_ck, .rates = div_1_0_rates },
-	{ .parent = &per_hs_clk_div_ck, .rates = div_1_1_rates },
-	{ .parent = NULL },
-};
-
-static struct clk per_hsd_byp_clk_mux_ck = {
-	.name		= "per_hsd_byp_clk_mux_ck",
-	.parent		= &sys_clkin_ck,
-	.clksel		= per_hsd_byp_clk_mux_sel,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP4430_CM_CLKSEL_DPLL_PER,
-	.clksel_mask	= OMAP4430_DPLL_BYP_CLKSEL_MASK,
-	.ops		= &clkops_null,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-/* DPLL_PER */
-static struct dpll_data dpll_per_dd = {
-	.mult_div1_reg	= OMAP4430_CM_CLKSEL_DPLL_PER,
-	.clk_bypass	= &per_hsd_byp_clk_mux_ck,
-	.clk_ref	= &sys_clkin_ck,
-	.control_reg	= OMAP4430_CM_CLKMODE_DPLL_PER,
-	.modes		= (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
-	.autoidle_reg	= OMAP4430_CM_AUTOIDLE_DPLL_PER,
-	.idlest_reg	= OMAP4430_CM_IDLEST_DPLL_PER,
-	.mult_mask	= OMAP4430_DPLL_MULT_MASK,
-	.div1_mask	= OMAP4430_DPLL_DIV_MASK,
-	.enable_mask	= OMAP4430_DPLL_EN_MASK,
-	.autoidle_mask	= OMAP4430_AUTO_DPLL_MODE_MASK,
-	.idlest_mask	= OMAP4430_ST_DPLL_CLK_MASK,
-	.max_multiplier	= 2047,
-	.max_divider	= 128,
-	.min_divider	= 1,
-};
-
-
-static struct clk dpll_per_ck = {
-	.name		= "dpll_per_ck",
-	.parent		= &sys_clkin_ck,
-	.dpll_data	= &dpll_per_dd,
-	.init		= &omap2_init_dpll_parent,
-	.ops		= &clkops_omap3_noncore_dpll_ops,
-	.recalc		= &omap3_dpll_recalc,
-	.round_rate	= &omap2_dpll_round_rate,
-	.set_rate	= &omap3_noncore_dpll_set_rate,
-};
-
-static const struct clksel dpll_per_m2_div[] = {
-	{ .parent = &dpll_per_ck, .rates = div31_1to31_rates },
-	{ .parent = NULL },
-};
-
-static struct clk dpll_per_m2_ck = {
-	.name		= "dpll_per_m2_ck",
-	.parent		= &dpll_per_ck,
-	.clksel		= dpll_per_m2_div,
-	.clksel_reg	= OMAP4430_CM_DIV_M2_DPLL_PER,
-	.clksel_mask	= OMAP4430_DPLL_CLKOUT_DIV_MASK,
-	.ops		= &clkops_omap4_dpllmx_ops,
-	.recalc		= &omap2_clksel_recalc,
-	.round_rate	= &omap2_clksel_round_rate,
-	.set_rate	= &omap2_clksel_set_rate,
-};
-
-static struct clk dpll_per_x2_ck = {
-	.name		= "dpll_per_x2_ck",
-	.parent		= &dpll_per_ck,
-	.clksel_reg	= OMAP4430_CM_DIV_M2_DPLL_PER,
-	.flags		= CLOCK_CLKOUTX2,
-	.ops		= &clkops_omap4_dpllmx_ops,
-	.recalc		= &omap3_clkoutx2_recalc,
-};
-
-static const struct clksel dpll_per_m2x2_div[] = {
-	{ .parent = &dpll_per_x2_ck, .rates = div31_1to31_rates },
-	{ .parent = NULL },
-};
-
-static struct clk dpll_per_m2x2_ck = {
-	.name		= "dpll_per_m2x2_ck",
-	.parent		= &dpll_per_x2_ck,
-	.clksel		= dpll_per_m2x2_div,
-	.clksel_reg	= OMAP4430_CM_DIV_M2_DPLL_PER,
-	.clksel_mask	= OMAP4430_DPLL_CLKOUT_DIV_MASK,
-	.ops		= &clkops_omap4_dpllmx_ops,
-	.recalc		= &omap2_clksel_recalc,
-	.round_rate	= &omap2_clksel_round_rate,
-	.set_rate	= &omap2_clksel_set_rate,
-};
-
-static struct clk dpll_per_m3x2_ck = {
-	.name		= "dpll_per_m3x2_ck",
-	.parent		= &dpll_per_x2_ck,
-	.clksel		= dpll_per_m2x2_div,
-	.clksel_reg	= OMAP4430_CM_DIV_M3_DPLL_PER,
-	.clksel_mask	= OMAP4430_DPLL_CLKOUTHIF_DIV_MASK,
-	.ops		= &clkops_omap2_dflt,
-	.recalc		= &omap2_clksel_recalc,
-	.round_rate	= &omap2_clksel_round_rate,
-	.set_rate	= &omap2_clksel_set_rate,
-	.enable_reg	= OMAP4430_CM_DIV_M3_DPLL_PER,
-	.enable_bit	= OMAP4430_DPLL_CLKOUTHIF_GATE_CTRL_SHIFT,
-};
-
-static struct clk dpll_per_m4x2_ck = {
-	.name		= "dpll_per_m4x2_ck",
-	.parent		= &dpll_per_x2_ck,
-	.clksel		= dpll_per_m2x2_div,
-	.clksel_reg	= OMAP4430_CM_DIV_M4_DPLL_PER,
-	.clksel_mask	= OMAP4430_HSDIVIDER_CLKOUT1_DIV_MASK,
-	.ops		= &clkops_omap4_dpllmx_ops,
-	.recalc		= &omap2_clksel_recalc,
-	.round_rate	= &omap2_clksel_round_rate,
-	.set_rate	= &omap2_clksel_set_rate,
-};
-
-static struct clk dpll_per_m5x2_ck = {
-	.name		= "dpll_per_m5x2_ck",
-	.parent		= &dpll_per_x2_ck,
-	.clksel		= dpll_per_m2x2_div,
-	.clksel_reg	= OMAP4430_CM_DIV_M5_DPLL_PER,
-	.clksel_mask	= OMAP4430_HSDIVIDER_CLKOUT2_DIV_MASK,
-	.ops		= &clkops_omap4_dpllmx_ops,
-	.recalc		= &omap2_clksel_recalc,
-	.round_rate	= &omap2_clksel_round_rate,
-	.set_rate	= &omap2_clksel_set_rate,
-};
-
-static struct clk dpll_per_m6x2_ck = {
-	.name		= "dpll_per_m6x2_ck",
-	.parent		= &dpll_per_x2_ck,
-	.clksel		= dpll_per_m2x2_div,
-	.clksel_reg	= OMAP4430_CM_DIV_M6_DPLL_PER,
-	.clksel_mask	= OMAP4430_HSDIVIDER_CLKOUT3_DIV_MASK,
-	.ops		= &clkops_omap4_dpllmx_ops,
-	.recalc		= &omap2_clksel_recalc,
-	.round_rate	= &omap2_clksel_round_rate,
-	.set_rate	= &omap2_clksel_set_rate,
-};
-
-static struct clk dpll_per_m7x2_ck = {
-	.name		= "dpll_per_m7x2_ck",
-	.parent		= &dpll_per_x2_ck,
-	.clksel		= dpll_per_m2x2_div,
-	.clksel_reg	= OMAP4430_CM_DIV_M7_DPLL_PER,
-	.clksel_mask	= OMAP4430_HSDIVIDER_CLKOUT4_DIV_MASK,
-	.ops		= &clkops_omap4_dpllmx_ops,
-	.recalc		= &omap2_clksel_recalc,
-	.round_rate	= &omap2_clksel_round_rate,
-	.set_rate	= &omap2_clksel_set_rate,
-};
-
-static struct clk usb_hs_clk_div_ck = {
-	.name		= "usb_hs_clk_div_ck",
-	.parent		= &dpll_abe_m3x2_ck,
-	.ops		= &clkops_null,
-	.fixed_div	= 3,
-	.recalc		= &omap_fixed_divisor_recalc,
-};
-
-/* DPLL_USB */
-static struct dpll_data dpll_usb_dd = {
-	.mult_div1_reg	= OMAP4430_CM_CLKSEL_DPLL_USB,
-	.clk_bypass	= &usb_hs_clk_div_ck,
-	.flags		= DPLL_J_TYPE,
-	.clk_ref	= &sys_clkin_ck,
-	.control_reg	= OMAP4430_CM_CLKMODE_DPLL_USB,
-	.modes		= (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
-	.autoidle_reg	= OMAP4430_CM_AUTOIDLE_DPLL_USB,
-	.idlest_reg	= OMAP4430_CM_IDLEST_DPLL_USB,
-	.mult_mask	= OMAP4430_DPLL_MULT_USB_MASK,
-	.div1_mask	= OMAP4430_DPLL_DIV_0_7_MASK,
-	.enable_mask	= OMAP4430_DPLL_EN_MASK,
-	.autoidle_mask	= OMAP4430_AUTO_DPLL_MODE_MASK,
-	.idlest_mask	= OMAP4430_ST_DPLL_CLK_MASK,
-	.sddiv_mask	= OMAP4430_DPLL_SD_DIV_MASK,
-	.max_multiplier	= 4095,
-	.max_divider	= 256,
-	.min_divider	= 1,
-};
-
-
-static struct clk dpll_usb_ck = {
-	.name		= "dpll_usb_ck",
-	.parent		= &sys_clkin_ck,
-	.dpll_data	= &dpll_usb_dd,
-	.init		= &omap2_init_dpll_parent,
-	.ops		= &clkops_omap3_noncore_dpll_ops,
-	.recalc		= &omap3_dpll_recalc,
-	.round_rate	= &omap2_dpll_round_rate,
-	.set_rate	= &omap3_noncore_dpll_set_rate,
-	.clkdm_name	= "l3_init_clkdm",
-};
-
-static struct clk dpll_usb_clkdcoldo_ck = {
-	.name		= "dpll_usb_clkdcoldo_ck",
-	.parent		= &dpll_usb_ck,
-	.clksel_reg	= OMAP4430_CM_CLKDCOLDO_DPLL_USB,
-	.ops		= &clkops_omap4_dpllmx_ops,
-	.recalc		= &followparent_recalc,
-};
-
-static const struct clksel dpll_usb_m2_div[] = {
-	{ .parent = &dpll_usb_ck, .rates = div31_1to31_rates },
-	{ .parent = NULL },
-};
-
-static struct clk dpll_usb_m2_ck = {
-	.name		= "dpll_usb_m2_ck",
-	.parent		= &dpll_usb_ck,
-	.clksel		= dpll_usb_m2_div,
-	.clksel_reg	= OMAP4430_CM_DIV_M2_DPLL_USB,
-	.clksel_mask	= OMAP4430_DPLL_CLKOUT_DIV_0_6_MASK,
-	.ops		= &clkops_omap4_dpllmx_ops,
-	.recalc		= &omap2_clksel_recalc,
-	.round_rate	= &omap2_clksel_round_rate,
-	.set_rate	= &omap2_clksel_set_rate,
-};
-
-static const struct clksel ducati_clk_mux_sel[] = {
-	{ .parent = &div_core_ck, .rates = div_1_0_rates },
-	{ .parent = &dpll_per_m6x2_ck, .rates = div_1_1_rates },
-	{ .parent = NULL },
-};
-
-static struct clk ducati_clk_mux_ck = {
-	.name		= "ducati_clk_mux_ck",
-	.parent		= &div_core_ck,
-	.clksel		= ducati_clk_mux_sel,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP4430_CM_CLKSEL_DUCATI_ISS_ROOT,
-	.clksel_mask	= OMAP4430_CLKSEL_0_0_MASK,
-	.ops		= &clkops_null,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk func_12m_fclk = {
-	.name		= "func_12m_fclk",
-	.parent		= &dpll_per_m2x2_ck,
-	.ops		= &clkops_null,
-	.fixed_div	= 16,
-	.recalc		= &omap_fixed_divisor_recalc,
-};
-
-static struct clk func_24m_clk = {
-	.name		= "func_24m_clk",
-	.parent		= &dpll_per_m2_ck,
-	.ops		= &clkops_null,
-	.fixed_div	= 4,
-	.recalc		= &omap_fixed_divisor_recalc,
-};
-
-static struct clk func_24mc_fclk = {
-	.name		= "func_24mc_fclk",
-	.parent		= &dpll_per_m2x2_ck,
-	.ops		= &clkops_null,
-	.fixed_div	= 8,
-	.recalc		= &omap_fixed_divisor_recalc,
-};
-
-static const struct clksel_rate div2_4to8_rates[] = {
-	{ .div = 4, .val = 0, .flags = RATE_IN_4430 },
-	{ .div = 8, .val = 1, .flags = RATE_IN_4430 },
-	{ .div = 0 },
-};
-
-static const struct clksel func_48m_fclk_div[] = {
-	{ .parent = &dpll_per_m2x2_ck, .rates = div2_4to8_rates },
-	{ .parent = NULL },
-};
-
-static struct clk func_48m_fclk = {
-	.name		= "func_48m_fclk",
-	.parent		= &dpll_per_m2x2_ck,
-	.clksel		= func_48m_fclk_div,
-	.clksel_reg	= OMAP4430_CM_SCALE_FCLK,
-	.clksel_mask	= OMAP4430_SCALE_FCLK_MASK,
-	.ops		= &clkops_null,
-	.recalc		= &omap2_clksel_recalc,
-	.round_rate	= &omap2_clksel_round_rate,
-	.set_rate	= &omap2_clksel_set_rate,
-};
-
-static struct clk func_48mc_fclk = {
-	.name		= "func_48mc_fclk",
-	.parent		= &dpll_per_m2x2_ck,
-	.ops		= &clkops_null,
-	.fixed_div	= 4,
-	.recalc		= &omap_fixed_divisor_recalc,
-};
-
-static const struct clksel_rate div2_2to4_rates[] = {
-	{ .div = 2, .val = 0, .flags = RATE_IN_4430 },
-	{ .div = 4, .val = 1, .flags = RATE_IN_4430 },
-	{ .div = 0 },
-};
-
-static const struct clksel func_64m_fclk_div[] = {
-	{ .parent = &dpll_per_m4x2_ck, .rates = div2_2to4_rates },
-	{ .parent = NULL },
-};
-
-static struct clk func_64m_fclk = {
-	.name		= "func_64m_fclk",
-	.parent		= &dpll_per_m4x2_ck,
-	.clksel		= func_64m_fclk_div,
-	.clksel_reg	= OMAP4430_CM_SCALE_FCLK,
-	.clksel_mask	= OMAP4430_SCALE_FCLK_MASK,
-	.ops		= &clkops_null,
-	.recalc		= &omap2_clksel_recalc,
-	.round_rate	= &omap2_clksel_round_rate,
-	.set_rate	= &omap2_clksel_set_rate,
-};
-
-static const struct clksel func_96m_fclk_div[] = {
-	{ .parent = &dpll_per_m2x2_ck, .rates = div2_2to4_rates },
-	{ .parent = NULL },
-};
-
-static struct clk func_96m_fclk = {
-	.name		= "func_96m_fclk",
-	.parent		= &dpll_per_m2x2_ck,
-	.clksel		= func_96m_fclk_div,
-	.clksel_reg	= OMAP4430_CM_SCALE_FCLK,
-	.clksel_mask	= OMAP4430_SCALE_FCLK_MASK,
-	.ops		= &clkops_null,
-	.recalc		= &omap2_clksel_recalc,
-	.round_rate	= &omap2_clksel_round_rate,
-	.set_rate	= &omap2_clksel_set_rate,
-};
-
-static const struct clksel_rate div2_1to8_rates[] = {
-	{ .div = 1, .val = 0, .flags = RATE_IN_4430 },
-	{ .div = 8, .val = 1, .flags = RATE_IN_4430 },
-	{ .div = 0 },
-};
-
-static const struct clksel init_60m_fclk_div[] = {
-	{ .parent = &dpll_usb_m2_ck, .rates = div2_1to8_rates },
-	{ .parent = NULL },
-};
-
-static struct clk init_60m_fclk = {
-	.name		= "init_60m_fclk",
-	.parent		= &dpll_usb_m2_ck,
-	.clksel		= init_60m_fclk_div,
-	.clksel_reg	= OMAP4430_CM_CLKSEL_USB_60MHZ,
-	.clksel_mask	= OMAP4430_CLKSEL_0_0_MASK,
-	.ops		= &clkops_null,
-	.recalc		= &omap2_clksel_recalc,
-	.round_rate	= &omap2_clksel_round_rate,
-	.set_rate	= &omap2_clksel_set_rate,
-};
-
-static const struct clksel l3_div_div[] = {
-	{ .parent = &div_core_ck, .rates = div2_1to2_rates },
-	{ .parent = NULL },
-};
-
-static struct clk l3_div_ck = {
-	.name		= "l3_div_ck",
-	.parent		= &div_core_ck,
-	.clkdm_name	= "cm_clkdm",
-	.clksel		= l3_div_div,
-	.clksel_reg	= OMAP4430_CM_CLKSEL_CORE,
-	.clksel_mask	= OMAP4430_CLKSEL_L3_MASK,
-	.ops		= &clkops_null,
-	.recalc		= &omap2_clksel_recalc,
-	.round_rate	= &omap2_clksel_round_rate,
-	.set_rate	= &omap2_clksel_set_rate,
-};
-
-static const struct clksel l4_div_div[] = {
-	{ .parent = &l3_div_ck, .rates = div2_1to2_rates },
-	{ .parent = NULL },
-};
-
-static struct clk l4_div_ck = {
-	.name		= "l4_div_ck",
-	.parent		= &l3_div_ck,
-	.clksel		= l4_div_div,
-	.clksel_reg	= OMAP4430_CM_CLKSEL_CORE,
-	.clksel_mask	= OMAP4430_CLKSEL_L4_MASK,
-	.ops		= &clkops_null,
-	.recalc		= &omap2_clksel_recalc,
-	.round_rate	= &omap2_clksel_round_rate,
-	.set_rate	= &omap2_clksel_set_rate,
-};
-
-static struct clk lp_clk_div_ck = {
-	.name		= "lp_clk_div_ck",
-	.parent		= &dpll_abe_m2x2_ck,
-	.ops		= &clkops_null,
-	.fixed_div	= 16,
-	.recalc		= &omap_fixed_divisor_recalc,
-};
-
-static const struct clksel l4_wkup_clk_mux_sel[] = {
-	{ .parent = &sys_clkin_ck, .rates = div_1_0_rates },
-	{ .parent = &lp_clk_div_ck, .rates = div_1_1_rates },
-	{ .parent = NULL },
-};
-
-static struct clk l4_wkup_clk_mux_ck = {
-	.name		= "l4_wkup_clk_mux_ck",
-	.parent		= &sys_clkin_ck,
-	.clksel		= l4_wkup_clk_mux_sel,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP4430_CM_L4_WKUP_CLKSEL,
-	.clksel_mask	= OMAP4430_CLKSEL_0_0_MASK,
-	.ops		= &clkops_null,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static const struct clksel_rate div2_2to1_rates[] = {
-	{ .div = 1, .val = 1, .flags = RATE_IN_4430 },
-	{ .div = 2, .val = 0, .flags = RATE_IN_4430 },
-	{ .div = 0 },
-};
-
-static const struct clksel ocp_abe_iclk_div[] = {
-	{ .parent = &aess_fclk, .rates = div2_2to1_rates },
-	{ .parent = NULL },
-};
-
-static struct clk mpu_periphclk = {
-	.name		= "mpu_periphclk",
-	.parent		= &dpll_mpu_ck,
-	.ops		= &clkops_null,
-	.fixed_div	= 2,
-	.recalc		= &omap_fixed_divisor_recalc,
-};
-
-static struct clk ocp_abe_iclk = {
-	.name		= "ocp_abe_iclk",
-	.parent		= &aess_fclk,
-	.clksel		= ocp_abe_iclk_div,
-	.clksel_reg	= OMAP4430_CM1_ABE_AESS_CLKCTRL,
-	.clksel_mask	= OMAP4430_CLKSEL_AESS_FCLK_MASK,
-	.ops		= &clkops_null,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk per_abe_24m_fclk = {
-	.name		= "per_abe_24m_fclk",
-	.parent		= &dpll_abe_m2_ck,
-	.ops		= &clkops_null,
-	.fixed_div	= 4,
-	.recalc		= &omap_fixed_divisor_recalc,
-};
-
-static const struct clksel per_abe_nc_fclk_div[] = {
-	{ .parent = &dpll_abe_m2_ck, .rates = div2_1to2_rates },
-	{ .parent = NULL },
-};
-
-static struct clk per_abe_nc_fclk = {
-	.name		= "per_abe_nc_fclk",
-	.parent		= &dpll_abe_m2_ck,
-	.clksel		= per_abe_nc_fclk_div,
-	.clksel_reg	= OMAP4430_CM_SCALE_FCLK,
-	.clksel_mask	= OMAP4430_SCALE_FCLK_MASK,
-	.ops		= &clkops_null,
-	.recalc		= &omap2_clksel_recalc,
-	.round_rate	= &omap2_clksel_round_rate,
-	.set_rate	= &omap2_clksel_set_rate,
-};
-
-static const struct clksel pmd_stm_clock_mux_sel[] = {
-	{ .parent = &sys_clkin_ck, .rates = div_1_0_rates },
-	{ .parent = &dpll_core_m6x2_ck, .rates = div_1_1_rates },
-	{ .parent = &tie_low_clock_ck, .rates = div_1_2_rates },
-	{ .parent = NULL },
-};
-
-static struct clk pmd_stm_clock_mux_ck = {
-	.name		= "pmd_stm_clock_mux_ck",
-	.parent		= &sys_clkin_ck,
-	.ops		= &clkops_null,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk pmd_trace_clk_mux_ck = {
-	.name		= "pmd_trace_clk_mux_ck",
-	.parent		= &sys_clkin_ck,
-	.ops		= &clkops_null,
-	.recalc		= &followparent_recalc,
-};
-
-static const struct clksel syc_clk_div_div[] = {
-	{ .parent = &sys_clkin_ck, .rates = div2_1to2_rates },
-	{ .parent = NULL },
-};
-
-static struct clk syc_clk_div_ck = {
-	.name		= "syc_clk_div_ck",
-	.parent		= &sys_clkin_ck,
-	.clksel		= syc_clk_div_div,
-	.clksel_reg	= OMAP4430_CM_ABE_DSS_SYS_CLKSEL,
-	.clksel_mask	= OMAP4430_CLKSEL_0_0_MASK,
-	.ops		= &clkops_null,
-	.recalc		= &omap2_clksel_recalc,
-	.round_rate	= &omap2_clksel_round_rate,
-	.set_rate	= &omap2_clksel_set_rate,
-};
-
-/* Leaf clocks controlled by modules */
-
-static struct clk aes1_fck = {
-	.name		= "aes1_fck",
-	.ops		= &clkops_omap2_dflt,
-	.enable_reg	= OMAP4430_CM_L4SEC_AES1_CLKCTRL,
-	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
-	.clkdm_name	= "l4_secure_clkdm",
-	.parent		= &l3_div_ck,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk aes2_fck = {
-	.name		= "aes2_fck",
-	.ops		= &clkops_omap2_dflt,
-	.enable_reg	= OMAP4430_CM_L4SEC_AES2_CLKCTRL,
-	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
-	.clkdm_name	= "l4_secure_clkdm",
-	.parent		= &l3_div_ck,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk aess_fck = {
-	.name		= "aess_fck",
-	.ops		= &clkops_omap2_dflt,
-	.enable_reg	= OMAP4430_CM1_ABE_AESS_CLKCTRL,
-	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
-	.clkdm_name	= "abe_clkdm",
-	.parent		= &aess_fclk,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk bandgap_fclk = {
-	.name		= "bandgap_fclk",
-	.ops		= &clkops_omap2_dflt,
-	.enable_reg	= OMAP4430_CM_WKUP_BANDGAP_CLKCTRL,
-	.enable_bit	= OMAP4430_OPTFCLKEN_BGAP_32K_SHIFT,
-	.clkdm_name	= "l4_wkup_clkdm",
-	.parent		= &sys_32k_ck,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk des3des_fck = {
-	.name		= "des3des_fck",
-	.ops		= &clkops_omap2_dflt,
-	.enable_reg	= OMAP4430_CM_L4SEC_DES3DES_CLKCTRL,
-	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
-	.clkdm_name	= "l4_secure_clkdm",
-	.parent		= &l4_div_ck,
-	.recalc		= &followparent_recalc,
-};
-
-static const struct clksel dmic_sync_mux_sel[] = {
-	{ .parent = &abe_24m_fclk, .rates = div_1_0_rates },
-	{ .parent = &syc_clk_div_ck, .rates = div_1_1_rates },
-	{ .parent = &func_24m_clk, .rates = div_1_2_rates },
-	{ .parent = NULL },
-};
-
-static struct clk dmic_sync_mux_ck = {
-	.name		= "dmic_sync_mux_ck",
-	.parent		= &abe_24m_fclk,
-	.clksel		= dmic_sync_mux_sel,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP4430_CM1_ABE_DMIC_CLKCTRL,
-	.clksel_mask	= OMAP4430_CLKSEL_INTERNAL_SOURCE_MASK,
-	.ops		= &clkops_null,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static const struct clksel func_dmic_abe_gfclk_sel[] = {
-	{ .parent = &dmic_sync_mux_ck, .rates = div_1_0_rates },
-	{ .parent = &pad_clks_ck, .rates = div_1_1_rates },
-	{ .parent = &slimbus_clk, .rates = div_1_2_rates },
-	{ .parent = NULL },
-};
-
-/* Merged func_dmic_abe_gfclk into dmic */
-static struct clk dmic_fck = {
-	.name		= "dmic_fck",
-	.parent		= &dmic_sync_mux_ck,
-	.clksel		= func_dmic_abe_gfclk_sel,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP4430_CM1_ABE_DMIC_CLKCTRL,
-	.clksel_mask	= OMAP4430_CLKSEL_SOURCE_MASK,
-	.ops		= &clkops_omap2_dflt,
-	.recalc		= &omap2_clksel_recalc,
-	.enable_reg	= OMAP4430_CM1_ABE_DMIC_CLKCTRL,
-	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
-	.clkdm_name	= "abe_clkdm",
-};
-
-static struct clk dsp_fck = {
-	.name		= "dsp_fck",
-	.ops		= &clkops_omap2_dflt,
-	.enable_reg	= OMAP4430_CM_TESLA_TESLA_CLKCTRL,
-	.enable_bit	= OMAP4430_MODULEMODE_HWCTRL,
-	.clkdm_name	= "tesla_clkdm",
-	.parent		= &dpll_iva_m4x2_ck,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk dss_sys_clk = {
-	.name		= "dss_sys_clk",
-	.ops		= &clkops_omap2_dflt,
-	.enable_reg	= OMAP4430_CM_DSS_DSS_CLKCTRL,
-	.enable_bit	= OMAP4430_OPTFCLKEN_SYS_CLK_SHIFT,
-	.clkdm_name	= "l3_dss_clkdm",
-	.parent		= &syc_clk_div_ck,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk dss_tv_clk = {
-	.name		= "dss_tv_clk",
-	.ops		= &clkops_omap2_dflt,
-	.enable_reg	= OMAP4430_CM_DSS_DSS_CLKCTRL,
-	.enable_bit	= OMAP4430_OPTFCLKEN_TV_CLK_SHIFT,
-	.clkdm_name	= "l3_dss_clkdm",
-	.parent		= &extalt_clkin_ck,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk dss_dss_clk = {
-	.name		= "dss_dss_clk",
-	.ops		= &clkops_omap2_dflt,
-	.enable_reg	= OMAP4430_CM_DSS_DSS_CLKCTRL,
-	.enable_bit	= OMAP4430_OPTFCLKEN_DSSCLK_SHIFT,
-	.clkdm_name	= "l3_dss_clkdm",
-	.parent		= &dpll_per_m5x2_ck,
-	.recalc		= &followparent_recalc,
-};
-
-static const struct clksel_rate div3_8to32_rates[] = {
-	{ .div = 8, .val = 0, .flags = RATE_IN_4460 },
-	{ .div = 16, .val = 1, .flags = RATE_IN_4460 },
-	{ .div = 32, .val = 2, .flags = RATE_IN_4460 },
-	{ .div = 0 },
-};
-
-static const struct clksel div_ts_div[] = {
-	{ .parent = &l4_wkup_clk_mux_ck, .rates = div3_8to32_rates },
-	{ .parent = NULL },
-};
-
-static struct clk div_ts_ck = {
-	.name		= "div_ts_ck",
-	.parent		= &l4_wkup_clk_mux_ck,
-	.clksel		= div_ts_div,
-	.clksel_reg	= OMAP4430_CM_WKUP_BANDGAP_CLKCTRL,
-	.clksel_mask	= OMAP4430_CLKSEL_24_25_MASK,
-	.ops		= &clkops_null,
-	.recalc		= &omap2_clksel_recalc,
-	.round_rate	= &omap2_clksel_round_rate,
-	.set_rate	= &omap2_clksel_set_rate,
-};
-
-static struct clk bandgap_ts_fclk = {
-	.name		= "bandgap_ts_fclk",
-	.ops		= &clkops_omap2_dflt,
-	.enable_reg	= OMAP4430_CM_WKUP_BANDGAP_CLKCTRL,
-	.enable_bit	= OMAP4460_OPTFCLKEN_TS_FCLK_SHIFT,
-	.clkdm_name	= "l4_wkup_clkdm",
-	.parent		= &div_ts_ck,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk dss_48mhz_clk = {
-	.name		= "dss_48mhz_clk",
-	.ops		= &clkops_omap2_dflt,
-	.enable_reg	= OMAP4430_CM_DSS_DSS_CLKCTRL,
-	.enable_bit	= OMAP4430_OPTFCLKEN_48MHZ_CLK_SHIFT,
-	.clkdm_name	= "l3_dss_clkdm",
-	.parent		= &func_48mc_fclk,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk dss_fck = {
-	.name		= "dss_fck",
-	.ops		= &clkops_omap2_dflt,
-	.enable_reg	= OMAP4430_CM_DSS_DSS_CLKCTRL,
-	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
-	.clkdm_name	= "l3_dss_clkdm",
-	.parent		= &l3_div_ck,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk efuse_ctrl_cust_fck = {
-	.name		= "efuse_ctrl_cust_fck",
-	.ops		= &clkops_omap2_dflt,
-	.enable_reg	= OMAP4430_CM_CEFUSE_CEFUSE_CLKCTRL,
-	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
-	.clkdm_name	= "l4_cefuse_clkdm",
-	.parent		= &sys_clkin_ck,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk emif1_fck = {
-	.name		= "emif1_fck",
-	.ops		= &clkops_omap2_dflt,
-	.enable_reg	= OMAP4430_CM_MEMIF_EMIF_1_CLKCTRL,
-	.enable_bit	= OMAP4430_MODULEMODE_HWCTRL,
-	.flags		= ENABLE_ON_INIT,
-	.clkdm_name	= "l3_emif_clkdm",
-	.parent		= &ddrphy_ck,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk emif2_fck = {
-	.name		= "emif2_fck",
-	.ops		= &clkops_omap2_dflt,
-	.enable_reg	= OMAP4430_CM_MEMIF_EMIF_2_CLKCTRL,
-	.enable_bit	= OMAP4430_MODULEMODE_HWCTRL,
-	.flags		= ENABLE_ON_INIT,
-	.clkdm_name	= "l3_emif_clkdm",
-	.parent		= &ddrphy_ck,
-	.recalc		= &followparent_recalc,
-};
-
-static const struct clksel fdif_fclk_div[] = {
-	{ .parent = &dpll_per_m4x2_ck, .rates = div3_1to4_rates },
-	{ .parent = NULL },
-};
-
-/* Merged fdif_fclk into fdif */
-static struct clk fdif_fck = {
-	.name		= "fdif_fck",
-	.parent		= &dpll_per_m4x2_ck,
-	.clksel		= fdif_fclk_div,
-	.clksel_reg	= OMAP4430_CM_CAM_FDIF_CLKCTRL,
-	.clksel_mask	= OMAP4430_CLKSEL_FCLK_MASK,
-	.ops		= &clkops_omap2_dflt,
-	.recalc		= &omap2_clksel_recalc,
-	.round_rate	= &omap2_clksel_round_rate,
-	.set_rate	= &omap2_clksel_set_rate,
-	.enable_reg	= OMAP4430_CM_CAM_FDIF_CLKCTRL,
-	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
-	.clkdm_name	= "iss_clkdm",
-};
-
-static struct clk fpka_fck = {
-	.name		= "fpka_fck",
-	.ops		= &clkops_omap2_dflt,
-	.enable_reg	= OMAP4430_CM_L4SEC_PKAEIP29_CLKCTRL,
-	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
-	.clkdm_name	= "l4_secure_clkdm",
-	.parent		= &l4_div_ck,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpio1_dbclk = {
-	.name		= "gpio1_dbclk",
-	.ops		= &clkops_omap2_dflt,
-	.enable_reg	= OMAP4430_CM_WKUP_GPIO1_CLKCTRL,
-	.enable_bit	= OMAP4430_OPTFCLKEN_DBCLK_SHIFT,
-	.clkdm_name	= "l4_wkup_clkdm",
-	.parent		= &sys_32k_ck,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpio1_ick = {
-	.name		= "gpio1_ick",
-	.ops		= &clkops_omap2_dflt,
-	.enable_reg	= OMAP4430_CM_WKUP_GPIO1_CLKCTRL,
-	.enable_bit	= OMAP4430_MODULEMODE_HWCTRL,
-	.clkdm_name	= "l4_wkup_clkdm",
-	.parent		= &l4_wkup_clk_mux_ck,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpio2_dbclk = {
-	.name		= "gpio2_dbclk",
-	.ops		= &clkops_omap2_dflt,
-	.enable_reg	= OMAP4430_CM_L4PER_GPIO2_CLKCTRL,
-	.enable_bit	= OMAP4430_OPTFCLKEN_DBCLK_SHIFT,
-	.clkdm_name	= "l4_per_clkdm",
-	.parent		= &sys_32k_ck,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpio2_ick = {
-	.name		= "gpio2_ick",
-	.ops		= &clkops_omap2_dflt,
-	.enable_reg	= OMAP4430_CM_L4PER_GPIO2_CLKCTRL,
-	.enable_bit	= OMAP4430_MODULEMODE_HWCTRL,
-	.clkdm_name	= "l4_per_clkdm",
-	.parent		= &l4_div_ck,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpio3_dbclk = {
-	.name		= "gpio3_dbclk",
-	.ops		= &clkops_omap2_dflt,
-	.enable_reg	= OMAP4430_CM_L4PER_GPIO3_CLKCTRL,
-	.enable_bit	= OMAP4430_OPTFCLKEN_DBCLK_SHIFT,
-	.clkdm_name	= "l4_per_clkdm",
-	.parent		= &sys_32k_ck,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpio3_ick = {
-	.name		= "gpio3_ick",
-	.ops		= &clkops_omap2_dflt,
-	.enable_reg	= OMAP4430_CM_L4PER_GPIO3_CLKCTRL,
-	.enable_bit	= OMAP4430_MODULEMODE_HWCTRL,
-	.clkdm_name	= "l4_per_clkdm",
-	.parent		= &l4_div_ck,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpio4_dbclk = {
-	.name		= "gpio4_dbclk",
-	.ops		= &clkops_omap2_dflt,
-	.enable_reg	= OMAP4430_CM_L4PER_GPIO4_CLKCTRL,
-	.enable_bit	= OMAP4430_OPTFCLKEN_DBCLK_SHIFT,
-	.clkdm_name	= "l4_per_clkdm",
-	.parent		= &sys_32k_ck,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpio4_ick = {
-	.name		= "gpio4_ick",
-	.ops		= &clkops_omap2_dflt,
-	.enable_reg	= OMAP4430_CM_L4PER_GPIO4_CLKCTRL,
-	.enable_bit	= OMAP4430_MODULEMODE_HWCTRL,
-	.clkdm_name	= "l4_per_clkdm",
-	.parent		= &l4_div_ck,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpio5_dbclk = {
-	.name		= "gpio5_dbclk",
-	.ops		= &clkops_omap2_dflt,
-	.enable_reg	= OMAP4430_CM_L4PER_GPIO5_CLKCTRL,
-	.enable_bit	= OMAP4430_OPTFCLKEN_DBCLK_SHIFT,
-	.clkdm_name	= "l4_per_clkdm",
-	.parent		= &sys_32k_ck,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpio5_ick = {
-	.name		= "gpio5_ick",
-	.ops		= &clkops_omap2_dflt,
-	.enable_reg	= OMAP4430_CM_L4PER_GPIO5_CLKCTRL,
-	.enable_bit	= OMAP4430_MODULEMODE_HWCTRL,
-	.clkdm_name	= "l4_per_clkdm",
-	.parent		= &l4_div_ck,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpio6_dbclk = {
-	.name		= "gpio6_dbclk",
-	.ops		= &clkops_omap2_dflt,
-	.enable_reg	= OMAP4430_CM_L4PER_GPIO6_CLKCTRL,
-	.enable_bit	= OMAP4430_OPTFCLKEN_DBCLK_SHIFT,
-	.clkdm_name	= "l4_per_clkdm",
-	.parent		= &sys_32k_ck,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpio6_ick = {
-	.name		= "gpio6_ick",
-	.ops		= &clkops_omap2_dflt,
-	.enable_reg	= OMAP4430_CM_L4PER_GPIO6_CLKCTRL,
-	.enable_bit	= OMAP4430_MODULEMODE_HWCTRL,
-	.clkdm_name	= "l4_per_clkdm",
-	.parent		= &l4_div_ck,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk gpmc_ick = {
-	.name		= "gpmc_ick",
-	.ops		= &clkops_omap2_dflt,
-	.enable_reg	= OMAP4430_CM_L3_2_GPMC_CLKCTRL,
-	.enable_bit	= OMAP4430_MODULEMODE_HWCTRL,
-	.flags		= ENABLE_ON_INIT,
-	.clkdm_name	= "l3_2_clkdm",
-	.parent		= &l3_div_ck,
-	.recalc		= &followparent_recalc,
-};
-
-static const struct clksel sgx_clk_mux_sel[] = {
-	{ .parent = &dpll_core_m7x2_ck, .rates = div_1_0_rates },
-	{ .parent = &dpll_per_m7x2_ck, .rates = div_1_1_rates },
-	{ .parent = NULL },
-};
-
-/* Merged sgx_clk_mux into gpu */
-static struct clk gpu_fck = {
-	.name		= "gpu_fck",
-	.parent		= &dpll_core_m7x2_ck,
-	.clksel		= sgx_clk_mux_sel,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP4430_CM_GFX_GFX_CLKCTRL,
-	.clksel_mask	= OMAP4430_CLKSEL_SGX_FCLK_MASK,
-	.ops		= &clkops_omap2_dflt,
-	.recalc		= &omap2_clksel_recalc,
-	.enable_reg	= OMAP4430_CM_GFX_GFX_CLKCTRL,
-	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
-	.clkdm_name	= "l3_gfx_clkdm",
-};
-
-static struct clk hdq1w_fck = {
-	.name		= "hdq1w_fck",
-	.ops		= &clkops_omap2_dflt,
-	.enable_reg	= OMAP4430_CM_L4PER_HDQ1W_CLKCTRL,
-	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
-	.clkdm_name	= "l4_per_clkdm",
-	.parent		= &func_12m_fclk,
-	.recalc		= &followparent_recalc,
-};
-
-static const struct clksel hsi_fclk_div[] = {
-	{ .parent = &dpll_per_m2x2_ck, .rates = div3_1to4_rates },
-	{ .parent = NULL },
-};
-
-/* Merged hsi_fclk into hsi */
-static struct clk hsi_fck = {
-	.name		= "hsi_fck",
-	.parent		= &dpll_per_m2x2_ck,
-	.clksel		= hsi_fclk_div,
-	.clksel_reg	= OMAP4430_CM_L3INIT_HSI_CLKCTRL,
-	.clksel_mask	= OMAP4430_CLKSEL_24_25_MASK,
-	.ops		= &clkops_omap2_dflt,
-	.recalc		= &omap2_clksel_recalc,
-	.round_rate	= &omap2_clksel_round_rate,
-	.set_rate	= &omap2_clksel_set_rate,
-	.enable_reg	= OMAP4430_CM_L3INIT_HSI_CLKCTRL,
-	.enable_bit	= OMAP4430_MODULEMODE_HWCTRL,
-	.clkdm_name	= "l3_init_clkdm",
-};
-
-static struct clk i2c1_fck = {
-	.name		= "i2c1_fck",
-	.ops		= &clkops_omap2_dflt,
-	.enable_reg	= OMAP4430_CM_L4PER_I2C1_CLKCTRL,
-	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
-	.clkdm_name	= "l4_per_clkdm",
-	.parent		= &func_96m_fclk,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk i2c2_fck = {
-	.name		= "i2c2_fck",
-	.ops		= &clkops_omap2_dflt,
-	.enable_reg	= OMAP4430_CM_L4PER_I2C2_CLKCTRL,
-	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
-	.clkdm_name	= "l4_per_clkdm",
-	.parent		= &func_96m_fclk,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk i2c3_fck = {
-	.name		= "i2c3_fck",
-	.ops		= &clkops_omap2_dflt,
-	.enable_reg	= OMAP4430_CM_L4PER_I2C3_CLKCTRL,
-	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
-	.clkdm_name	= "l4_per_clkdm",
-	.parent		= &func_96m_fclk,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk i2c4_fck = {
-	.name		= "i2c4_fck",
-	.ops		= &clkops_omap2_dflt,
-	.enable_reg	= OMAP4430_CM_L4PER_I2C4_CLKCTRL,
-	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
-	.clkdm_name	= "l4_per_clkdm",
-	.parent		= &func_96m_fclk,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk ipu_fck = {
-	.name		= "ipu_fck",
-	.ops		= &clkops_omap2_dflt,
-	.enable_reg	= OMAP4430_CM_DUCATI_DUCATI_CLKCTRL,
-	.enable_bit	= OMAP4430_MODULEMODE_HWCTRL,
-	.clkdm_name	= "ducati_clkdm",
-	.parent		= &ducati_clk_mux_ck,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk iss_ctrlclk = {
-	.name		= "iss_ctrlclk",
-	.ops		= &clkops_omap2_dflt,
-	.enable_reg	= OMAP4430_CM_CAM_ISS_CLKCTRL,
-	.enable_bit	= OMAP4430_OPTFCLKEN_CTRLCLK_SHIFT,
-	.clkdm_name	= "iss_clkdm",
-	.parent		= &func_96m_fclk,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk iss_fck = {
-	.name		= "iss_fck",
-	.ops		= &clkops_omap2_dflt,
-	.enable_reg	= OMAP4430_CM_CAM_ISS_CLKCTRL,
-	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
-	.clkdm_name	= "iss_clkdm",
-	.parent		= &ducati_clk_mux_ck,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk iva_fck = {
-	.name		= "iva_fck",
-	.ops		= &clkops_omap2_dflt,
-	.enable_reg	= OMAP4430_CM_IVAHD_IVAHD_CLKCTRL,
-	.enable_bit	= OMAP4430_MODULEMODE_HWCTRL,
-	.clkdm_name	= "ivahd_clkdm",
-	.parent		= &dpll_iva_m5x2_ck,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk kbd_fck = {
-	.name		= "kbd_fck",
-	.ops		= &clkops_omap2_dflt,
-	.enable_reg	= OMAP4430_CM_WKUP_KEYBOARD_CLKCTRL,
-	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
-	.clkdm_name	= "l4_wkup_clkdm",
-	.parent		= &sys_32k_ck,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk l3_instr_ick = {
-	.name		= "l3_instr_ick",
-	.ops		= &clkops_omap2_dflt,
-	.enable_reg	= OMAP4430_CM_L3INSTR_L3_INSTR_CLKCTRL,
-	.enable_bit	= OMAP4430_MODULEMODE_HWCTRL,
-	.flags		= ENABLE_ON_INIT,
-	.clkdm_name	= "l3_instr_clkdm",
-	.parent		= &l3_div_ck,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk l3_main_3_ick = {
-	.name		= "l3_main_3_ick",
-	.ops		= &clkops_omap2_dflt,
-	.enable_reg	= OMAP4430_CM_L3INSTR_L3_3_CLKCTRL,
-	.enable_bit	= OMAP4430_MODULEMODE_HWCTRL,
-	.flags		= ENABLE_ON_INIT,
-	.clkdm_name	= "l3_instr_clkdm",
-	.parent		= &l3_div_ck,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mcasp_sync_mux_ck = {
-	.name		= "mcasp_sync_mux_ck",
-	.parent		= &abe_24m_fclk,
-	.clksel		= dmic_sync_mux_sel,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP4430_CM1_ABE_MCASP_CLKCTRL,
-	.clksel_mask	= OMAP4430_CLKSEL_INTERNAL_SOURCE_MASK,
-	.ops		= &clkops_null,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static const struct clksel func_mcasp_abe_gfclk_sel[] = {
-	{ .parent = &mcasp_sync_mux_ck, .rates = div_1_0_rates },
-	{ .parent = &pad_clks_ck, .rates = div_1_1_rates },
-	{ .parent = &slimbus_clk, .rates = div_1_2_rates },
-	{ .parent = NULL },
-};
-
-/* Merged func_mcasp_abe_gfclk into mcasp */
-static struct clk mcasp_fck = {
-	.name		= "mcasp_fck",
-	.parent		= &mcasp_sync_mux_ck,
-	.clksel		= func_mcasp_abe_gfclk_sel,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP4430_CM1_ABE_MCASP_CLKCTRL,
-	.clksel_mask	= OMAP4430_CLKSEL_SOURCE_MASK,
-	.ops		= &clkops_omap2_dflt,
-	.recalc		= &omap2_clksel_recalc,
-	.enable_reg	= OMAP4430_CM1_ABE_MCASP_CLKCTRL,
-	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
-	.clkdm_name	= "abe_clkdm",
-};
-
-static struct clk mcbsp1_sync_mux_ck = {
-	.name		= "mcbsp1_sync_mux_ck",
-	.parent		= &abe_24m_fclk,
-	.clksel		= dmic_sync_mux_sel,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP4430_CM1_ABE_MCBSP1_CLKCTRL,
-	.clksel_mask	= OMAP4430_CLKSEL_INTERNAL_SOURCE_MASK,
-	.ops		= &clkops_null,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static const struct clksel func_mcbsp1_gfclk_sel[] = {
-	{ .parent = &mcbsp1_sync_mux_ck, .rates = div_1_0_rates },
-	{ .parent = &pad_clks_ck, .rates = div_1_1_rates },
-	{ .parent = &slimbus_clk, .rates = div_1_2_rates },
-	{ .parent = NULL },
-};
-
-/* Merged func_mcbsp1_gfclk into mcbsp1 */
-static struct clk mcbsp1_fck = {
-	.name		= "mcbsp1_fck",
-	.parent		= &mcbsp1_sync_mux_ck,
-	.clksel		= func_mcbsp1_gfclk_sel,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP4430_CM1_ABE_MCBSP1_CLKCTRL,
-	.clksel_mask	= OMAP4430_CLKSEL_SOURCE_MASK,
-	.ops		= &clkops_omap2_dflt,
-	.recalc		= &omap2_clksel_recalc,
-	.enable_reg	= OMAP4430_CM1_ABE_MCBSP1_CLKCTRL,
-	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
-	.clkdm_name	= "abe_clkdm",
-};
-
-static struct clk mcbsp2_sync_mux_ck = {
-	.name		= "mcbsp2_sync_mux_ck",
-	.parent		= &abe_24m_fclk,
-	.clksel		= dmic_sync_mux_sel,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP4430_CM1_ABE_MCBSP2_CLKCTRL,
-	.clksel_mask	= OMAP4430_CLKSEL_INTERNAL_SOURCE_MASK,
-	.ops		= &clkops_null,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static const struct clksel func_mcbsp2_gfclk_sel[] = {
-	{ .parent = &mcbsp2_sync_mux_ck, .rates = div_1_0_rates },
-	{ .parent = &pad_clks_ck, .rates = div_1_1_rates },
-	{ .parent = &slimbus_clk, .rates = div_1_2_rates },
-	{ .parent = NULL },
-};
-
-/* Merged func_mcbsp2_gfclk into mcbsp2 */
-static struct clk mcbsp2_fck = {
-	.name		= "mcbsp2_fck",
-	.parent		= &mcbsp2_sync_mux_ck,
-	.clksel		= func_mcbsp2_gfclk_sel,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP4430_CM1_ABE_MCBSP2_CLKCTRL,
-	.clksel_mask	= OMAP4430_CLKSEL_SOURCE_MASK,
-	.ops		= &clkops_omap2_dflt,
-	.recalc		= &omap2_clksel_recalc,
-	.enable_reg	= OMAP4430_CM1_ABE_MCBSP2_CLKCTRL,
-	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
-	.clkdm_name	= "abe_clkdm",
-};
-
-static struct clk mcbsp3_sync_mux_ck = {
-	.name		= "mcbsp3_sync_mux_ck",
-	.parent		= &abe_24m_fclk,
-	.clksel		= dmic_sync_mux_sel,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP4430_CM1_ABE_MCBSP3_CLKCTRL,
-	.clksel_mask	= OMAP4430_CLKSEL_INTERNAL_SOURCE_MASK,
-	.ops		= &clkops_null,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static const struct clksel func_mcbsp3_gfclk_sel[] = {
-	{ .parent = &mcbsp3_sync_mux_ck, .rates = div_1_0_rates },
-	{ .parent = &pad_clks_ck, .rates = div_1_1_rates },
-	{ .parent = &slimbus_clk, .rates = div_1_2_rates },
-	{ .parent = NULL },
-};
-
-/* Merged func_mcbsp3_gfclk into mcbsp3 */
-static struct clk mcbsp3_fck = {
-	.name		= "mcbsp3_fck",
-	.parent		= &mcbsp3_sync_mux_ck,
-	.clksel		= func_mcbsp3_gfclk_sel,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP4430_CM1_ABE_MCBSP3_CLKCTRL,
-	.clksel_mask	= OMAP4430_CLKSEL_SOURCE_MASK,
-	.ops		= &clkops_omap2_dflt,
-	.recalc		= &omap2_clksel_recalc,
-	.enable_reg	= OMAP4430_CM1_ABE_MCBSP3_CLKCTRL,
-	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
-	.clkdm_name	= "abe_clkdm",
-};
-
-static const struct clksel mcbsp4_sync_mux_sel[] = {
-	{ .parent = &func_96m_fclk, .rates = div_1_0_rates },
-	{ .parent = &per_abe_nc_fclk, .rates = div_1_1_rates },
-	{ .parent = NULL },
-};
-
-static struct clk mcbsp4_sync_mux_ck = {
-	.name		= "mcbsp4_sync_mux_ck",
-	.parent		= &func_96m_fclk,
-	.clksel		= mcbsp4_sync_mux_sel,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP4430_CM_L4PER_MCBSP4_CLKCTRL,
-	.clksel_mask	= OMAP4430_CLKSEL_INTERNAL_SOURCE_MASK,
-	.ops		= &clkops_null,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static const struct clksel per_mcbsp4_gfclk_sel[] = {
-	{ .parent = &mcbsp4_sync_mux_ck, .rates = div_1_0_rates },
-	{ .parent = &pad_clks_ck, .rates = div_1_1_rates },
-	{ .parent = NULL },
-};
-
-/* Merged per_mcbsp4_gfclk into mcbsp4 */
-static struct clk mcbsp4_fck = {
-	.name		= "mcbsp4_fck",
-	.parent		= &mcbsp4_sync_mux_ck,
-	.clksel		= per_mcbsp4_gfclk_sel,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP4430_CM_L4PER_MCBSP4_CLKCTRL,
-	.clksel_mask	= OMAP4430_CLKSEL_SOURCE_24_24_MASK,
-	.ops		= &clkops_omap2_dflt,
-	.recalc		= &omap2_clksel_recalc,
-	.enable_reg	= OMAP4430_CM_L4PER_MCBSP4_CLKCTRL,
-	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
-	.clkdm_name	= "l4_per_clkdm",
-};
-
-static struct clk mcpdm_fck = {
-	.name		= "mcpdm_fck",
-	.ops		= &clkops_omap2_dflt,
-	.enable_reg	= OMAP4430_CM1_ABE_PDM_CLKCTRL,
-	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
-	.clkdm_name	= "abe_clkdm",
-	.parent		= &pad_clks_ck,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mcspi1_fck = {
-	.name		= "mcspi1_fck",
-	.ops		= &clkops_omap2_dflt,
-	.enable_reg	= OMAP4430_CM_L4PER_MCSPI1_CLKCTRL,
-	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
-	.clkdm_name	= "l4_per_clkdm",
-	.parent		= &func_48m_fclk,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mcspi2_fck = {
-	.name		= "mcspi2_fck",
-	.ops		= &clkops_omap2_dflt,
-	.enable_reg	= OMAP4430_CM_L4PER_MCSPI2_CLKCTRL,
-	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
-	.clkdm_name	= "l4_per_clkdm",
-	.parent		= &func_48m_fclk,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mcspi3_fck = {
-	.name		= "mcspi3_fck",
-	.ops		= &clkops_omap2_dflt,
-	.enable_reg	= OMAP4430_CM_L4PER_MCSPI3_CLKCTRL,
-	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
-	.clkdm_name	= "l4_per_clkdm",
-	.parent		= &func_48m_fclk,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mcspi4_fck = {
-	.name		= "mcspi4_fck",
-	.ops		= &clkops_omap2_dflt,
-	.enable_reg	= OMAP4430_CM_L4PER_MCSPI4_CLKCTRL,
-	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
-	.clkdm_name	= "l4_per_clkdm",
-	.parent		= &func_48m_fclk,
-	.recalc		= &followparent_recalc,
-};
-
-static const struct clksel hsmmc1_fclk_sel[] = {
-	{ .parent = &func_64m_fclk, .rates = div_1_0_rates },
-	{ .parent = &func_96m_fclk, .rates = div_1_1_rates },
-	{ .parent = NULL },
-};
-
-/* Merged hsmmc1_fclk into mmc1 */
-static struct clk mmc1_fck = {
-	.name		= "mmc1_fck",
-	.parent		= &func_64m_fclk,
-	.clksel		= hsmmc1_fclk_sel,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP4430_CM_L3INIT_MMC1_CLKCTRL,
-	.clksel_mask	= OMAP4430_CLKSEL_MASK,
-	.ops		= &clkops_omap2_dflt,
-	.recalc		= &omap2_clksel_recalc,
-	.enable_reg	= OMAP4430_CM_L3INIT_MMC1_CLKCTRL,
-	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
-	.clkdm_name	= "l3_init_clkdm",
-};
-
-/* Merged hsmmc2_fclk into mmc2 */
-static struct clk mmc2_fck = {
-	.name		= "mmc2_fck",
-	.parent		= &func_64m_fclk,
-	.clksel		= hsmmc1_fclk_sel,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP4430_CM_L3INIT_MMC2_CLKCTRL,
-	.clksel_mask	= OMAP4430_CLKSEL_MASK,
-	.ops		= &clkops_omap2_dflt,
-	.recalc		= &omap2_clksel_recalc,
-	.enable_reg	= OMAP4430_CM_L3INIT_MMC2_CLKCTRL,
-	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
-	.clkdm_name	= "l3_init_clkdm",
-};
-
-static struct clk mmc3_fck = {
-	.name		= "mmc3_fck",
-	.ops		= &clkops_omap2_dflt,
-	.enable_reg	= OMAP4430_CM_L4PER_MMCSD3_CLKCTRL,
-	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
-	.clkdm_name	= "l4_per_clkdm",
-	.parent		= &func_48m_fclk,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mmc4_fck = {
-	.name		= "mmc4_fck",
-	.ops		= &clkops_omap2_dflt,
-	.enable_reg	= OMAP4430_CM_L4PER_MMCSD4_CLKCTRL,
-	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
-	.clkdm_name	= "l4_per_clkdm",
-	.parent		= &func_48m_fclk,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk mmc5_fck = {
-	.name		= "mmc5_fck",
-	.ops		= &clkops_omap2_dflt,
-	.enable_reg	= OMAP4430_CM_L4PER_MMCSD5_CLKCTRL,
-	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
-	.clkdm_name	= "l4_per_clkdm",
-	.parent		= &func_48m_fclk,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk ocp2scp_usb_phy_phy_48m = {
-	.name		= "ocp2scp_usb_phy_phy_48m",
-	.ops		= &clkops_omap2_dflt,
-	.enable_reg	= OMAP4430_CM_L3INIT_USBPHYOCP2SCP_CLKCTRL,
-	.enable_bit	= OMAP4430_OPTFCLKEN_PHY_48M_SHIFT,
-	.clkdm_name	= "l3_init_clkdm",
-	.parent		= &func_48m_fclk,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk ocp2scp_usb_phy_ick = {
-	.name		= "ocp2scp_usb_phy_ick",
-	.ops		= &clkops_omap2_dflt,
-	.enable_reg	= OMAP4430_CM_L3INIT_USBPHYOCP2SCP_CLKCTRL,
-	.enable_bit	= OMAP4430_MODULEMODE_HWCTRL,
-	.clkdm_name	= "l3_init_clkdm",
-	.parent		= &l4_div_ck,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk ocp_wp_noc_ick = {
-	.name		= "ocp_wp_noc_ick",
-	.ops		= &clkops_omap2_dflt,
-	.enable_reg	= OMAP4430_CM_L3INSTR_OCP_WP1_CLKCTRL,
-	.enable_bit	= OMAP4430_MODULEMODE_HWCTRL,
-	.flags		= ENABLE_ON_INIT,
-	.clkdm_name	= "l3_instr_clkdm",
-	.parent		= &l3_div_ck,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk rng_ick = {
-	.name		= "rng_ick",
-	.ops		= &clkops_omap2_dflt,
-	.enable_reg	= OMAP4430_CM_L4SEC_RNG_CLKCTRL,
-	.enable_bit	= OMAP4430_MODULEMODE_HWCTRL,
-	.clkdm_name	= "l4_secure_clkdm",
-	.parent		= &l4_div_ck,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk sha2md5_fck = {
-	.name		= "sha2md5_fck",
-	.ops		= &clkops_omap2_dflt,
-	.enable_reg	= OMAP4430_CM_L4SEC_SHA2MD51_CLKCTRL,
-	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
-	.clkdm_name	= "l4_secure_clkdm",
-	.parent		= &l3_div_ck,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk sl2if_ick = {
-	.name		= "sl2if_ick",
-	.ops		= &clkops_omap2_dflt,
-	.enable_reg	= OMAP4430_CM_IVAHD_SL2_CLKCTRL,
-	.enable_bit	= OMAP4430_MODULEMODE_HWCTRL,
-	.clkdm_name	= "ivahd_clkdm",
-	.parent		= &dpll_iva_m5x2_ck,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk slimbus1_fclk_1 = {
-	.name		= "slimbus1_fclk_1",
-	.ops		= &clkops_omap2_dflt,
-	.enable_reg	= OMAP4430_CM1_ABE_SLIMBUS_CLKCTRL,
-	.enable_bit	= OMAP4430_OPTFCLKEN_FCLK1_SHIFT,
-	.clkdm_name	= "abe_clkdm",
-	.parent		= &func_24m_clk,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk slimbus1_fclk_0 = {
-	.name		= "slimbus1_fclk_0",
-	.ops		= &clkops_omap2_dflt,
-	.enable_reg	= OMAP4430_CM1_ABE_SLIMBUS_CLKCTRL,
-	.enable_bit	= OMAP4430_OPTFCLKEN_FCLK0_SHIFT,
-	.clkdm_name	= "abe_clkdm",
-	.parent		= &abe_24m_fclk,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk slimbus1_fclk_2 = {
-	.name		= "slimbus1_fclk_2",
-	.ops		= &clkops_omap2_dflt,
-	.enable_reg	= OMAP4430_CM1_ABE_SLIMBUS_CLKCTRL,
-	.enable_bit	= OMAP4430_OPTFCLKEN_FCLK2_SHIFT,
-	.clkdm_name	= "abe_clkdm",
-	.parent		= &pad_clks_ck,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk slimbus1_slimbus_clk = {
-	.name		= "slimbus1_slimbus_clk",
-	.ops		= &clkops_omap2_dflt,
-	.enable_reg	= OMAP4430_CM1_ABE_SLIMBUS_CLKCTRL,
-	.enable_bit	= OMAP4430_OPTFCLKEN_SLIMBUS_CLK_11_11_SHIFT,
-	.clkdm_name	= "abe_clkdm",
-	.parent		= &slimbus_clk,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk slimbus1_fck = {
-	.name		= "slimbus1_fck",
-	.ops		= &clkops_omap2_dflt,
-	.enable_reg	= OMAP4430_CM1_ABE_SLIMBUS_CLKCTRL,
-	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
-	.clkdm_name	= "abe_clkdm",
-	.parent		= &ocp_abe_iclk,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk slimbus2_fclk_1 = {
-	.name		= "slimbus2_fclk_1",
-	.ops		= &clkops_omap2_dflt,
-	.enable_reg	= OMAP4430_CM_L4PER_SLIMBUS2_CLKCTRL,
-	.enable_bit	= OMAP4430_OPTFCLKEN_PERABE24M_GFCLK_SHIFT,
-	.clkdm_name	= "l4_per_clkdm",
-	.parent		= &per_abe_24m_fclk,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk slimbus2_fclk_0 = {
-	.name		= "slimbus2_fclk_0",
-	.ops		= &clkops_omap2_dflt,
-	.enable_reg	= OMAP4430_CM_L4PER_SLIMBUS2_CLKCTRL,
-	.enable_bit	= OMAP4430_OPTFCLKEN_PER24MC_GFCLK_SHIFT,
-	.clkdm_name	= "l4_per_clkdm",
-	.parent		= &func_24mc_fclk,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk slimbus2_slimbus_clk = {
-	.name		= "slimbus2_slimbus_clk",
-	.ops		= &clkops_omap2_dflt,
-	.enable_reg	= OMAP4430_CM_L4PER_SLIMBUS2_CLKCTRL,
-	.enable_bit	= OMAP4430_OPTFCLKEN_SLIMBUS_CLK_SHIFT,
-	.clkdm_name	= "l4_per_clkdm",
-	.parent		= &pad_slimbus_core_clks_ck,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk slimbus2_fck = {
-	.name		= "slimbus2_fck",
-	.ops		= &clkops_omap2_dflt,
-	.enable_reg	= OMAP4430_CM_L4PER_SLIMBUS2_CLKCTRL,
-	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
-	.clkdm_name	= "l4_per_clkdm",
-	.parent		= &l4_div_ck,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk smartreflex_core_fck = {
-	.name		= "smartreflex_core_fck",
-	.ops		= &clkops_omap2_dflt,
-	.enable_reg	= OMAP4430_CM_ALWON_SR_CORE_CLKCTRL,
-	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
-	.clkdm_name	= "l4_ao_clkdm",
-	.parent		= &l4_wkup_clk_mux_ck,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk smartreflex_iva_fck = {
-	.name		= "smartreflex_iva_fck",
-	.ops		= &clkops_omap2_dflt,
-	.enable_reg	= OMAP4430_CM_ALWON_SR_IVA_CLKCTRL,
-	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
-	.clkdm_name	= "l4_ao_clkdm",
-	.parent		= &l4_wkup_clk_mux_ck,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk smartreflex_mpu_fck = {
-	.name		= "smartreflex_mpu_fck",
-	.ops		= &clkops_omap2_dflt,
-	.enable_reg	= OMAP4430_CM_ALWON_SR_MPU_CLKCTRL,
-	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
-	.clkdm_name	= "l4_ao_clkdm",
-	.parent		= &l4_wkup_clk_mux_ck,
-	.recalc		= &followparent_recalc,
-};
-
-/* Merged dmt1_clk_mux into timer1 */
-static struct clk timer1_fck = {
-	.name		= "timer1_fck",
-	.parent		= &sys_clkin_ck,
-	.clksel		= abe_dpll_bypass_clk_mux_sel,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP4430_CM_WKUP_TIMER1_CLKCTRL,
-	.clksel_mask	= OMAP4430_CLKSEL_MASK,
-	.ops		= &clkops_omap2_dflt,
-	.recalc		= &omap2_clksel_recalc,
-	.enable_reg	= OMAP4430_CM_WKUP_TIMER1_CLKCTRL,
-	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
-	.clkdm_name	= "l4_wkup_clkdm",
-};
-
-/* Merged cm2_dm10_mux into timer10 */
-static struct clk timer10_fck = {
-	.name		= "timer10_fck",
-	.parent		= &sys_clkin_ck,
-	.clksel		= abe_dpll_bypass_clk_mux_sel,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP4430_CM_L4PER_DMTIMER10_CLKCTRL,
-	.clksel_mask	= OMAP4430_CLKSEL_MASK,
-	.ops		= &clkops_omap2_dflt,
-	.recalc		= &omap2_clksel_recalc,
-	.enable_reg	= OMAP4430_CM_L4PER_DMTIMER10_CLKCTRL,
-	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
-	.clkdm_name	= "l4_per_clkdm",
-};
-
-/* Merged cm2_dm11_mux into timer11 */
-static struct clk timer11_fck = {
-	.name		= "timer11_fck",
-	.parent		= &sys_clkin_ck,
-	.clksel		= abe_dpll_bypass_clk_mux_sel,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP4430_CM_L4PER_DMTIMER11_CLKCTRL,
-	.clksel_mask	= OMAP4430_CLKSEL_MASK,
-	.ops		= &clkops_omap2_dflt,
-	.recalc		= &omap2_clksel_recalc,
-	.enable_reg	= OMAP4430_CM_L4PER_DMTIMER11_CLKCTRL,
-	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
-	.clkdm_name	= "l4_per_clkdm",
-};
-
-/* Merged cm2_dm2_mux into timer2 */
-static struct clk timer2_fck = {
-	.name		= "timer2_fck",
-	.parent		= &sys_clkin_ck,
-	.clksel		= abe_dpll_bypass_clk_mux_sel,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP4430_CM_L4PER_DMTIMER2_CLKCTRL,
-	.clksel_mask	= OMAP4430_CLKSEL_MASK,
-	.ops		= &clkops_omap2_dflt,
-	.recalc		= &omap2_clksel_recalc,
-	.enable_reg	= OMAP4430_CM_L4PER_DMTIMER2_CLKCTRL,
-	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
-	.clkdm_name	= "l4_per_clkdm",
-};
-
-/* Merged cm2_dm3_mux into timer3 */
-static struct clk timer3_fck = {
-	.name		= "timer3_fck",
-	.parent		= &sys_clkin_ck,
-	.clksel		= abe_dpll_bypass_clk_mux_sel,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP4430_CM_L4PER_DMTIMER3_CLKCTRL,
-	.clksel_mask	= OMAP4430_CLKSEL_MASK,
-	.ops		= &clkops_omap2_dflt,
-	.recalc		= &omap2_clksel_recalc,
-	.enable_reg	= OMAP4430_CM_L4PER_DMTIMER3_CLKCTRL,
-	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
-	.clkdm_name	= "l4_per_clkdm",
-};
-
-/* Merged cm2_dm4_mux into timer4 */
-static struct clk timer4_fck = {
-	.name		= "timer4_fck",
-	.parent		= &sys_clkin_ck,
-	.clksel		= abe_dpll_bypass_clk_mux_sel,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP4430_CM_L4PER_DMTIMER4_CLKCTRL,
-	.clksel_mask	= OMAP4430_CLKSEL_MASK,
-	.ops		= &clkops_omap2_dflt,
-	.recalc		= &omap2_clksel_recalc,
-	.enable_reg	= OMAP4430_CM_L4PER_DMTIMER4_CLKCTRL,
-	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
-	.clkdm_name	= "l4_per_clkdm",
-};
-
-static const struct clksel timer5_sync_mux_sel[] = {
-	{ .parent = &syc_clk_div_ck, .rates = div_1_0_rates },
-	{ .parent = &sys_32k_ck, .rates = div_1_1_rates },
-	{ .parent = NULL },
-};
-
-/* Merged timer5_sync_mux into timer5 */
-static struct clk timer5_fck = {
-	.name		= "timer5_fck",
-	.parent		= &syc_clk_div_ck,
-	.clksel		= timer5_sync_mux_sel,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP4430_CM1_ABE_TIMER5_CLKCTRL,
-	.clksel_mask	= OMAP4430_CLKSEL_MASK,
-	.ops		= &clkops_omap2_dflt,
-	.recalc		= &omap2_clksel_recalc,
-	.enable_reg	= OMAP4430_CM1_ABE_TIMER5_CLKCTRL,
-	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
-	.clkdm_name	= "abe_clkdm",
-};
-
-/* Merged timer6_sync_mux into timer6 */
-static struct clk timer6_fck = {
-	.name		= "timer6_fck",
-	.parent		= &syc_clk_div_ck,
-	.clksel		= timer5_sync_mux_sel,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP4430_CM1_ABE_TIMER6_CLKCTRL,
-	.clksel_mask	= OMAP4430_CLKSEL_MASK,
-	.ops		= &clkops_omap2_dflt,
-	.recalc		= &omap2_clksel_recalc,
-	.enable_reg	= OMAP4430_CM1_ABE_TIMER6_CLKCTRL,
-	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
-	.clkdm_name	= "abe_clkdm",
-};
-
-/* Merged timer7_sync_mux into timer7 */
-static struct clk timer7_fck = {
-	.name		= "timer7_fck",
-	.parent		= &syc_clk_div_ck,
-	.clksel		= timer5_sync_mux_sel,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP4430_CM1_ABE_TIMER7_CLKCTRL,
-	.clksel_mask	= OMAP4430_CLKSEL_MASK,
-	.ops		= &clkops_omap2_dflt,
-	.recalc		= &omap2_clksel_recalc,
-	.enable_reg	= OMAP4430_CM1_ABE_TIMER7_CLKCTRL,
-	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
-	.clkdm_name	= "abe_clkdm",
-};
-
-/* Merged timer8_sync_mux into timer8 */
-static struct clk timer8_fck = {
-	.name		= "timer8_fck",
-	.parent		= &syc_clk_div_ck,
-	.clksel		= timer5_sync_mux_sel,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP4430_CM1_ABE_TIMER8_CLKCTRL,
-	.clksel_mask	= OMAP4430_CLKSEL_MASK,
-	.ops		= &clkops_omap2_dflt,
-	.recalc		= &omap2_clksel_recalc,
-	.enable_reg	= OMAP4430_CM1_ABE_TIMER8_CLKCTRL,
-	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
-	.clkdm_name	= "abe_clkdm",
-};
-
-/* Merged cm2_dm9_mux into timer9 */
-static struct clk timer9_fck = {
-	.name		= "timer9_fck",
-	.parent		= &sys_clkin_ck,
-	.clksel		= abe_dpll_bypass_clk_mux_sel,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP4430_CM_L4PER_DMTIMER9_CLKCTRL,
-	.clksel_mask	= OMAP4430_CLKSEL_MASK,
-	.ops		= &clkops_omap2_dflt,
-	.recalc		= &omap2_clksel_recalc,
-	.enable_reg	= OMAP4430_CM_L4PER_DMTIMER9_CLKCTRL,
-	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
-	.clkdm_name	= "l4_per_clkdm",
-};
-
-static struct clk uart1_fck = {
-	.name		= "uart1_fck",
-	.ops		= &clkops_omap2_dflt,
-	.enable_reg	= OMAP4430_CM_L4PER_UART1_CLKCTRL,
-	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
-	.clkdm_name	= "l4_per_clkdm",
-	.parent		= &func_48m_fclk,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk uart2_fck = {
-	.name		= "uart2_fck",
-	.ops		= &clkops_omap2_dflt,
-	.enable_reg	= OMAP4430_CM_L4PER_UART2_CLKCTRL,
-	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
-	.clkdm_name	= "l4_per_clkdm",
-	.parent		= &func_48m_fclk,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk uart3_fck = {
-	.name		= "uart3_fck",
-	.ops		= &clkops_omap2_dflt,
-	.enable_reg	= OMAP4430_CM_L4PER_UART3_CLKCTRL,
-	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
-	.clkdm_name	= "l4_per_clkdm",
-	.parent		= &func_48m_fclk,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk uart4_fck = {
-	.name		= "uart4_fck",
-	.ops		= &clkops_omap2_dflt,
-	.enable_reg	= OMAP4430_CM_L4PER_UART4_CLKCTRL,
-	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
-	.clkdm_name	= "l4_per_clkdm",
-	.parent		= &func_48m_fclk,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk usb_host_fs_fck = {
-	.name		= "usb_host_fs_fck",
-	.ops		= &clkops_omap2_dflt,
-	.enable_reg	= OMAP4430_CM_L3INIT_USB_HOST_FS_CLKCTRL,
-	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
-	.clkdm_name	= "l3_init_clkdm",
-	.parent		= &func_48mc_fclk,
-	.recalc		= &followparent_recalc,
-};
-
-static const struct clksel utmi_p1_gfclk_sel[] = {
-	{ .parent = &init_60m_fclk, .rates = div_1_0_rates },
-	{ .parent = &xclk60mhsp1_ck, .rates = div_1_1_rates },
-	{ .parent = NULL },
-};
-
-static struct clk utmi_p1_gfclk = {
-	.name		= "utmi_p1_gfclk",
-	.parent		= &init_60m_fclk,
-	.clksel		= utmi_p1_gfclk_sel,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP4430_CM_L3INIT_USB_HOST_CLKCTRL,
-	.clksel_mask	= OMAP4430_CLKSEL_UTMI_P1_MASK,
-	.ops		= &clkops_null,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk usb_host_hs_utmi_p1_clk = {
-	.name		= "usb_host_hs_utmi_p1_clk",
-	.ops		= &clkops_omap2_dflt,
-	.enable_reg	= OMAP4430_CM_L3INIT_USB_HOST_CLKCTRL,
-	.enable_bit	= OMAP4430_OPTFCLKEN_UTMI_P1_CLK_SHIFT,
-	.clkdm_name	= "l3_init_clkdm",
-	.parent		= &utmi_p1_gfclk,
-	.recalc		= &followparent_recalc,
-};
-
-static const struct clksel utmi_p2_gfclk_sel[] = {
-	{ .parent = &init_60m_fclk, .rates = div_1_0_rates },
-	{ .parent = &xclk60mhsp2_ck, .rates = div_1_1_rates },
-	{ .parent = NULL },
-};
-
-static struct clk utmi_p2_gfclk = {
-	.name		= "utmi_p2_gfclk",
-	.parent		= &init_60m_fclk,
-	.clksel		= utmi_p2_gfclk_sel,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP4430_CM_L3INIT_USB_HOST_CLKCTRL,
-	.clksel_mask	= OMAP4430_CLKSEL_UTMI_P2_MASK,
-	.ops		= &clkops_null,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk usb_host_hs_utmi_p2_clk = {
-	.name		= "usb_host_hs_utmi_p2_clk",
-	.ops		= &clkops_omap2_dflt,
-	.enable_reg	= OMAP4430_CM_L3INIT_USB_HOST_CLKCTRL,
-	.enable_bit	= OMAP4430_OPTFCLKEN_UTMI_P2_CLK_SHIFT,
-	.clkdm_name	= "l3_init_clkdm",
-	.parent		= &utmi_p2_gfclk,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk usb_host_hs_utmi_p3_clk = {
-	.name		= "usb_host_hs_utmi_p3_clk",
-	.ops		= &clkops_omap2_dflt,
-	.enable_reg	= OMAP4430_CM_L3INIT_USB_HOST_CLKCTRL,
-	.enable_bit	= OMAP4430_OPTFCLKEN_UTMI_P3_CLK_SHIFT,
-	.clkdm_name	= "l3_init_clkdm",
-	.parent		= &init_60m_fclk,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk usb_host_hs_hsic480m_p1_clk = {
-	.name		= "usb_host_hs_hsic480m_p1_clk",
-	.ops		= &clkops_omap2_dflt,
-	.enable_reg	= OMAP4430_CM_L3INIT_USB_HOST_CLKCTRL,
-	.enable_bit	= OMAP4430_OPTFCLKEN_HSIC480M_P1_CLK_SHIFT,
-	.clkdm_name	= "l3_init_clkdm",
-	.parent		= &dpll_usb_m2_ck,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk usb_host_hs_hsic60m_p1_clk = {
-	.name		= "usb_host_hs_hsic60m_p1_clk",
-	.ops		= &clkops_omap2_dflt,
-	.enable_reg	= OMAP4430_CM_L3INIT_USB_HOST_CLKCTRL,
-	.enable_bit	= OMAP4430_OPTFCLKEN_HSIC60M_P1_CLK_SHIFT,
-	.clkdm_name	= "l3_init_clkdm",
-	.parent		= &init_60m_fclk,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk usb_host_hs_hsic60m_p2_clk = {
-	.name		= "usb_host_hs_hsic60m_p2_clk",
-	.ops		= &clkops_omap2_dflt,
-	.enable_reg	= OMAP4430_CM_L3INIT_USB_HOST_CLKCTRL,
-	.enable_bit	= OMAP4430_OPTFCLKEN_HSIC60M_P2_CLK_SHIFT,
-	.clkdm_name	= "l3_init_clkdm",
-	.parent		= &init_60m_fclk,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk usb_host_hs_hsic480m_p2_clk = {
-	.name		= "usb_host_hs_hsic480m_p2_clk",
-	.ops		= &clkops_omap2_dflt,
-	.enable_reg	= OMAP4430_CM_L3INIT_USB_HOST_CLKCTRL,
-	.enable_bit	= OMAP4430_OPTFCLKEN_HSIC480M_P2_CLK_SHIFT,
-	.clkdm_name	= "l3_init_clkdm",
-	.parent		= &dpll_usb_m2_ck,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk usb_host_hs_func48mclk = {
-	.name		= "usb_host_hs_func48mclk",
-	.ops		= &clkops_omap2_dflt,
-	.enable_reg	= OMAP4430_CM_L3INIT_USB_HOST_CLKCTRL,
-	.enable_bit	= OMAP4430_OPTFCLKEN_FUNC48MCLK_SHIFT,
-	.clkdm_name	= "l3_init_clkdm",
-	.parent		= &func_48mc_fclk,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk usb_host_hs_fck = {
-	.name		= "usb_host_hs_fck",
-	.ops		= &clkops_omap2_dflt,
-	.enable_reg	= OMAP4430_CM_L3INIT_USB_HOST_CLKCTRL,
-	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
-	.clkdm_name	= "l3_init_clkdm",
-	.parent		= &init_60m_fclk,
-	.recalc		= &followparent_recalc,
-};
-
-static const struct clksel otg_60m_gfclk_sel[] = {
-	{ .parent = &utmi_phy_clkout_ck, .rates = div_1_0_rates },
-	{ .parent = &xclk60motg_ck, .rates = div_1_1_rates },
-	{ .parent = NULL },
-};
-
-static struct clk otg_60m_gfclk = {
-	.name		= "otg_60m_gfclk",
-	.parent		= &utmi_phy_clkout_ck,
-	.clksel		= otg_60m_gfclk_sel,
-	.init		= &omap2_init_clksel_parent,
-	.clksel_reg	= OMAP4430_CM_L3INIT_USB_OTG_CLKCTRL,
-	.clksel_mask	= OMAP4430_CLKSEL_60M_MASK,
-	.ops		= &clkops_null,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk usb_otg_hs_xclk = {
-	.name		= "usb_otg_hs_xclk",
-	.ops		= &clkops_omap2_dflt,
-	.enable_reg	= OMAP4430_CM_L3INIT_USB_OTG_CLKCTRL,
-	.enable_bit	= OMAP4430_OPTFCLKEN_XCLK_SHIFT,
-	.clkdm_name	= "l3_init_clkdm",
-	.parent		= &otg_60m_gfclk,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk usb_otg_hs_ick = {
-	.name		= "usb_otg_hs_ick",
-	.ops		= &clkops_omap2_dflt,
-	.enable_reg	= OMAP4430_CM_L3INIT_USB_OTG_CLKCTRL,
-	.enable_bit	= OMAP4430_MODULEMODE_HWCTRL,
-	.clkdm_name	= "l3_init_clkdm",
-	.parent		= &l3_div_ck,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk usb_phy_cm_clk32k = {
-	.name		= "usb_phy_cm_clk32k",
-	.ops		= &clkops_omap2_dflt,
-	.enable_reg	= OMAP4430_CM_ALWON_USBPHY_CLKCTRL,
-	.enable_bit	= OMAP4430_OPTFCLKEN_CLK32K_SHIFT,
-	.clkdm_name	= "l4_ao_clkdm",
-	.parent		= &sys_32k_ck,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk usb_tll_hs_usb_ch2_clk = {
-	.name		= "usb_tll_hs_usb_ch2_clk",
-	.ops		= &clkops_omap2_dflt,
-	.enable_reg	= OMAP4430_CM_L3INIT_USB_TLL_CLKCTRL,
-	.enable_bit	= OMAP4430_OPTFCLKEN_USB_CH2_CLK_SHIFT,
-	.clkdm_name	= "l3_init_clkdm",
-	.parent		= &init_60m_fclk,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk usb_tll_hs_usb_ch0_clk = {
-	.name		= "usb_tll_hs_usb_ch0_clk",
-	.ops		= &clkops_omap2_dflt,
-	.enable_reg	= OMAP4430_CM_L3INIT_USB_TLL_CLKCTRL,
-	.enable_bit	= OMAP4430_OPTFCLKEN_USB_CH0_CLK_SHIFT,
-	.clkdm_name	= "l3_init_clkdm",
-	.parent		= &init_60m_fclk,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk usb_tll_hs_usb_ch1_clk = {
-	.name		= "usb_tll_hs_usb_ch1_clk",
-	.ops		= &clkops_omap2_dflt,
-	.enable_reg	= OMAP4430_CM_L3INIT_USB_TLL_CLKCTRL,
-	.enable_bit	= OMAP4430_OPTFCLKEN_USB_CH1_CLK_SHIFT,
-	.clkdm_name	= "l3_init_clkdm",
-	.parent		= &init_60m_fclk,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk usb_tll_hs_ick = {
-	.name		= "usb_tll_hs_ick",
-	.ops		= &clkops_omap2_dflt,
-	.enable_reg	= OMAP4430_CM_L3INIT_USB_TLL_CLKCTRL,
-	.enable_bit	= OMAP4430_MODULEMODE_HWCTRL,
-	.clkdm_name	= "l3_init_clkdm",
-	.parent		= &l4_div_ck,
-	.recalc		= &followparent_recalc,
-};
-
-static const struct clksel_rate div2_14to18_rates[] = {
-	{ .div = 14, .val = 0, .flags = RATE_IN_4430 },
-	{ .div = 18, .val = 1, .flags = RATE_IN_4430 },
-	{ .div = 0 },
-};
-
-static const struct clksel usim_fclk_div[] = {
-	{ .parent = &dpll_per_m4x2_ck, .rates = div2_14to18_rates },
-	{ .parent = NULL },
-};
-
-static struct clk usim_ck = {
-	.name		= "usim_ck",
-	.parent		= &dpll_per_m4x2_ck,
-	.clksel		= usim_fclk_div,
-	.clksel_reg	= OMAP4430_CM_WKUP_USIM_CLKCTRL,
-	.clksel_mask	= OMAP4430_CLKSEL_DIV_MASK,
-	.ops		= &clkops_null,
-	.recalc		= &omap2_clksel_recalc,
-	.round_rate	= &omap2_clksel_round_rate,
-	.set_rate	= &omap2_clksel_set_rate,
-};
-
-static struct clk usim_fclk = {
-	.name		= "usim_fclk",
-	.ops		= &clkops_omap2_dflt,
-	.enable_reg	= OMAP4430_CM_WKUP_USIM_CLKCTRL,
-	.enable_bit	= OMAP4430_OPTFCLKEN_FCLK_SHIFT,
-	.clkdm_name	= "l4_wkup_clkdm",
-	.parent		= &usim_ck,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk usim_fck = {
-	.name		= "usim_fck",
-	.ops		= &clkops_omap2_dflt,
-	.enable_reg	= OMAP4430_CM_WKUP_USIM_CLKCTRL,
-	.enable_bit	= OMAP4430_MODULEMODE_HWCTRL,
-	.clkdm_name	= "l4_wkup_clkdm",
-	.parent		= &sys_32k_ck,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk wd_timer2_fck = {
-	.name		= "wd_timer2_fck",
-	.ops		= &clkops_omap2_dflt,
-	.enable_reg	= OMAP4430_CM_WKUP_WDT2_CLKCTRL,
-	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
-	.clkdm_name	= "l4_wkup_clkdm",
-	.parent		= &sys_32k_ck,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk wd_timer3_fck = {
-	.name		= "wd_timer3_fck",
-	.ops		= &clkops_omap2_dflt,
-	.enable_reg	= OMAP4430_CM1_ABE_WDT3_CLKCTRL,
-	.enable_bit	= OMAP4430_MODULEMODE_SWCTRL,
-	.clkdm_name	= "abe_clkdm",
-	.parent		= &sys_32k_ck,
-	.recalc		= &followparent_recalc,
-};
-
-/* Remaining optional clocks */
-static const struct clksel stm_clk_div_div[] = {
-	{ .parent = &pmd_stm_clock_mux_ck, .rates = div3_1to4_rates },
-	{ .parent = NULL },
-};
-
-static struct clk stm_clk_div_ck = {
-	.name		= "stm_clk_div_ck",
-	.parent		= &pmd_stm_clock_mux_ck,
-	.clksel		= stm_clk_div_div,
-	.clksel_reg	= OMAP4430_CM_EMU_DEBUGSS_CLKCTRL,
-	.clksel_mask	= OMAP4430_CLKSEL_PMD_STM_CLK_MASK,
-	.ops		= &clkops_null,
-	.recalc		= &omap2_clksel_recalc,
-	.round_rate	= &omap2_clksel_round_rate,
-	.set_rate	= &omap2_clksel_set_rate,
-};
-
-static const struct clksel trace_clk_div_div[] = {
-	{ .parent = &pmd_trace_clk_mux_ck, .rates = div3_1to4_rates },
-	{ .parent = NULL },
-};
-
-static struct clk trace_clk_div_ck = {
-	.name		= "trace_clk_div_ck",
-	.parent		= &pmd_trace_clk_mux_ck,
-	.clkdm_name	= "emu_sys_clkdm",
-	.clksel		= trace_clk_div_div,
-	.clksel_reg	= OMAP4430_CM_EMU_DEBUGSS_CLKCTRL,
-	.clksel_mask	= OMAP4430_CLKSEL_PMD_TRACE_CLK_MASK,
-	.ops		= &clkops_null,
-	.recalc		= &omap2_clksel_recalc,
-	.round_rate	= &omap2_clksel_round_rate,
-	.set_rate	= &omap2_clksel_set_rate,
-};
-
-/* SCRM aux clk nodes */
-
-static const struct clksel auxclk_src_sel[] = {
-	{ .parent = &sys_clkin_ck, .rates = div_1_0_rates },
-	{ .parent = &dpll_core_m3x2_ck, .rates = div_1_1_rates },
-	{ .parent = &dpll_per_m3x2_ck, .rates = div_1_2_rates },
-	{ .parent = NULL },
-};
-
-static const struct clksel_rate div16_1to16_rates[] = {
-	{ .div = 1, .val = 0, .flags = RATE_IN_4430 },
-	{ .div = 2, .val = 1, .flags = RATE_IN_4430 },
-	{ .div = 3, .val = 2, .flags = RATE_IN_4430 },
-	{ .div = 4, .val = 3, .flags = RATE_IN_4430 },
-	{ .div = 5, .val = 4, .flags = RATE_IN_4430 },
-	{ .div = 6, .val = 5, .flags = RATE_IN_4430 },
-	{ .div = 7, .val = 6, .flags = RATE_IN_4430 },
-	{ .div = 8, .val = 7, .flags = RATE_IN_4430 },
-	{ .div = 9, .val = 8, .flags = RATE_IN_4430 },
-	{ .div = 10, .val = 9, .flags = RATE_IN_4430 },
-	{ .div = 11, .val = 10, .flags = RATE_IN_4430 },
-	{ .div = 12, .val = 11, .flags = RATE_IN_4430 },
-	{ .div = 13, .val = 12, .flags = RATE_IN_4430 },
-	{ .div = 14, .val = 13, .flags = RATE_IN_4430 },
-	{ .div = 15, .val = 14, .flags = RATE_IN_4430 },
-	{ .div = 16, .val = 15, .flags = RATE_IN_4430 },
-	{ .div = 0 },
-};
-
-static struct clk auxclk0_src_ck = {
-	.name		= "auxclk0_src_ck",
-	.parent		= &sys_clkin_ck,
-	.init		= &omap2_init_clksel_parent,
-	.ops		= &clkops_omap2_dflt,
-	.clksel		= auxclk_src_sel,
-	.clksel_reg	= OMAP4_SCRM_AUXCLK0,
-	.clksel_mask	= OMAP4_SRCSELECT_MASK,
-	.recalc		= &omap2_clksel_recalc,
-	.enable_reg	= OMAP4_SCRM_AUXCLK0,
-	.enable_bit	= OMAP4_ENABLE_SHIFT,
-};
-
-static const struct clksel auxclk0_sel[] = {
-	{ .parent = &auxclk0_src_ck, .rates = div16_1to16_rates },
-	{ .parent = NULL },
-};
-
-static struct clk auxclk0_ck = {
-	.name		= "auxclk0_ck",
-	.parent		= &auxclk0_src_ck,
-	.clksel		= auxclk0_sel,
-	.clksel_reg	= OMAP4_SCRM_AUXCLK0,
-	.clksel_mask	= OMAP4_CLKDIV_MASK,
-	.ops		= &clkops_null,
-	.recalc		= &omap2_clksel_recalc,
-	.round_rate	= &omap2_clksel_round_rate,
-	.set_rate	= &omap2_clksel_set_rate,
-};
-
-static struct clk auxclk1_src_ck = {
-	.name		= "auxclk1_src_ck",
-	.parent		= &sys_clkin_ck,
-	.init		= &omap2_init_clksel_parent,
-	.ops		= &clkops_omap2_dflt,
-	.clksel		= auxclk_src_sel,
-	.clksel_reg	= OMAP4_SCRM_AUXCLK1,
-	.clksel_mask	= OMAP4_SRCSELECT_MASK,
-	.recalc		= &omap2_clksel_recalc,
-	.enable_reg	= OMAP4_SCRM_AUXCLK1,
-	.enable_bit	= OMAP4_ENABLE_SHIFT,
-};
-
-static const struct clksel auxclk1_sel[] = {
-	{ .parent = &auxclk1_src_ck, .rates = div16_1to16_rates },
-	{ .parent = NULL },
-};
-
-static struct clk auxclk1_ck = {
-	.name		= "auxclk1_ck",
-	.parent		= &auxclk1_src_ck,
-	.clksel		= auxclk1_sel,
-	.clksel_reg	= OMAP4_SCRM_AUXCLK1,
-	.clksel_mask	= OMAP4_CLKDIV_MASK,
-	.ops		= &clkops_null,
-	.recalc		= &omap2_clksel_recalc,
-	.round_rate	= &omap2_clksel_round_rate,
-	.set_rate	= &omap2_clksel_set_rate,
-};
-
-static struct clk auxclk2_src_ck = {
-	.name		= "auxclk2_src_ck",
-	.parent		= &sys_clkin_ck,
-	.init		= &omap2_init_clksel_parent,
-	.ops		= &clkops_omap2_dflt,
-	.clksel		= auxclk_src_sel,
-	.clksel_reg	= OMAP4_SCRM_AUXCLK2,
-	.clksel_mask	= OMAP4_SRCSELECT_MASK,
-	.recalc		= &omap2_clksel_recalc,
-	.enable_reg	= OMAP4_SCRM_AUXCLK2,
-	.enable_bit	= OMAP4_ENABLE_SHIFT,
-};
-
-static const struct clksel auxclk2_sel[] = {
-	{ .parent = &auxclk2_src_ck, .rates = div16_1to16_rates },
-	{ .parent = NULL },
-};
-
-static struct clk auxclk2_ck = {
-	.name		= "auxclk2_ck",
-	.parent		= &auxclk2_src_ck,
-	.clksel		= auxclk2_sel,
-	.clksel_reg	= OMAP4_SCRM_AUXCLK2,
-	.clksel_mask	= OMAP4_CLKDIV_MASK,
-	.ops		= &clkops_null,
-	.recalc		= &omap2_clksel_recalc,
-	.round_rate	= &omap2_clksel_round_rate,
-	.set_rate	= &omap2_clksel_set_rate,
-};
-
-static struct clk auxclk3_src_ck = {
-	.name		= "auxclk3_src_ck",
-	.parent		= &sys_clkin_ck,
-	.init		= &omap2_init_clksel_parent,
-	.ops		= &clkops_omap2_dflt,
-	.clksel		= auxclk_src_sel,
-	.clksel_reg	= OMAP4_SCRM_AUXCLK3,
-	.clksel_mask	= OMAP4_SRCSELECT_MASK,
-	.recalc		= &omap2_clksel_recalc,
-	.enable_reg	= OMAP4_SCRM_AUXCLK3,
-	.enable_bit	= OMAP4_ENABLE_SHIFT,
-};
-
-static const struct clksel auxclk3_sel[] = {
-	{ .parent = &auxclk3_src_ck, .rates = div16_1to16_rates },
-	{ .parent = NULL },
-};
-
-static struct clk auxclk3_ck = {
-	.name		= "auxclk3_ck",
-	.parent		= &auxclk3_src_ck,
-	.clksel		= auxclk3_sel,
-	.clksel_reg	= OMAP4_SCRM_AUXCLK3,
-	.clksel_mask	= OMAP4_CLKDIV_MASK,
-	.ops		= &clkops_null,
-	.recalc		= &omap2_clksel_recalc,
-	.round_rate	= &omap2_clksel_round_rate,
-	.set_rate	= &omap2_clksel_set_rate,
-};
-
-static struct clk auxclk4_src_ck = {
-	.name		= "auxclk4_src_ck",
-	.parent		= &sys_clkin_ck,
-	.init		= &omap2_init_clksel_parent,
-	.ops		= &clkops_omap2_dflt,
-	.clksel		= auxclk_src_sel,
-	.clksel_reg	= OMAP4_SCRM_AUXCLK4,
-	.clksel_mask	= OMAP4_SRCSELECT_MASK,
-	.recalc		= &omap2_clksel_recalc,
-	.enable_reg	= OMAP4_SCRM_AUXCLK4,
-	.enable_bit	= OMAP4_ENABLE_SHIFT,
-};
-
-static const struct clksel auxclk4_sel[] = {
-	{ .parent = &auxclk4_src_ck, .rates = div16_1to16_rates },
-	{ .parent = NULL },
-};
-
-static struct clk auxclk4_ck = {
-	.name		= "auxclk4_ck",
-	.parent		= &auxclk4_src_ck,
-	.clksel		= auxclk4_sel,
-	.clksel_reg	= OMAP4_SCRM_AUXCLK4,
-	.clksel_mask	= OMAP4_CLKDIV_MASK,
-	.ops		= &clkops_null,
-	.recalc		= &omap2_clksel_recalc,
-	.round_rate	= &omap2_clksel_round_rate,
-	.set_rate	= &omap2_clksel_set_rate,
-};
-
-static struct clk auxclk5_src_ck = {
-	.name		= "auxclk5_src_ck",
-	.parent		= &sys_clkin_ck,
-	.init		= &omap2_init_clksel_parent,
-	.ops		= &clkops_omap2_dflt,
-	.clksel		= auxclk_src_sel,
-	.clksel_reg	= OMAP4_SCRM_AUXCLK5,
-	.clksel_mask	= OMAP4_SRCSELECT_MASK,
-	.recalc		= &omap2_clksel_recalc,
-	.enable_reg	= OMAP4_SCRM_AUXCLK5,
-	.enable_bit	= OMAP4_ENABLE_SHIFT,
-};
-
-static const struct clksel auxclk5_sel[] = {
-	{ .parent = &auxclk5_src_ck, .rates = div16_1to16_rates },
-	{ .parent = NULL },
-};
-
-static struct clk auxclk5_ck = {
-	.name		= "auxclk5_ck",
-	.parent		= &auxclk5_src_ck,
-	.clksel		= auxclk5_sel,
-	.clksel_reg	= OMAP4_SCRM_AUXCLK5,
-	.clksel_mask	= OMAP4_CLKDIV_MASK,
-	.ops		= &clkops_null,
-	.recalc		= &omap2_clksel_recalc,
-	.round_rate	= &omap2_clksel_round_rate,
-	.set_rate	= &omap2_clksel_set_rate,
-};
-
-static const struct clksel auxclkreq_sel[] = {
-	{ .parent = &auxclk0_ck, .rates = div_1_0_rates },
-	{ .parent = &auxclk1_ck, .rates = div_1_1_rates },
-	{ .parent = &auxclk2_ck, .rates = div_1_2_rates },
-	{ .parent = &auxclk3_ck, .rates = div_1_3_rates },
-	{ .parent = &auxclk4_ck, .rates = div_1_4_rates },
-	{ .parent = &auxclk5_ck, .rates = div_1_5_rates },
-	{ .parent = NULL },
-};
-
-static struct clk auxclkreq0_ck = {
-	.name		= "auxclkreq0_ck",
-	.parent		= &auxclk0_ck,
-	.init		= &omap2_init_clksel_parent,
-	.ops		= &clkops_null,
-	.clksel         = auxclkreq_sel,
-	.clksel_reg	= OMAP4_SCRM_AUXCLKREQ0,
-	.clksel_mask	= OMAP4_MAPPING_MASK,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk auxclkreq1_ck = {
-	.name		= "auxclkreq1_ck",
-	.parent		= &auxclk1_ck,
-	.init		= &omap2_init_clksel_parent,
-	.ops		= &clkops_null,
-	.clksel         = auxclkreq_sel,
-	.clksel_reg	= OMAP4_SCRM_AUXCLKREQ1,
-	.clksel_mask	= OMAP4_MAPPING_MASK,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk auxclkreq2_ck = {
-	.name		= "auxclkreq2_ck",
-	.parent		= &auxclk2_ck,
-	.init		= &omap2_init_clksel_parent,
-	.ops		= &clkops_null,
-	.clksel         = auxclkreq_sel,
-	.clksel_reg	= OMAP4_SCRM_AUXCLKREQ2,
-	.clksel_mask	= OMAP4_MAPPING_MASK,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk auxclkreq3_ck = {
-	.name		= "auxclkreq3_ck",
-	.parent		= &auxclk3_ck,
-	.init		= &omap2_init_clksel_parent,
-	.ops		= &clkops_null,
-	.clksel         = auxclkreq_sel,
-	.clksel_reg	= OMAP4_SCRM_AUXCLKREQ3,
-	.clksel_mask	= OMAP4_MAPPING_MASK,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk auxclkreq4_ck = {
-	.name		= "auxclkreq4_ck",
-	.parent		= &auxclk4_ck,
-	.init		= &omap2_init_clksel_parent,
-	.ops		= &clkops_null,
-	.clksel         = auxclkreq_sel,
-	.clksel_reg	= OMAP4_SCRM_AUXCLKREQ4,
-	.clksel_mask	= OMAP4_MAPPING_MASK,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-static struct clk auxclkreq5_ck = {
-	.name		= "auxclkreq5_ck",
-	.parent		= &auxclk5_ck,
-	.init		= &omap2_init_clksel_parent,
-	.ops		= &clkops_null,
-	.clksel         = auxclkreq_sel,
-	.clksel_reg	= OMAP4_SCRM_AUXCLKREQ5,
-	.clksel_mask	= OMAP4_MAPPING_MASK,
-	.recalc		= &omap2_clksel_recalc,
-};
-
-/*
- * clkdev
- */
-
-static struct omap_clk omap44xx_clks[] = {
-	CLK(NULL,	"extalt_clkin_ck",		&extalt_clkin_ck,	CK_443X),
-	CLK(NULL,	"pad_clks_ck",			&pad_clks_ck,	CK_443X),
-	CLK(NULL,	"pad_slimbus_core_clks_ck",	&pad_slimbus_core_clks_ck,	CK_443X),
-	CLK(NULL,	"secure_32k_clk_src_ck",	&secure_32k_clk_src_ck,	CK_443X),
-	CLK(NULL,	"slimbus_clk",			&slimbus_clk,	CK_443X),
-	CLK(NULL,	"sys_32k_ck",			&sys_32k_ck,	CK_443X),
-	CLK(NULL,	"virt_12000000_ck",		&virt_12000000_ck,	CK_443X),
-	CLK(NULL,	"virt_13000000_ck",		&virt_13000000_ck,	CK_443X),
-	CLK(NULL,	"virt_16800000_ck",		&virt_16800000_ck,	CK_443X),
-	CLK(NULL,	"virt_19200000_ck",		&virt_19200000_ck,	CK_443X),
-	CLK(NULL,	"virt_26000000_ck",		&virt_26000000_ck,	CK_443X),
-	CLK(NULL,	"virt_27000000_ck",		&virt_27000000_ck,	CK_443X),
-	CLK(NULL,	"virt_38400000_ck",		&virt_38400000_ck,	CK_443X),
-	CLK(NULL,	"sys_clkin_ck",			&sys_clkin_ck,	CK_443X),
-	CLK(NULL,	"tie_low_clock_ck",		&tie_low_clock_ck,	CK_443X),
-	CLK(NULL,	"utmi_phy_clkout_ck",		&utmi_phy_clkout_ck,	CK_443X),
-	CLK(NULL,	"xclk60mhsp1_ck",		&xclk60mhsp1_ck,	CK_443X),
-	CLK(NULL,	"xclk60mhsp2_ck",		&xclk60mhsp2_ck,	CK_443X),
-	CLK(NULL,	"xclk60motg_ck",		&xclk60motg_ck,	CK_443X),
-	CLK(NULL,	"abe_dpll_bypass_clk_mux_ck",	&abe_dpll_bypass_clk_mux_ck,	CK_443X),
-	CLK(NULL,	"abe_dpll_refclk_mux_ck",	&abe_dpll_refclk_mux_ck,	CK_443X),
-	CLK(NULL,	"dpll_abe_ck",			&dpll_abe_ck,	CK_443X),
-	CLK(NULL,	"dpll_abe_x2_ck",		&dpll_abe_x2_ck,	CK_443X),
-	CLK(NULL,	"dpll_abe_m2x2_ck",		&dpll_abe_m2x2_ck,	CK_443X),
-	CLK(NULL,	"abe_24m_fclk",			&abe_24m_fclk,	CK_443X),
-	CLK(NULL,	"abe_clk",			&abe_clk,	CK_443X),
-	CLK(NULL,	"aess_fclk",			&aess_fclk,	CK_443X),
-	CLK(NULL,	"dpll_abe_m3x2_ck",		&dpll_abe_m3x2_ck,	CK_443X),
-	CLK(NULL,	"core_hsd_byp_clk_mux_ck",	&core_hsd_byp_clk_mux_ck,	CK_443X),
-	CLK(NULL,	"dpll_core_ck",			&dpll_core_ck,	CK_443X),
-	CLK(NULL,	"dpll_core_x2_ck",		&dpll_core_x2_ck,	CK_443X),
-	CLK(NULL,	"dpll_core_m6x2_ck",		&dpll_core_m6x2_ck,	CK_443X),
-	CLK(NULL,	"dbgclk_mux_ck",		&dbgclk_mux_ck,	CK_443X),
-	CLK(NULL,	"dpll_core_m2_ck",		&dpll_core_m2_ck,	CK_443X),
-	CLK(NULL,	"ddrphy_ck",			&ddrphy_ck,	CK_443X),
-	CLK(NULL,	"dpll_core_m5x2_ck",		&dpll_core_m5x2_ck,	CK_443X),
-	CLK(NULL,	"div_core_ck",			&div_core_ck,	CK_443X),
-	CLK(NULL,	"div_iva_hs_clk",		&div_iva_hs_clk,	CK_443X),
-	CLK(NULL,	"div_mpu_hs_clk",		&div_mpu_hs_clk,	CK_443X),
-	CLK(NULL,	"dpll_core_m4x2_ck",		&dpll_core_m4x2_ck,	CK_443X),
-	CLK(NULL,	"dll_clk_div_ck",		&dll_clk_div_ck,	CK_443X),
-	CLK(NULL,	"dpll_abe_m2_ck",		&dpll_abe_m2_ck,	CK_443X),
-	CLK(NULL,	"dpll_core_m3x2_ck",		&dpll_core_m3x2_ck,	CK_443X),
-	CLK(NULL,	"dpll_core_m7x2_ck",		&dpll_core_m7x2_ck,	CK_443X),
-	CLK(NULL,	"iva_hsd_byp_clk_mux_ck",	&iva_hsd_byp_clk_mux_ck,	CK_443X),
-	CLK(NULL,	"dpll_iva_ck",			&dpll_iva_ck,	CK_443X),
-	CLK(NULL,	"dpll_iva_x2_ck",		&dpll_iva_x2_ck,	CK_443X),
-	CLK(NULL,	"dpll_iva_m4x2_ck",		&dpll_iva_m4x2_ck,	CK_443X),
-	CLK(NULL,	"dpll_iva_m5x2_ck",		&dpll_iva_m5x2_ck,	CK_443X),
-	CLK(NULL,	"dpll_mpu_ck",			&dpll_mpu_ck,	CK_443X),
-	CLK(NULL,	"dpll_mpu_m2_ck",		&dpll_mpu_m2_ck,	CK_443X),
-	CLK(NULL,	"per_hs_clk_div_ck",		&per_hs_clk_div_ck,	CK_443X),
-	CLK(NULL,	"per_hsd_byp_clk_mux_ck",	&per_hsd_byp_clk_mux_ck,	CK_443X),
-	CLK(NULL,	"dpll_per_ck",			&dpll_per_ck,	CK_443X),
-	CLK(NULL,	"dpll_per_m2_ck",		&dpll_per_m2_ck,	CK_443X),
-	CLK(NULL,	"dpll_per_x2_ck",		&dpll_per_x2_ck,	CK_443X),
-	CLK(NULL,	"dpll_per_m2x2_ck",		&dpll_per_m2x2_ck,	CK_443X),
-	CLK(NULL,	"dpll_per_m3x2_ck",		&dpll_per_m3x2_ck,	CK_443X),
-	CLK(NULL,	"dpll_per_m4x2_ck",		&dpll_per_m4x2_ck,	CK_443X),
-	CLK(NULL,	"dpll_per_m5x2_ck",		&dpll_per_m5x2_ck,	CK_443X),
-	CLK(NULL,	"dpll_per_m6x2_ck",		&dpll_per_m6x2_ck,	CK_443X),
-	CLK(NULL,	"dpll_per_m7x2_ck",		&dpll_per_m7x2_ck,	CK_443X),
-	CLK(NULL,	"usb_hs_clk_div_ck",		&usb_hs_clk_div_ck,	CK_443X),
-	CLK(NULL,	"dpll_usb_ck",			&dpll_usb_ck,	CK_443X),
-	CLK(NULL,	"dpll_usb_clkdcoldo_ck",	&dpll_usb_clkdcoldo_ck,	CK_443X),
-	CLK(NULL,	"dpll_usb_m2_ck",		&dpll_usb_m2_ck,	CK_443X),
-	CLK(NULL,	"ducati_clk_mux_ck",		&ducati_clk_mux_ck,	CK_443X),
-	CLK(NULL,	"func_12m_fclk",		&func_12m_fclk,	CK_443X),
-	CLK(NULL,	"func_24m_clk",			&func_24m_clk,	CK_443X),
-	CLK(NULL,	"func_24mc_fclk",		&func_24mc_fclk,	CK_443X),
-	CLK(NULL,	"func_48m_fclk",		&func_48m_fclk,	CK_443X),
-	CLK(NULL,	"func_48mc_fclk",		&func_48mc_fclk,	CK_443X),
-	CLK(NULL,	"func_64m_fclk",		&func_64m_fclk,	CK_443X),
-	CLK(NULL,	"func_96m_fclk",		&func_96m_fclk,	CK_443X),
-	CLK(NULL,	"init_60m_fclk",		&init_60m_fclk,	CK_443X),
-	CLK(NULL,	"l3_div_ck",			&l3_div_ck,	CK_443X),
-	CLK(NULL,	"l4_div_ck",			&l4_div_ck,	CK_443X),
-	CLK(NULL,	"lp_clk_div_ck",		&lp_clk_div_ck,	CK_443X),
-	CLK(NULL,	"l4_wkup_clk_mux_ck",		&l4_wkup_clk_mux_ck,	CK_443X),
-	CLK("smp_twd",	NULL,				&mpu_periphclk,	CK_443X),
-	CLK(NULL,	"ocp_abe_iclk",			&ocp_abe_iclk,	CK_443X),
-	CLK(NULL,	"per_abe_24m_fclk",		&per_abe_24m_fclk,	CK_443X),
-	CLK(NULL,	"per_abe_nc_fclk",		&per_abe_nc_fclk,	CK_443X),
-	CLK(NULL,	"pmd_stm_clock_mux_ck",		&pmd_stm_clock_mux_ck,	CK_443X),
-	CLK(NULL,	"pmd_trace_clk_mux_ck",		&pmd_trace_clk_mux_ck,	CK_443X),
-	CLK(NULL,	"syc_clk_div_ck",		&syc_clk_div_ck,	CK_443X),
-	CLK(NULL,	"aes1_fck",			&aes1_fck,	CK_443X),
-	CLK(NULL,	"aes2_fck",			&aes2_fck,	CK_443X),
-	CLK(NULL,	"aess_fck",			&aess_fck,	CK_443X),
-	CLK(NULL,	"bandgap_fclk",			&bandgap_fclk,	CK_443X),
-	CLK(NULL,	"bandgap_ts_fclk",		&bandgap_ts_fclk,	CK_446X),
-	CLK(NULL,	"des3des_fck",			&des3des_fck,	CK_443X),
-	CLK(NULL,	"div_ts_ck",			&div_ts_ck,	CK_446X),
-	CLK(NULL,	"dmic_sync_mux_ck",		&dmic_sync_mux_ck,	CK_443X),
-	CLK(NULL,	"dmic_fck",			&dmic_fck,	CK_443X),
-	CLK(NULL,	"dsp_fck",			&dsp_fck,	CK_443X),
-	CLK(NULL,	"dss_sys_clk",			&dss_sys_clk,	CK_443X),
-	CLK(NULL,	"dss_tv_clk",			&dss_tv_clk,	CK_443X),
-	CLK(NULL,	"dss_48mhz_clk",		&dss_48mhz_clk,	CK_443X),
-	CLK(NULL,	"dss_dss_clk",			&dss_dss_clk,	CK_443X),
-	CLK(NULL,	"dss_fck",			&dss_fck,	CK_443X),
-	CLK("omapdss_dss",	"ick",				&dss_fck,	CK_443X),
-	CLK(NULL,	"efuse_ctrl_cust_fck",		&efuse_ctrl_cust_fck,	CK_443X),
-	CLK(NULL,	"emif1_fck",			&emif1_fck,	CK_443X),
-	CLK(NULL,	"emif2_fck",			&emif2_fck,	CK_443X),
-	CLK(NULL,	"fdif_fck",			&fdif_fck,	CK_443X),
-	CLK(NULL,	"fpka_fck",			&fpka_fck,	CK_443X),
-	CLK(NULL,	"gpio1_dbclk",			&gpio1_dbclk,	CK_443X),
-	CLK(NULL,	"gpio1_ick",			&gpio1_ick,	CK_443X),
-	CLK(NULL,	"gpio2_dbclk",			&gpio2_dbclk,	CK_443X),
-	CLK(NULL,	"gpio2_ick",			&gpio2_ick,	CK_443X),
-	CLK(NULL,	"gpio3_dbclk",			&gpio3_dbclk,	CK_443X),
-	CLK(NULL,	"gpio3_ick",			&gpio3_ick,	CK_443X),
-	CLK(NULL,	"gpio4_dbclk",			&gpio4_dbclk,	CK_443X),
-	CLK(NULL,	"gpio4_ick",			&gpio4_ick,	CK_443X),
-	CLK(NULL,	"gpio5_dbclk",			&gpio5_dbclk,	CK_443X),
-	CLK(NULL,	"gpio5_ick",			&gpio5_ick,	CK_443X),
-	CLK(NULL,	"gpio6_dbclk",			&gpio6_dbclk,	CK_443X),
-	CLK(NULL,	"gpio6_ick",			&gpio6_ick,	CK_443X),
-	CLK(NULL,	"gpmc_ick",			&gpmc_ick,	CK_443X),
-	CLK(NULL,	"gpu_fck",			&gpu_fck,	CK_443X),
-	CLK(NULL,	"hdq1w_fck",			&hdq1w_fck,	CK_443X),
-	CLK(NULL,	"hsi_fck",			&hsi_fck,	CK_443X),
-	CLK(NULL,	"i2c1_fck",			&i2c1_fck,	CK_443X),
-	CLK(NULL,	"i2c2_fck",			&i2c2_fck,	CK_443X),
-	CLK(NULL,	"i2c3_fck",			&i2c3_fck,	CK_443X),
-	CLK(NULL,	"i2c4_fck",			&i2c4_fck,	CK_443X),
-	CLK(NULL,	"ipu_fck",			&ipu_fck,	CK_443X),
-	CLK(NULL,	"iss_ctrlclk",			&iss_ctrlclk,	CK_443X),
-	CLK(NULL,	"iss_fck",			&iss_fck,	CK_443X),
-	CLK(NULL,	"iva_fck",			&iva_fck,	CK_443X),
-	CLK(NULL,	"kbd_fck",			&kbd_fck,	CK_443X),
-	CLK(NULL,	"l3_instr_ick",			&l3_instr_ick,	CK_443X),
-	CLK(NULL,	"l3_main_3_ick",		&l3_main_3_ick,	CK_443X),
-	CLK(NULL,	"mcasp_sync_mux_ck",		&mcasp_sync_mux_ck,	CK_443X),
-	CLK(NULL,	"mcasp_fck",			&mcasp_fck,	CK_443X),
-	CLK(NULL,	"mcbsp1_sync_mux_ck",		&mcbsp1_sync_mux_ck,	CK_443X),
-	CLK(NULL,	"mcbsp1_fck",			&mcbsp1_fck,	CK_443X),
-	CLK(NULL,	"mcbsp2_sync_mux_ck",		&mcbsp2_sync_mux_ck,	CK_443X),
-	CLK(NULL,	"mcbsp2_fck",			&mcbsp2_fck,	CK_443X),
-	CLK(NULL,	"mcbsp3_sync_mux_ck",		&mcbsp3_sync_mux_ck,	CK_443X),
-	CLK(NULL,	"mcbsp3_fck",			&mcbsp3_fck,	CK_443X),
-	CLK(NULL,	"mcbsp4_sync_mux_ck",		&mcbsp4_sync_mux_ck,	CK_443X),
-	CLK(NULL,	"mcbsp4_fck",			&mcbsp4_fck,	CK_443X),
-	CLK(NULL,	"mcpdm_fck",			&mcpdm_fck,	CK_443X),
-	CLK(NULL,	"mcspi1_fck",			&mcspi1_fck,	CK_443X),
-	CLK(NULL,	"mcspi2_fck",			&mcspi2_fck,	CK_443X),
-	CLK(NULL,	"mcspi3_fck",			&mcspi3_fck,	CK_443X),
-	CLK(NULL,	"mcspi4_fck",			&mcspi4_fck,	CK_443X),
-	CLK(NULL,	"mmc1_fck",			&mmc1_fck,	CK_443X),
-	CLK(NULL,	"mmc2_fck",			&mmc2_fck,	CK_443X),
-	CLK(NULL,	"mmc3_fck",			&mmc3_fck,	CK_443X),
-	CLK(NULL,	"mmc4_fck",			&mmc4_fck,	CK_443X),
-	CLK(NULL,	"mmc5_fck",			&mmc5_fck,	CK_443X),
-	CLK(NULL,	"ocp2scp_usb_phy_phy_48m",	&ocp2scp_usb_phy_phy_48m,	CK_443X),
-	CLK(NULL,	"ocp2scp_usb_phy_ick",		&ocp2scp_usb_phy_ick,	CK_443X),
-	CLK(NULL,	"ocp_wp_noc_ick",		&ocp_wp_noc_ick,	CK_443X),
-	CLK(NULL,	"rng_ick",			&rng_ick,	CK_443X),
-	CLK("omap_rng",	"ick",				&rng_ick,	CK_443X),
-	CLK(NULL,	"sha2md5_fck",			&sha2md5_fck,	CK_443X),
-	CLK(NULL,	"sl2if_ick",			&sl2if_ick,	CK_443X),
-	CLK(NULL,	"slimbus1_fclk_1",		&slimbus1_fclk_1,	CK_443X),
-	CLK(NULL,	"slimbus1_fclk_0",		&slimbus1_fclk_0,	CK_443X),
-	CLK(NULL,	"slimbus1_fclk_2",		&slimbus1_fclk_2,	CK_443X),
-	CLK(NULL,	"slimbus1_slimbus_clk",		&slimbus1_slimbus_clk,	CK_443X),
-	CLK(NULL,	"slimbus1_fck",			&slimbus1_fck,	CK_443X),
-	CLK(NULL,	"slimbus2_fclk_1",		&slimbus2_fclk_1,	CK_443X),
-	CLK(NULL,	"slimbus2_fclk_0",		&slimbus2_fclk_0,	CK_443X),
-	CLK(NULL,	"slimbus2_slimbus_clk",		&slimbus2_slimbus_clk,	CK_443X),
-	CLK(NULL,	"slimbus2_fck",			&slimbus2_fck,	CK_443X),
-	CLK(NULL,	"smartreflex_core_fck",		&smartreflex_core_fck,	CK_443X),
-	CLK(NULL,	"smartreflex_iva_fck",		&smartreflex_iva_fck,	CK_443X),
-	CLK(NULL,	"smartreflex_mpu_fck",		&smartreflex_mpu_fck,	CK_443X),
-	CLK(NULL,	"timer1_fck",			&timer1_fck,	CK_443X),
-	CLK(NULL,	"timer10_fck",			&timer10_fck,	CK_443X),
-	CLK(NULL,	"timer11_fck",			&timer11_fck,	CK_443X),
-	CLK(NULL,	"timer2_fck",			&timer2_fck,	CK_443X),
-	CLK(NULL,	"timer3_fck",			&timer3_fck,	CK_443X),
-	CLK(NULL,	"timer4_fck",			&timer4_fck,	CK_443X),
-	CLK(NULL,	"timer5_fck",			&timer5_fck,	CK_443X),
-	CLK(NULL,	"timer6_fck",			&timer6_fck,	CK_443X),
-	CLK(NULL,	"timer7_fck",			&timer7_fck,	CK_443X),
-	CLK(NULL,	"timer8_fck",			&timer8_fck,	CK_443X),
-	CLK(NULL,	"timer9_fck",			&timer9_fck,	CK_443X),
-	CLK(NULL,	"uart1_fck",			&uart1_fck,	CK_443X),
-	CLK(NULL,	"uart2_fck",			&uart2_fck,	CK_443X),
-	CLK(NULL,	"uart3_fck",			&uart3_fck,	CK_443X),
-	CLK(NULL,	"uart4_fck",			&uart4_fck,	CK_443X),
-	CLK("usbhs_omap",	"fs_fck",		&usb_host_fs_fck,	CK_443X),
-	CLK(NULL,	"usb_host_fs_fck",		&usb_host_fs_fck,	CK_443X),
-	CLK(NULL,	"utmi_p1_gfclk",		&utmi_p1_gfclk,	CK_443X),
-	CLK(NULL,	"usb_host_hs_utmi_p1_clk",	&usb_host_hs_utmi_p1_clk,	CK_443X),
-	CLK(NULL,	"utmi_p2_gfclk",		&utmi_p2_gfclk,	CK_443X),
-	CLK(NULL,	"usb_host_hs_utmi_p2_clk",	&usb_host_hs_utmi_p2_clk,	CK_443X),
-	CLK(NULL,	"usb_host_hs_utmi_p3_clk",	&usb_host_hs_utmi_p3_clk,	CK_443X),
-	CLK(NULL,	"usb_host_hs_hsic480m_p1_clk",	&usb_host_hs_hsic480m_p1_clk,	CK_443X),
-	CLK(NULL,	"usb_host_hs_hsic60m_p1_clk",	&usb_host_hs_hsic60m_p1_clk,	CK_443X),
-	CLK(NULL,	"usb_host_hs_hsic60m_p2_clk",	&usb_host_hs_hsic60m_p2_clk,	CK_443X),
-	CLK(NULL,	"usb_host_hs_hsic480m_p2_clk",	&usb_host_hs_hsic480m_p2_clk,	CK_443X),
-	CLK(NULL,	"usb_host_hs_func48mclk",	&usb_host_hs_func48mclk,	CK_443X),
-	CLK(NULL,	"usb_host_hs_fck",		&usb_host_hs_fck,	CK_443X),
-	CLK("usbhs_omap",	"hs_fck",		&usb_host_hs_fck,	CK_443X),
-	CLK(NULL,	"otg_60m_gfclk",		&otg_60m_gfclk,	CK_443X),
-	CLK(NULL,	"usb_otg_hs_xclk",		&usb_otg_hs_xclk,	CK_443X),
-	CLK(NULL,	"usb_otg_hs_ick",		&usb_otg_hs_ick,	CK_443X),
-	CLK("musb-omap2430",	"ick",				&usb_otg_hs_ick,	CK_443X),
-	CLK(NULL,	"usb_phy_cm_clk32k",		&usb_phy_cm_clk32k,	CK_443X),
-	CLK(NULL,	"usb_tll_hs_usb_ch2_clk",	&usb_tll_hs_usb_ch2_clk,	CK_443X),
-	CLK(NULL,	"usb_tll_hs_usb_ch0_clk",	&usb_tll_hs_usb_ch0_clk,	CK_443X),
-	CLK(NULL,	"usb_tll_hs_usb_ch1_clk",	&usb_tll_hs_usb_ch1_clk,	CK_443X),
-	CLK(NULL,	"usb_tll_hs_ick",		&usb_tll_hs_ick,	CK_443X),
-	CLK("usbhs_omap",	"usbtll_ick",		&usb_tll_hs_ick,	CK_443X),
-	CLK("usbhs_tll",	"usbtll_ick",		&usb_tll_hs_ick,	CK_443X),
-	CLK(NULL,	"usim_ck",			&usim_ck,	CK_443X),
-	CLK(NULL,	"usim_fclk",			&usim_fclk,	CK_443X),
-	CLK(NULL,	"usim_fck",			&usim_fck,	CK_443X),
-	CLK(NULL,	"wd_timer2_fck",		&wd_timer2_fck,	CK_443X),
-	CLK(NULL,	"wd_timer3_fck",		&wd_timer3_fck,	CK_443X),
-	CLK(NULL,	"stm_clk_div_ck",		&stm_clk_div_ck,	CK_443X),
-	CLK(NULL,	"trace_clk_div_ck",		&trace_clk_div_ck,	CK_443X),
-	CLK(NULL,	"auxclk0_src_ck",		&auxclk0_src_ck,	CK_443X),
-	CLK(NULL,	"auxclk0_ck",			&auxclk0_ck,	CK_443X),
-	CLK(NULL,	"auxclkreq0_ck",		&auxclkreq0_ck,	CK_443X),
-	CLK(NULL,	"auxclk1_src_ck",		&auxclk1_src_ck,	CK_443X),
-	CLK(NULL,	"auxclk1_ck",			&auxclk1_ck,	CK_443X),
-	CLK(NULL,	"auxclkreq1_ck",		&auxclkreq1_ck,	CK_443X),
-	CLK(NULL,	"auxclk2_src_ck",		&auxclk2_src_ck,	CK_443X),
-	CLK(NULL,	"auxclk2_ck",			&auxclk2_ck,	CK_443X),
-	CLK(NULL,	"auxclkreq2_ck",		&auxclkreq2_ck,	CK_443X),
-	CLK(NULL,	"auxclk3_src_ck",		&auxclk3_src_ck,	CK_443X),
-	CLK(NULL,	"auxclk3_ck",			&auxclk3_ck,	CK_443X),
-	CLK(NULL,	"auxclkreq3_ck",		&auxclkreq3_ck,	CK_443X),
-	CLK(NULL,	"auxclk4_src_ck",		&auxclk4_src_ck,	CK_443X),
-	CLK(NULL,	"auxclk4_ck",			&auxclk4_ck,	CK_443X),
-	CLK(NULL,	"auxclkreq4_ck",		&auxclkreq4_ck,	CK_443X),
-	CLK(NULL,	"auxclk5_src_ck",		&auxclk5_src_ck,	CK_443X),
-	CLK(NULL,	"auxclk5_ck",			&auxclk5_ck,	CK_443X),
-	CLK(NULL,	"auxclkreq5_ck",		&auxclkreq5_ck,	CK_443X),
-	CLK("omap-gpmc",	"fck",				&dummy_ck,	CK_443X),
-	CLK("omap_i2c.1",	"ick",				&dummy_ck,	CK_443X),
-	CLK("omap_i2c.2",	"ick",				&dummy_ck,	CK_443X),
-	CLK("omap_i2c.3",	"ick",				&dummy_ck,	CK_443X),
-	CLK("omap_i2c.4",	"ick",				&dummy_ck,	CK_443X),
-	CLK(NULL,	"mailboxes_ick",		&dummy_ck,	CK_443X),
-	CLK("omap_hsmmc.0",	"ick",				&dummy_ck,	CK_443X),
-	CLK("omap_hsmmc.1",	"ick",				&dummy_ck,	CK_443X),
-	CLK("omap_hsmmc.2",	"ick",				&dummy_ck,	CK_443X),
-	CLK("omap_hsmmc.3",	"ick",				&dummy_ck,	CK_443X),
-	CLK("omap_hsmmc.4",	"ick",				&dummy_ck,	CK_443X),
-	CLK("omap-mcbsp.1",	"ick",				&dummy_ck,	CK_443X),
-	CLK("omap-mcbsp.2",	"ick",				&dummy_ck,	CK_443X),
-	CLK("omap-mcbsp.3",	"ick",				&dummy_ck,	CK_443X),
-	CLK("omap-mcbsp.4",	"ick",				&dummy_ck,	CK_443X),
-	CLK("omap2_mcspi.1",	"ick",				&dummy_ck,	CK_443X),
-	CLK("omap2_mcspi.2",	"ick",				&dummy_ck,	CK_443X),
-	CLK("omap2_mcspi.3",	"ick",				&dummy_ck,	CK_443X),
-	CLK("omap2_mcspi.4",	"ick",				&dummy_ck,	CK_443X),
-	CLK(NULL,	"uart1_ick",			&dummy_ck,	CK_443X),
-	CLK(NULL,	"uart2_ick",			&dummy_ck,	CK_443X),
-	CLK(NULL,	"uart3_ick",			&dummy_ck,	CK_443X),
-	CLK(NULL,	"uart4_ick",			&dummy_ck,	CK_443X),
-	CLK("usbhs_omap",	"usbhost_ick",		&dummy_ck,		CK_443X),
-	CLK("usbhs_omap",	"usbtll_fck",		&dummy_ck,	CK_443X),
-	CLK("usbhs_tll",	"usbtll_fck",		&dummy_ck,	CK_443X),
-	CLK("omap_wdt",	"ick",				&dummy_ck,	CK_443X),
-	CLK(NULL,	"timer_32k_ck",	&sys_32k_ck,	CK_443X),
-	/* TODO: Remove "omap_timer.X" aliases once DT migration is complete */
-	CLK("omap_timer.1",	"timer_sys_ck",	&sys_clkin_ck,	CK_443X),
-	CLK("omap_timer.2",	"timer_sys_ck",	&sys_clkin_ck,	CK_443X),
-	CLK("omap_timer.3",	"timer_sys_ck",	&sys_clkin_ck,	CK_443X),
-	CLK("omap_timer.4",	"timer_sys_ck",	&sys_clkin_ck,	CK_443X),
-	CLK("omap_timer.9",	"timer_sys_ck",	&sys_clkin_ck,	CK_443X),
-	CLK("omap_timer.10",	"timer_sys_ck",	&sys_clkin_ck,	CK_443X),
-	CLK("omap_timer.11",	"timer_sys_ck",	&sys_clkin_ck,	CK_443X),
-	CLK("omap_timer.5",	"timer_sys_ck",	&syc_clk_div_ck,	CK_443X),
-	CLK("omap_timer.6",	"timer_sys_ck",	&syc_clk_div_ck,	CK_443X),
-	CLK("omap_timer.7",	"timer_sys_ck",	&syc_clk_div_ck,	CK_443X),
-	CLK("omap_timer.8",	"timer_sys_ck",	&syc_clk_div_ck,	CK_443X),
-	CLK("4a318000.timer",	"timer_sys_ck",	&sys_clkin_ck,	CK_443X),
-	CLK("48032000.timer",	"timer_sys_ck",	&sys_clkin_ck,	CK_443X),
-	CLK("48034000.timer",	"timer_sys_ck",	&sys_clkin_ck,	CK_443X),
-	CLK("48036000.timer",	"timer_sys_ck",	&sys_clkin_ck,	CK_443X),
-	CLK("4803e000.timer",	"timer_sys_ck",	&sys_clkin_ck,	CK_443X),
-	CLK("48086000.timer",	"timer_sys_ck",	&sys_clkin_ck,	CK_443X),
-	CLK("48088000.timer",	"timer_sys_ck",	&sys_clkin_ck,	CK_443X),
-	CLK("49038000.timer",	"timer_sys_ck",	&syc_clk_div_ck,	CK_443X),
-	CLK("4903a000.timer",	"timer_sys_ck",	&syc_clk_div_ck,	CK_443X),
-	CLK("4903c000.timer",	"timer_sys_ck",	&syc_clk_div_ck,	CK_443X),
-	CLK("4903e000.timer",	"timer_sys_ck",	&syc_clk_div_ck,	CK_443X),
-	CLK(NULL,	"cpufreq_ck",	&dpll_mpu_ck,	CK_443X),
-};
-
-int __init omap4xxx_clk_init(void)
-{
-	struct omap_clk *c;
-	u32 cpu_clkflg;
-
-	if (cpu_is_omap443x()) {
-		cpu_mask = RATE_IN_4430;
-		cpu_clkflg = CK_443X;
-	} else if (cpu_is_omap446x() || cpu_is_omap447x()) {
-		cpu_mask = RATE_IN_4460 | RATE_IN_4430;
-		cpu_clkflg = CK_446X | CK_443X;
-
-		if (cpu_is_omap447x())
-			pr_warn("WARNING: OMAP4470 clock data incomplete!\n");
-	} else {
-		return 0;
-	}
-
-	/*
-	 * Must stay commented until all OMAP SoC drivers are
-	 * converted to runtime PM, or drivers may start crashing
-	 *
-	 * omap2_clk_disable_clkdm_control();
-	 */
-
-	for (c = omap44xx_clks; c < omap44xx_clks + ARRAY_SIZE(omap44xx_clks);
-									  c++)
-		clk_preinit(c->lk.clk);
-
-	for (c = omap44xx_clks; c < omap44xx_clks + ARRAY_SIZE(omap44xx_clks);
-									  c++)
-		if (c->cpu & cpu_clkflg) {
-			clkdev_add(&c->lk);
-			clk_register(c->lk.clk);
-			omap2_init_clk_clkdm(c->lk.clk);
-		}
-
-	/* Disable autoidle on all clocks; let the PM code enable it later */
-	omap_clk_disable_autoidle_all();
-
-	recalculate_root_clocks();
-
-	/*
-	 * Only enable those clocks we will need, let the drivers
-	 * enable other clocks as necessary
-	 */
-	clk_enable_init_clocks();
-
-	return 0;
-}
diff --git a/arch/arm/mach-omap2/clock_common_data.c b/arch/arm/mach-omap2/clock_common_data.c
index b9f3ba6..ef4d21b 100644
--- a/arch/arm/mach-omap2/clock_common_data.c
+++ b/arch/arm/mach-omap2/clock_common_data.c
@@ -16,6 +16,7 @@
  * OMAP3xxx clock definition files.
  */
 
+#include <linux/clk-private.h>
 #include "clock.h"
 
 /* clksel_rate data common to 24xx/343x */
@@ -52,6 +53,13 @@
 	{ .div = 0 },
 };
 
+const struct clksel_rate div3_1to4_rates[] = {
+	{ .div = 1, .val = 0, .flags = RATE_IN_4430 },
+	{ .div = 2, .val = 1, .flags = RATE_IN_4430 },
+	{ .div = 4, .val = 2, .flags = RATE_IN_4430 },
+	{ .div = 0 },
+};
+
 const struct clksel_rate div_1_1_rates[] = {
 	{ .div = 1, .val = 1, .flags = RATE_IN_4430 | RATE_IN_AM33XX },
 	{ .div = 0 },
@@ -109,14 +117,10 @@
 
 /* Clocks shared between various OMAP SoCs */
 
-struct clk virt_19200000_ck = {
-	.name		= "virt_19200000_ck",
-	.ops		= &clkops_null,
-	.rate		= 19200000,
-};
+static struct clk_ops dummy_ck_ops = {};
 
-struct clk virt_26000000_ck = {
-	.name		= "virt_26000000_ck",
-	.ops		= &clkops_null,
-	.rate		= 26000000,
+struct clk dummy_ck = {
+	.name = "dummy_clk",
+	.ops = &dummy_ck_ops,
+	.flags = CLK_IS_BASIC,
 };
diff --git a/arch/arm/mach-omap2/clockdomain.c b/arch/arm/mach-omap2/clockdomain.c
index 64e5046..3848735 100644
--- a/arch/arm/mach-omap2/clockdomain.c
+++ b/arch/arm/mach-omap2/clockdomain.c
@@ -22,6 +22,7 @@
 #include <linux/clk.h>
 #include <linux/limits.h>
 #include <linux/err.h>
+#include <linux/clk-provider.h>
 
 #include <linux/io.h>
 
@@ -947,35 +948,6 @@
 	return 0;
 }
 
-static int _clkdm_clk_hwmod_disable(struct clockdomain *clkdm)
-{
-	unsigned long flags;
-
-	if (!clkdm || !arch_clkdm || !arch_clkdm->clkdm_clk_disable)
-		return -EINVAL;
-
-	spin_lock_irqsave(&clkdm->lock, flags);
-
-	if (atomic_read(&clkdm->usecount) == 0) {
-		spin_unlock_irqrestore(&clkdm->lock, flags);
-		WARN_ON(1); /* underflow */
-		return -ERANGE;
-	}
-
-	if (atomic_dec_return(&clkdm->usecount) > 0) {
-		spin_unlock_irqrestore(&clkdm->lock, flags);
-		return 0;
-	}
-
-	arch_clkdm->clkdm_clk_disable(clkdm);
-	pwrdm_state_switch(clkdm->pwrdm.ptr);
-	spin_unlock_irqrestore(&clkdm->lock, flags);
-
-	pr_debug("clockdomain: %s: disabled\n", clkdm->name);
-
-	return 0;
-}
-
 /**
  * clkdm_clk_enable - add an enabled downstream clock to this clkdm
  * @clkdm: struct clockdomain *
@@ -1018,15 +990,37 @@
  */
 int clkdm_clk_disable(struct clockdomain *clkdm, struct clk *clk)
 {
-	/*
-	 * XXX Rewrite this code to maintain a list of enabled
-	 * downstream clocks for debugging purposes?
-	 */
+	unsigned long flags;
 
-	if (!clk)
+	if (!clkdm || !clk || !arch_clkdm || !arch_clkdm->clkdm_clk_disable)
 		return -EINVAL;
 
-	return _clkdm_clk_hwmod_disable(clkdm);
+	spin_lock_irqsave(&clkdm->lock, flags);
+
+	/* corner case: disabling unused clocks */
+	if (__clk_get_enable_count(clk) == 0)
+		goto ccd_exit;
+
+	if (atomic_read(&clkdm->usecount) == 0) {
+		spin_unlock_irqrestore(&clkdm->lock, flags);
+		WARN_ON(1); /* underflow */
+		return -ERANGE;
+	}
+
+	if (atomic_dec_return(&clkdm->usecount) > 0) {
+		spin_unlock_irqrestore(&clkdm->lock, flags);
+		return 0;
+	}
+
+	arch_clkdm->clkdm_clk_disable(clkdm);
+	pwrdm_state_switch(clkdm->pwrdm.ptr);
+
+	pr_debug("clockdomain: %s: disabled\n", clkdm->name);
+
+ccd_exit:
+	spin_unlock_irqrestore(&clkdm->lock, flags);
+
+	return 0;
 }
 
 /**
@@ -1077,6 +1071,8 @@
  */
 int clkdm_hwmod_disable(struct clockdomain *clkdm, struct omap_hwmod *oh)
 {
+	unsigned long flags;
+
 	/* The clkdm attribute does not exist yet prior OMAP4 */
 	if (cpu_is_omap24xx() || cpu_is_omap34xx())
 		return 0;
@@ -1086,9 +1082,28 @@
 	 * downstream hwmods for debugging purposes?
 	 */
 
-	if (!oh)
+	if (!clkdm || !oh || !arch_clkdm || !arch_clkdm->clkdm_clk_disable)
 		return -EINVAL;
 
-	return _clkdm_clk_hwmod_disable(clkdm);
+	spin_lock_irqsave(&clkdm->lock, flags);
+
+	if (atomic_read(&clkdm->usecount) == 0) {
+		spin_unlock_irqrestore(&clkdm->lock, flags);
+		WARN_ON(1); /* underflow */
+		return -ERANGE;
+	}
+
+	if (atomic_dec_return(&clkdm->usecount) > 0) {
+		spin_unlock_irqrestore(&clkdm->lock, flags);
+		return 0;
+	}
+
+	arch_clkdm->clkdm_clk_disable(clkdm);
+	pwrdm_state_switch(clkdm->pwrdm.ptr);
+	spin_unlock_irqrestore(&clkdm->lock, flags);
+
+	pr_debug("clockdomain: %s: disabled\n", clkdm->name);
+
+	return 0;
 }
 
diff --git a/arch/arm/mach-omap2/cm-regbits-24xx.h b/arch/arm/mach-omap2/cm-regbits-24xx.h
index 11eaf16..669ef51 100644
--- a/arch/arm/mach-omap2/cm-regbits-24xx.h
+++ b/arch/arm/mach-omap2/cm-regbits-24xx.h
@@ -59,6 +59,7 @@
 /* CM_CLKSEL_MPU */
 #define OMAP24XX_CLKSEL_MPU_SHIFT			0
 #define OMAP24XX_CLKSEL_MPU_MASK			(0x1f << 0)
+#define OMAP24XX_CLKSEL_MPU_WIDTH			5
 
 /* CM_CLKSTCTRL_MPU */
 #define OMAP24XX_AUTOSTATE_MPU_SHIFT			0
@@ -237,8 +238,10 @@
 #define OMAP24XX_CLKSEL_DSS1_MASK			(0x1f << 8)
 #define OMAP24XX_CLKSEL_L4_SHIFT			5
 #define OMAP24XX_CLKSEL_L4_MASK				(0x3 << 5)
+#define OMAP24XX_CLKSEL_L4_WIDTH			2
 #define OMAP24XX_CLKSEL_L3_SHIFT			0
 #define OMAP24XX_CLKSEL_L3_MASK				(0x1f << 0)
+#define OMAP24XX_CLKSEL_L3_WIDTH			5
 
 /* CM_CLKSEL2_CORE */
 #define OMAP24XX_CLKSEL_GPT12_SHIFT			22
@@ -363,8 +366,10 @@
 #define OMAP24XX_DPLL_DIV_MASK				(0xf << 8)
 #define OMAP24XX_54M_SOURCE_SHIFT			5
 #define OMAP24XX_54M_SOURCE_MASK			(1 << 5)
+#define OMAP24XX_54M_SOURCE_WIDTH			1
 #define OMAP2430_96M_SOURCE_SHIFT			4
 #define OMAP2430_96M_SOURCE_MASK			(1 << 4)
+#define OMAP2430_96M_SOURCE_WIDTH			1
 #define OMAP24XX_48M_SOURCE_SHIFT			3
 #define OMAP24XX_48M_SOURCE_MASK			(1 << 3)
 #define OMAP2430_ALTCLK_SOURCE_SHIFT			0
diff --git a/arch/arm/mach-omap2/cm-regbits-34xx.h b/arch/arm/mach-omap2/cm-regbits-34xx.h
index 59598ff..adf78d3 100644
--- a/arch/arm/mach-omap2/cm-regbits-34xx.h
+++ b/arch/arm/mach-omap2/cm-regbits-34xx.h
@@ -81,6 +81,7 @@
 /* CM_CLKSEL1_PLL_IVA2 */
 #define OMAP3430_IVA2_CLK_SRC_SHIFT			19
 #define OMAP3430_IVA2_CLK_SRC_MASK			(0x7 << 19)
+#define OMAP3430_IVA2_CLK_SRC_WIDTH			3
 #define OMAP3430_IVA2_DPLL_MULT_SHIFT			8
 #define OMAP3430_IVA2_DPLL_MULT_MASK			(0x7ff << 8)
 #define OMAP3430_IVA2_DPLL_DIV_SHIFT			0
@@ -89,6 +90,7 @@
 /* CM_CLKSEL2_PLL_IVA2 */
 #define OMAP3430_IVA2_DPLL_CLKOUT_DIV_SHIFT		0
 #define OMAP3430_IVA2_DPLL_CLKOUT_DIV_MASK		(0x1f << 0)
+#define OMAP3430_IVA2_DPLL_CLKOUT_DIV_WIDTH		5
 
 /* CM_CLKSTCTRL_IVA2 */
 #define OMAP3430_CLKTRCTRL_IVA2_SHIFT			0
@@ -118,6 +120,7 @@
 /* CM_IDLEST_PLL_MPU */
 #define OMAP3430_ST_MPU_CLK_SHIFT			0
 #define OMAP3430_ST_MPU_CLK_MASK			(1 << 0)
+#define OMAP3430_ST_MPU_CLK_WIDTH			1
 
 /* CM_AUTOIDLE_PLL_MPU */
 #define OMAP3430_AUTO_MPU_DPLL_SHIFT			0
@@ -126,6 +129,7 @@
 /* CM_CLKSEL1_PLL_MPU */
 #define OMAP3430_MPU_CLK_SRC_SHIFT			19
 #define OMAP3430_MPU_CLK_SRC_MASK			(0x7 << 19)
+#define OMAP3430_MPU_CLK_SRC_WIDTH			3
 #define OMAP3430_MPU_DPLL_MULT_SHIFT			8
 #define OMAP3430_MPU_DPLL_MULT_MASK			(0x7ff << 8)
 #define OMAP3430_MPU_DPLL_DIV_SHIFT			0
@@ -134,6 +138,7 @@
 /* CM_CLKSEL2_PLL_MPU */
 #define OMAP3430_MPU_DPLL_CLKOUT_DIV_SHIFT		0
 #define OMAP3430_MPU_DPLL_CLKOUT_DIV_MASK		(0x1f << 0)
+#define OMAP3430_MPU_DPLL_CLKOUT_DIV_WIDTH		5
 
 /* CM_CLKSTCTRL_MPU */
 #define OMAP3430_CLKTRCTRL_MPU_SHIFT			0
@@ -345,10 +350,13 @@
 #define OMAP3430ES1_CLKSEL_FSHOSTUSB_MASK		(0x3 << 4)
 #define OMAP3430_CLKSEL_L4_SHIFT			2
 #define OMAP3430_CLKSEL_L4_MASK				(0x3 << 2)
+#define OMAP3430_CLKSEL_L4_WIDTH			2
 #define OMAP3430_CLKSEL_L3_SHIFT			0
 #define OMAP3430_CLKSEL_L3_MASK				(0x3 << 0)
+#define OMAP3430_CLKSEL_L3_WIDTH			2
 #define OMAP3630_CLKSEL_96M_SHIFT			12
 #define OMAP3630_CLKSEL_96M_MASK			(0x3 << 12)
+#define OMAP3630_CLKSEL_96M_WIDTH			2
 
 /* CM_CLKSTCTRL_CORE */
 #define OMAP3430ES1_CLKTRCTRL_D2D_SHIFT			4
@@ -452,6 +460,7 @@
 #define OMAP3430ES2_CLKSEL_USIMOCP_MASK			(0xf << 3)
 #define OMAP3430_CLKSEL_RM_SHIFT			1
 #define OMAP3430_CLKSEL_RM_MASK				(0x3 << 1)
+#define OMAP3430_CLKSEL_RM_WIDTH			2
 #define OMAP3430_CLKSEL_GPT1_SHIFT			0
 #define OMAP3430_CLKSEL_GPT1_MASK			(1 << 0)
 
@@ -520,14 +529,17 @@
 /* Note that OMAP3430_CORE_DPLL_CLKOUT_DIV_MASK was (0x3 << 27) on 3430ES1 */
 #define OMAP3430_CORE_DPLL_CLKOUT_DIV_SHIFT		27
 #define OMAP3430_CORE_DPLL_CLKOUT_DIV_MASK		(0x1f << 27)
+#define OMAP3430_CORE_DPLL_CLKOUT_DIV_WIDTH		5
 #define OMAP3430_CORE_DPLL_MULT_SHIFT			16
 #define OMAP3430_CORE_DPLL_MULT_MASK			(0x7ff << 16)
 #define OMAP3430_CORE_DPLL_DIV_SHIFT			8
 #define OMAP3430_CORE_DPLL_DIV_MASK			(0x7f << 8)
 #define OMAP3430_SOURCE_96M_SHIFT			6
 #define OMAP3430_SOURCE_96M_MASK			(1 << 6)
+#define OMAP3430_SOURCE_96M_WIDTH			1
 #define OMAP3430_SOURCE_54M_SHIFT			5
 #define OMAP3430_SOURCE_54M_MASK			(1 << 5)
+#define OMAP3430_SOURCE_54M_WIDTH			1
 #define OMAP3430_SOURCE_48M_SHIFT			3
 #define OMAP3430_SOURCE_48M_MASK			(1 << 3)
 
@@ -545,7 +557,9 @@
 /* CM_CLKSEL3_PLL */
 #define OMAP3430_DIV_96M_SHIFT				0
 #define OMAP3430_DIV_96M_MASK				(0x1f << 0)
+#define OMAP3430_DIV_96M_WIDTH				5
 #define OMAP3630_DIV_96M_MASK				(0x3f << 0)
+#define OMAP3630_DIV_96M_WIDTH				6
 
 /* CM_CLKSEL4_PLL */
 #define OMAP3430ES2_PERIPH2_DPLL_MULT_SHIFT		8
@@ -556,12 +570,14 @@
 /* CM_CLKSEL5_PLL */
 #define OMAP3430ES2_DIV_120M_SHIFT			0
 #define OMAP3430ES2_DIV_120M_MASK			(0x1f << 0)
+#define OMAP3430ES2_DIV_120M_WIDTH			5
 
 /* CM_CLKOUT_CTRL */
 #define OMAP3430_CLKOUT2_EN_SHIFT			7
 #define OMAP3430_CLKOUT2_EN_MASK			(1 << 7)
 #define OMAP3430_CLKOUT2_DIV_SHIFT			3
 #define OMAP3430_CLKOUT2_DIV_MASK			(0x7 << 3)
+#define OMAP3430_CLKOUT2_DIV_WIDTH			3
 #define OMAP3430_CLKOUT2SOURCE_SHIFT			0
 #define OMAP3430_CLKOUT2SOURCE_MASK			(0x3 << 0)
 
@@ -592,10 +608,14 @@
 /* CM_CLKSEL_DSS */
 #define OMAP3430_CLKSEL_TV_SHIFT			8
 #define OMAP3430_CLKSEL_TV_MASK				(0x1f << 8)
+#define OMAP3430_CLKSEL_TV_WIDTH			5
 #define OMAP3630_CLKSEL_TV_MASK				(0x3f << 8)
+#define OMAP3630_CLKSEL_TV_WIDTH			6
 #define OMAP3430_CLKSEL_DSS1_SHIFT			0
 #define OMAP3430_CLKSEL_DSS1_MASK			(0x1f << 0)
+#define OMAP3430_CLKSEL_DSS1_WIDTH			5
 #define OMAP3630_CLKSEL_DSS1_MASK			(0x3f << 0)
+#define OMAP3630_CLKSEL_DSS1_WIDTH			6
 
 /* CM_SLEEPDEP_DSS specific bits */
 
@@ -623,7 +643,9 @@
 /* CM_CLKSEL_CAM */
 #define OMAP3430_CLKSEL_CAM_SHIFT			0
 #define OMAP3430_CLKSEL_CAM_MASK			(0x1f << 0)
+#define OMAP3430_CLKSEL_CAM_WIDTH			5
 #define OMAP3630_CLKSEL_CAM_MASK			(0x3f << 0)
+#define OMAP3630_CLKSEL_CAM_WIDTH			6
 
 /* CM_SLEEPDEP_CAM specific bits */
 
@@ -721,21 +743,30 @@
 /* CM_CLKSEL1_EMU */
 #define OMAP3430_DIV_DPLL4_SHIFT			24
 #define OMAP3430_DIV_DPLL4_MASK				(0x1f << 24)
+#define OMAP3430_DIV_DPLL4_WIDTH			5
 #define OMAP3630_DIV_DPLL4_MASK				(0x3f << 24)
+#define OMAP3630_DIV_DPLL4_WIDTH			6
 #define OMAP3430_DIV_DPLL3_SHIFT			16
 #define OMAP3430_DIV_DPLL3_MASK				(0x1f << 16)
+#define OMAP3430_DIV_DPLL3_WIDTH			5
 #define OMAP3430_CLKSEL_TRACECLK_SHIFT			11
 #define OMAP3430_CLKSEL_TRACECLK_MASK			(0x7 << 11)
+#define OMAP3430_CLKSEL_TRACECLK_WIDTH			3
 #define OMAP3430_CLKSEL_PCLK_SHIFT			8
 #define OMAP3430_CLKSEL_PCLK_MASK			(0x7 << 8)
+#define OMAP3430_CLKSEL_PCLK_WIDTH			3
 #define OMAP3430_CLKSEL_PCLKX2_SHIFT			6
 #define OMAP3430_CLKSEL_PCLKX2_MASK			(0x3 << 6)
+#define OMAP3430_CLKSEL_PCLKX2_WIDTH			2
 #define OMAP3430_CLKSEL_ATCLK_SHIFT			4
 #define OMAP3430_CLKSEL_ATCLK_MASK			(0x3 << 4)
+#define OMAP3430_CLKSEL_ATCLK_WIDTH			2
 #define OMAP3430_TRACE_MUX_CTRL_SHIFT			2
 #define OMAP3430_TRACE_MUX_CTRL_MASK			(0x3 << 2)
+#define OMAP3430_TRACE_MUX_CTRL_WIDTH			2
 #define OMAP3430_MUX_CTRL_SHIFT				0
 #define OMAP3430_MUX_CTRL_MASK				(0x3 << 0)
+#define OMAP3430_MUX_CTRL_WIDTH				2
 
 /* CM_CLKSTCTRL_EMU */
 #define OMAP3430_CLKTRCTRL_EMU_SHIFT			0
diff --git a/arch/arm/mach-omap2/cm2xxx_3xxx.h b/arch/arm/mach-omap2/cm2xxx_3xxx.h
index 98e6b3c..bfbd16f 100644
--- a/arch/arm/mach-omap2/cm2xxx_3xxx.h
+++ b/arch/arm/mach-omap2/cm2xxx_3xxx.h
@@ -108,6 +108,7 @@
 /* CM_CLKSEL_GFX */
 #define OMAP_CLKSEL_GFX_SHIFT				0
 #define OMAP_CLKSEL_GFX_MASK				(0x7 << 0)
+#define OMAP_CLKSEL_GFX_WIDTH				3
 
 /* CM_ICLKEN_GFX */
 #define OMAP_EN_GFX_SHIFT				0
diff --git a/arch/arm/mach-omap2/control.h b/arch/arm/mach-omap2/control.h
index 4ca8747..3d944d3 100644
--- a/arch/arm/mach-omap2/control.h
+++ b/arch/arm/mach-omap2/control.h
@@ -201,6 +201,7 @@
 #define OMAP44XX_CONTROL_FUSE_MPU_OPPNITRO	0x249
 #define OMAP44XX_CONTROL_FUSE_CORE_OPP50	0x254
 #define OMAP44XX_CONTROL_FUSE_CORE_OPP100	0x257
+#define OMAP44XX_CONTROL_FUSE_CORE_OPP100OV	0x25A
 
 /* AM35XX only CONTROL_GENERAL register offsets */
 #define AM35XX_CONTROL_MSUSPENDMUX_6    (OMAP2_CONTROL_GENERAL + 0x0038)
diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c
index 3cff7dc..c67a731 100644
--- a/arch/arm/mach-omap2/devices.c
+++ b/arch/arm/mach-omap2/devices.c
@@ -24,7 +24,7 @@
 #include <asm/mach-types.h>
 #include <asm/mach/map.h>
 
-#include <plat-omap/dma-omap.h>
+#include <linux/omap-dma.h>
 
 #include "iomap.h"
 #include "omap_hwmod.h"
diff --git a/arch/arm/mach-omap2/dma.c b/arch/arm/mach-omap2/dma.c
index e5aba58..612b982 100644
--- a/arch/arm/mach-omap2/dma.c
+++ b/arch/arm/mach-omap2/dma.c
@@ -28,7 +28,7 @@
 #include <linux/init.h>
 #include <linux/device.h>
 
-#include <plat-omap/dma-omap.h>
+#include <linux/omap-dma.h>
 
 #include "soc.h"
 #include "omap_hwmod.h"
diff --git a/arch/arm/mach-omap2/dpll3xxx.c b/arch/arm/mach-omap2/dpll3xxx.c
index eacf51f..fafb28c 100644
--- a/arch/arm/mach-omap2/dpll3xxx.c
+++ b/arch/arm/mach-omap2/dpll3xxx.c
@@ -29,6 +29,7 @@
 #include <linux/clkdev.h>
 
 #include "soc.h"
+#include "clockdomain.h"
 #include "clock.h"
 #include "cm2xxx_3xxx.h"
 #include "cm-regbits-34xx.h"
@@ -42,7 +43,7 @@
 /* Private functions */
 
 /* _omap3_dpll_write_clken - write clken_bits arg to a DPLL's enable bits */
-static void _omap3_dpll_write_clken(struct clk *clk, u8 clken_bits)
+static void _omap3_dpll_write_clken(struct clk_hw_omap *clk, u8 clken_bits)
 {
 	const struct dpll_data *dd;
 	u32 v;
@@ -56,7 +57,7 @@
 }
 
 /* _omap3_wait_dpll_status: wait for a DPLL to enter a specific state */
-static int _omap3_wait_dpll_status(struct clk *clk, u8 state)
+static int _omap3_wait_dpll_status(struct clk_hw_omap *clk, u8 state)
 {
 	const struct dpll_data *dd;
 	int i = 0;
@@ -64,7 +65,7 @@
 	const char *clk_name;
 
 	dd = clk->dpll_data;
-	clk_name = __clk_get_name(clk);
+	clk_name = __clk_get_name(clk->hw.clk);
 
 	state <<= __ffs(dd->idlest_mask);
 
@@ -88,7 +89,7 @@
 }
 
 /* From 3430 TRM ES2 4.7.6.2 */
-static u16 _omap3_dpll_compute_freqsel(struct clk *clk, u8 n)
+static u16 _omap3_dpll_compute_freqsel(struct clk_hw_omap *clk, u8 n)
 {
 	unsigned long fint;
 	u16 f = 0;
@@ -133,14 +134,14 @@
  * locked successfully, return 0; if the DPLL did not lock in the time
  * allotted, or DPLL3 was passed in, return -EINVAL.
  */
-static int _omap3_noncore_dpll_lock(struct clk *clk)
+static int _omap3_noncore_dpll_lock(struct clk_hw_omap *clk)
 {
 	const struct dpll_data *dd;
 	u8 ai;
 	u8 state = 1;
 	int r = 0;
 
-	pr_debug("clock: locking DPLL %s\n", __clk_get_name(clk));
+	pr_debug("clock: locking DPLL %s\n", __clk_get_name(clk->hw.clk));
 
 	dd = clk->dpll_data;
 	state <<= __ffs(dd->idlest_mask);
@@ -178,7 +179,7 @@
  * DPLL3 was passed in, or the DPLL does not support low-power bypass,
  * return -EINVAL.
  */
-static int _omap3_noncore_dpll_bypass(struct clk *clk)
+static int _omap3_noncore_dpll_bypass(struct clk_hw_omap *clk)
 {
 	int r;
 	u8 ai;
@@ -187,7 +188,7 @@
 		return -EINVAL;
 
 	pr_debug("clock: configuring DPLL %s for low-power bypass\n",
-		 __clk_get_name(clk));
+		 __clk_get_name(clk->hw.clk));
 
 	ai = omap3_dpll_autoidle_read(clk);
 
@@ -210,14 +211,14 @@
  * code.  If DPLL3 was passed in, or the DPLL does not support
  * low-power stop, return -EINVAL; otherwise, return 0.
  */
-static int _omap3_noncore_dpll_stop(struct clk *clk)
+static int _omap3_noncore_dpll_stop(struct clk_hw_omap *clk)
 {
 	u8 ai;
 
 	if (!(clk->dpll_data->modes & (1 << DPLL_LOW_POWER_STOP)))
 		return -EINVAL;
 
-	pr_debug("clock: stopping DPLL %s\n", __clk_get_name(clk));
+	pr_debug("clock: stopping DPLL %s\n", __clk_get_name(clk->hw.clk));
 
 	ai = omap3_dpll_autoidle_read(clk);
 
@@ -241,11 +242,11 @@
  * XXX This code is not needed for 3430/AM35xx; can it be optimized
  * out in non-multi-OMAP builds for those chips?
  */
-static void _lookup_dco(struct clk *clk, u8 *dco, u16 m, u8 n)
+static void _lookup_dco(struct clk_hw_omap *clk, u8 *dco, u16 m, u8 n)
 {
 	unsigned long fint, clkinp; /* watch out for overflow */
 
-	clkinp = __clk_get_rate(__clk_get_parent(clk));
+	clkinp = __clk_get_rate(__clk_get_parent(clk->hw.clk));
 	fint = (clkinp / n) * m;
 
 	if (fint < 1000000000)
@@ -266,12 +267,12 @@
  * XXX This code is not needed for 3430/AM35xx; can it be optimized
  * out in non-multi-OMAP builds for those chips?
  */
-static void _lookup_sddiv(struct clk *clk, u8 *sd_div, u16 m, u8 n)
+static void _lookup_sddiv(struct clk_hw_omap *clk, u8 *sd_div, u16 m, u8 n)
 {
 	unsigned long clkinp, sd; /* watch out for overflow */
 	int mod1, mod2;
 
-	clkinp = __clk_get_rate(__clk_get_parent(clk));
+	clkinp = __clk_get_rate(__clk_get_parent(clk->hw.clk));
 
 	/*
 	 * target sigma-delta to near 250MHz
@@ -298,7 +299,8 @@
  * Program the DPLL with the supplied M, N values, and wait for the DPLL to
  * lock..  Returns -EINVAL upon error, or 0 upon success.
  */
-static int omap3_noncore_dpll_program(struct clk *clk, u16 m, u8 n, u16 freqsel)
+static int omap3_noncore_dpll_program(struct clk_hw_omap *clk, u16 m, u8 n,
+				      u16 freqsel)
 {
 	struct dpll_data *dd = clk->dpll_data;
 	u8 dco, sd_div;
@@ -355,8 +357,10 @@
  *
  * Recalculate and propagate the DPLL rate.
  */
-unsigned long omap3_dpll_recalc(struct clk *clk)
+unsigned long omap3_dpll_recalc(struct clk_hw *hw, unsigned long parent_rate)
 {
+	struct clk_hw_omap *clk = to_clk_hw_omap(hw);
+
 	return omap2_get_dpll_rate(clk);
 }
 
@@ -376,8 +380,9 @@
  * support low-power stop, or if the DPLL took too long to enter
  * bypass or lock, return -EINVAL; otherwise, return 0.
  */
-int omap3_noncore_dpll_enable(struct clk *clk)
+int omap3_noncore_dpll_enable(struct clk_hw *hw)
 {
+	struct clk_hw_omap *clk = to_clk_hw_omap(hw);
 	int r;
 	struct dpll_data *dd;
 	struct clk *parent;
@@ -386,22 +391,26 @@
 	if (!dd)
 		return -EINVAL;
 
-	parent = __clk_get_parent(clk);
+	if (clk->clkdm) {
+		r = clkdm_clk_enable(clk->clkdm, hw->clk);
+		if (r) {
+			WARN(1,
+			     "%s: could not enable %s's clockdomain %s: %d\n",
+			     __func__, __clk_get_name(hw->clk),
+			     clk->clkdm->name, r);
+			return r;
+		}
+	}
 
-	if (__clk_get_rate(clk) == __clk_get_rate(dd->clk_bypass)) {
+	parent = __clk_get_parent(hw->clk);
+
+	if (__clk_get_rate(hw->clk) == __clk_get_rate(dd->clk_bypass)) {
 		WARN_ON(parent != dd->clk_bypass);
 		r = _omap3_noncore_dpll_bypass(clk);
 	} else {
 		WARN_ON(parent != dd->clk_ref);
 		r = _omap3_noncore_dpll_lock(clk);
 	}
-	/*
-	 *FIXME: this is dubious - if clk->rate has changed, what about
-	 * propagating?
-	 */
-	if (!r)
-		clk->rate = (clk->recalc) ? clk->recalc(clk) :
-			omap2_get_dpll_rate(clk);
 
 	return r;
 }
@@ -413,9 +422,13 @@
  * Instructs a non-CORE DPLL to enter low-power stop.  This function is
  * intended for use in struct clkops.  No return value.
  */
-void omap3_noncore_dpll_disable(struct clk *clk)
+void omap3_noncore_dpll_disable(struct clk_hw *hw)
 {
+	struct clk_hw_omap *clk = to_clk_hw_omap(hw);
+
 	_omap3_noncore_dpll_stop(clk);
+	if (clk->clkdm)
+		clkdm_clk_disable(clk->clkdm, hw->clk);
 }
 
 
@@ -432,80 +445,72 @@
  * target rate if it hasn't been done already, then program and lock
  * the DPLL.  Returns -EINVAL upon error, or 0 upon success.
  */
-int omap3_noncore_dpll_set_rate(struct clk *clk, unsigned long rate)
+int omap3_noncore_dpll_set_rate(struct clk_hw *hw, unsigned long rate,
+					unsigned long parent_rate)
 {
+	struct clk_hw_omap *clk = to_clk_hw_omap(hw);
 	struct clk *new_parent = NULL;
-	unsigned long hw_rate, bypass_rate;
 	u16 freqsel = 0;
 	struct dpll_data *dd;
 	int ret;
 
-	if (!clk || !rate)
+	if (!hw || !rate)
 		return -EINVAL;
 
 	dd = clk->dpll_data;
 	if (!dd)
 		return -EINVAL;
 
-	hw_rate = (clk->recalc) ? clk->recalc(clk) : omap2_get_dpll_rate(clk);
-	if (rate == hw_rate)
-		return 0;
+	__clk_prepare(dd->clk_bypass);
+	clk_enable(dd->clk_bypass);
+	__clk_prepare(dd->clk_ref);
+	clk_enable(dd->clk_ref);
 
-	/*
-	 * Ensure both the bypass and ref clocks are enabled prior to
-	 * doing anything; we need the bypass clock running to reprogram
-	 * the DPLL.
-	 */
-	omap2_clk_enable(dd->clk_bypass);
-	omap2_clk_enable(dd->clk_ref);
-
-	bypass_rate = __clk_get_rate(dd->clk_bypass);
-	if (bypass_rate == rate &&
-	    (clk->dpll_data->modes & (1 << DPLL_LOW_POWER_BYPASS))) {
-		pr_debug("clock: %s: set rate: entering bypass.\n", clk->name);
+	if (__clk_get_rate(dd->clk_bypass) == rate &&
+	    (dd->modes & (1 << DPLL_LOW_POWER_BYPASS))) {
+		pr_debug("%s: %s: set rate: entering bypass.\n",
+			 __func__, __clk_get_name(hw->clk));
 
 		ret = _omap3_noncore_dpll_bypass(clk);
 		if (!ret)
 			new_parent = dd->clk_bypass;
 	} else {
 		if (dd->last_rounded_rate != rate)
-			rate = clk->round_rate(clk, rate);
+			rate = __clk_round_rate(hw->clk, rate);
 
 		if (dd->last_rounded_rate == 0)
 			return -EINVAL;
 
 		/* No freqsel on OMAP4 and OMAP3630 */
-		if (!soc_is_am33xx() && !cpu_is_omap44xx() && !cpu_is_omap3630()) {
+		if (!cpu_is_omap44xx() && !cpu_is_omap3630()) {
 			freqsel = _omap3_dpll_compute_freqsel(clk,
 						dd->last_rounded_n);
 			if (!freqsel)
 				WARN_ON(1);
 		}
 
-		pr_debug("clock: %s: set rate: locking rate to %lu.\n",
-			 __clk_get_name(clk), rate);
+		pr_debug("%s: %s: set rate: locking rate to %lu.\n",
+			 __func__, __clk_get_name(hw->clk), rate);
 
 		ret = omap3_noncore_dpll_program(clk, dd->last_rounded_m,
-						 dd->last_rounded_n, freqsel);
+						dd->last_rounded_n, freqsel);
 		if (!ret)
 			new_parent = dd->clk_ref;
 	}
-	if (!ret) {
-		/*
-		 * Switch the parent clock in the hierarchy, and make sure
-		 * that the new parent's usecount is correct.  Note: we
-		 * enable the new parent before disabling the old to avoid
-		 * any unnecessary hardware disable->enable transitions.
-		 */
-		if (clk->usecount) {
-			omap2_clk_enable(new_parent);
-			omap2_clk_disable(clk->parent);
-		}
-		clk_reparent(clk, new_parent);
-		clk->rate = rate;
-	}
-	omap2_clk_disable(dd->clk_ref);
-	omap2_clk_disable(dd->clk_bypass);
+	/*
+	* FIXME - this is all wrong.  common code handles reparenting and
+	* migrating prepare/enable counts.  dplls should be a multiplexer
+	* clock and this should be a set_parent operation so that all of that
+	* stuff is inherited for free
+	*/
+
+	if (!ret)
+		__clk_reparent(hw->clk, new_parent);
+
+	clk_disable(dd->clk_ref);
+	__clk_unprepare(dd->clk_ref);
+	clk_disable(dd->clk_bypass);
+	__clk_unprepare(dd->clk_bypass);
 
 	return 0;
 }
@@ -520,7 +525,7 @@
  * -EINVAL if passed a null pointer or if the struct clk does not
  * appear to refer to a DPLL.
  */
-u32 omap3_dpll_autoidle_read(struct clk *clk)
+u32 omap3_dpll_autoidle_read(struct clk_hw_omap *clk)
 {
 	const struct dpll_data *dd;
 	u32 v;
@@ -549,7 +554,7 @@
  * OMAP3430.  The DPLL will enter low-power stop when its downstream
  * clocks are gated.  No return value.
  */
-void omap3_dpll_allow_idle(struct clk *clk)
+void omap3_dpll_allow_idle(struct clk_hw_omap *clk)
 {
 	const struct dpll_data *dd;
 	u32 v;
@@ -559,11 +564,8 @@
 
 	dd = clk->dpll_data;
 
-	if (!dd->autoidle_reg) {
-		pr_debug("clock: DPLL %s: autoidle not supported\n",
-			__clk_get_name(clk));
+	if (!dd->autoidle_reg)
 		return;
-	}
 
 	/*
 	 * REVISIT: CORE DPLL can optionally enter low-power bypass
@@ -583,7 +585,7 @@
  *
  * Disable DPLL automatic idle control.  No return value.
  */
-void omap3_dpll_deny_idle(struct clk *clk)
+void omap3_dpll_deny_idle(struct clk_hw_omap *clk)
 {
 	const struct dpll_data *dd;
 	u32 v;
@@ -593,11 +595,8 @@
 
 	dd = clk->dpll_data;
 
-	if (!dd->autoidle_reg) {
-		pr_debug("clock: DPLL %s: autoidle not supported\n",
-			__clk_get_name(clk));
+	if (!dd->autoidle_reg)
 		return;
-	}
 
 	v = __raw_readl(dd->autoidle_reg);
 	v &= ~dd->autoidle_mask;
@@ -615,18 +614,25 @@
  * Using parent clock DPLL data, look up DPLL state.  If locked, set our
  * rate to the dpll_clk * 2; otherwise, just use dpll_clk.
  */
-unsigned long omap3_clkoutx2_recalc(struct clk *clk)
+unsigned long omap3_clkoutx2_recalc(struct clk_hw *hw,
+				    unsigned long parent_rate)
 {
 	const struct dpll_data *dd;
 	unsigned long rate;
 	u32 v;
-	struct clk *pclk;
-	unsigned long parent_rate;
+	struct clk_hw_omap *pclk = NULL;
+	struct clk *parent;
 
 	/* Walk up the parents of clk, looking for a DPLL */
-	pclk = __clk_get_parent(clk);
-	while (pclk && !pclk->dpll_data)
-		pclk = __clk_get_parent(pclk);
+	do {
+		do {
+			parent = __clk_get_parent(hw->clk);
+			hw = __clk_get_hw(parent);
+		} while (hw && (__clk_get_flags(hw->clk) & CLK_IS_BASIC));
+		if (!hw)
+			break;
+		pclk = to_clk_hw_omap(hw);
+	} while (pclk && !pclk->dpll_data);
 
 	/* clk does not have a DPLL as a parent?  error in the clock data */
 	if (!pclk) {
@@ -638,7 +644,6 @@
 
 	WARN_ON(!dd->enable_mask);
 
-	parent_rate = __clk_get_rate(__clk_get_parent(clk));
 	v = __raw_readl(dd->control_reg) & dd->enable_mask;
 	v >>= __ffs(dd->enable_mask);
 	if ((v != OMAP3XXX_EN_DPLL_LOCKED) || (dd->flags & DPLL_J_TYPE))
@@ -649,15 +654,7 @@
 }
 
 /* OMAP3/4 non-CORE DPLL clkops */
-
-const struct clkops clkops_omap3_noncore_dpll_ops = {
-	.enable		= omap3_noncore_dpll_enable,
-	.disable	= omap3_noncore_dpll_disable,
-	.allow_idle	= omap3_dpll_allow_idle,
-	.deny_idle	= omap3_dpll_deny_idle,
-};
-
-const struct clkops clkops_omap3_core_dpll_ops = {
+const struct clk_hw_omap_ops clkhwops_omap3_dpll = {
 	.allow_idle	= omap3_dpll_allow_idle,
 	.deny_idle	= omap3_dpll_deny_idle,
 };
diff --git a/arch/arm/mach-omap2/dpll44xx.c b/arch/arm/mach-omap2/dpll44xx.c
index 5854da1..d3326c4 100644
--- a/arch/arm/mach-omap2/dpll44xx.c
+++ b/arch/arm/mach-omap2/dpll44xx.c
@@ -21,7 +21,7 @@
 #include "cm-regbits-44xx.h"
 
 /* Supported only on OMAP4 */
-int omap4_dpllmx_gatectrl_read(struct clk *clk)
+int omap4_dpllmx_gatectrl_read(struct clk_hw_omap *clk)
 {
 	u32 v;
 	u32 mask;
@@ -40,7 +40,7 @@
 	return v;
 }
 
-void omap4_dpllmx_allow_gatectrl(struct clk *clk)
+void omap4_dpllmx_allow_gatectrl(struct clk_hw_omap *clk)
 {
 	u32 v;
 	u32 mask;
@@ -58,7 +58,7 @@
 	__raw_writel(v, clk->clksel_reg);
 }
 
-void omap4_dpllmx_deny_gatectrl(struct clk *clk)
+void omap4_dpllmx_deny_gatectrl(struct clk_hw_omap *clk)
 {
 	u32 v;
 	u32 mask;
@@ -76,9 +76,9 @@
 	__raw_writel(v, clk->clksel_reg);
 }
 
-const struct clkops clkops_omap4_dpllmx_ops = {
+const struct clk_hw_omap_ops clkhwops_omap4_dpllmx = {
 	.allow_idle	= omap4_dpllmx_allow_gatectrl,
-	.deny_idle	= omap4_dpllmx_deny_gatectrl,
+	.deny_idle      = omap4_dpllmx_deny_gatectrl,
 };
 
 /**
@@ -90,8 +90,10 @@
  * OMAP4 ABE DPLL.  Returns the DPLL's output rate (before M-dividers)
  * upon success, or 0 upon error.
  */
-unsigned long omap4_dpll_regm4xen_recalc(struct clk *clk)
+unsigned long omap4_dpll_regm4xen_recalc(struct clk_hw *hw,
+			unsigned long parent_rate)
 {
+	struct clk_hw_omap *clk = to_clk_hw_omap(hw);
 	u32 v;
 	unsigned long rate;
 	struct dpll_data *dd;
@@ -123,8 +125,11 @@
  * M-dividers) upon success, -EINVAL if @clk is null or not a DPLL, or
  * ~0 if an error occurred in omap2_dpll_round_rate().
  */
-long omap4_dpll_regm4xen_round_rate(struct clk *clk, unsigned long target_rate)
+long omap4_dpll_regm4xen_round_rate(struct clk_hw *hw,
+				    unsigned long target_rate,
+				    unsigned long *parent_rate)
 {
+	struct clk_hw_omap *clk = to_clk_hw_omap(hw);
 	u32 v;
 	struct dpll_data *dd;
 	long r;
@@ -140,7 +145,7 @@
 	if (v)
 		target_rate = target_rate / OMAP4430_REGM4XEN_MULT;
 
-	r = omap2_dpll_round_rate(clk, target_rate);
+	r = omap2_dpll_round_rate(hw, target_rate, NULL);
 	if (r == ~0)
 		return r;
 
diff --git a/arch/arm/mach-omap2/gpmc-nand.c b/arch/arm/mach-omap2/gpmc-nand.c
index 8607735..db969a5 100644
--- a/arch/arm/mach-omap2/gpmc-nand.c
+++ b/arch/arm/mach-omap2/gpmc-nand.c
@@ -52,27 +52,27 @@
 
 	memset(&t, 0, sizeof(t));
 	t.sync_clk = gpmc_t->sync_clk;
-	t.cs_on = gpmc_round_ns_to_ticks(gpmc_t->cs_on);
-	t.adv_on = gpmc_round_ns_to_ticks(gpmc_t->adv_on);
+	t.cs_on = gpmc_t->cs_on;
+	t.adv_on = gpmc_t->adv_on;
 
 	/* Read */
-	t.adv_rd_off = gpmc_round_ns_to_ticks(gpmc_t->adv_rd_off);
+	t.adv_rd_off = gpmc_t->adv_rd_off;
 	t.oe_on  = t.adv_on;
-	t.access = gpmc_round_ns_to_ticks(gpmc_t->access);
-	t.oe_off = gpmc_round_ns_to_ticks(gpmc_t->oe_off);
-	t.cs_rd_off = gpmc_round_ns_to_ticks(gpmc_t->cs_rd_off);
-	t.rd_cycle  = gpmc_round_ns_to_ticks(gpmc_t->rd_cycle);
+	t.access = gpmc_t->access;
+	t.oe_off = gpmc_t->oe_off;
+	t.cs_rd_off = gpmc_t->cs_rd_off;
+	t.rd_cycle = gpmc_t->rd_cycle;
 
 	/* Write */
-	t.adv_wr_off = gpmc_round_ns_to_ticks(gpmc_t->adv_wr_off);
+	t.adv_wr_off = gpmc_t->adv_wr_off;
 	t.we_on  = t.oe_on;
 	if (cpu_is_omap34xx()) {
-	    t.wr_data_mux_bus =	gpmc_round_ns_to_ticks(gpmc_t->wr_data_mux_bus);
-	    t.wr_access = gpmc_round_ns_to_ticks(gpmc_t->wr_access);
+		t.wr_data_mux_bus = gpmc_t->wr_data_mux_bus;
+		t.wr_access = gpmc_t->wr_access;
 	}
-	t.we_off = gpmc_round_ns_to_ticks(gpmc_t->we_off);
-	t.cs_wr_off = gpmc_round_ns_to_ticks(gpmc_t->cs_wr_off);
-	t.wr_cycle  = gpmc_round_ns_to_ticks(gpmc_t->wr_cycle);
+	t.we_off = gpmc_t->we_off;
+	t.cs_wr_off = gpmc_t->cs_wr_off;
+	t.wr_cycle = gpmc_t->wr_cycle;
 
 	/* Configure GPMC */
 	if (gpmc_nand_data->devsize == NAND_BUSWIDTH_16)
diff --git a/arch/arm/mach-omap2/gpmc-onenand.c b/arch/arm/mach-omap2/gpmc-onenand.c
index d102183..94a349e 100644
--- a/arch/arm/mach-omap2/gpmc-onenand.c
+++ b/arch/arm/mach-omap2/gpmc-onenand.c
@@ -33,7 +33,6 @@
 
 static unsigned onenand_flags;
 static unsigned latency;
-static int fclk_offset;
 
 static struct omap_onenand_platform_data *gpmc_onenand_data;
 
@@ -50,6 +49,7 @@
 
 static struct gpmc_timings omap2_onenand_calc_async_timings(void)
 {
+	struct gpmc_device_timings dev_t;
 	struct gpmc_timings t;
 
 	const int t_cer = 15;
@@ -59,35 +59,24 @@
 	const int t_aa = 76;
 	const int t_oe = 20;
 	const int t_cez = 20; /* max of t_cez, t_oez */
-	const int t_ds = 30;
 	const int t_wpl = 40;
 	const int t_wph = 30;
 
-	memset(&t, 0, sizeof(t));
-	t.sync_clk = 0;
-	t.cs_on = 0;
-	t.adv_on = 0;
+	memset(&dev_t, 0, sizeof(dev_t));
 
-	/* Read */
-	t.adv_rd_off = gpmc_round_ns_to_ticks(max_t(int, t_avdp, t_cer));
-	t.oe_on  = t.adv_rd_off + gpmc_round_ns_to_ticks(t_aavdh);
-	t.access = t.adv_on + gpmc_round_ns_to_ticks(t_aa);
-	t.access = max_t(int, t.access, t.cs_on + gpmc_round_ns_to_ticks(t_ce));
-	t.access = max_t(int, t.access, t.oe_on + gpmc_round_ns_to_ticks(t_oe));
-	t.oe_off = t.access + gpmc_round_ns_to_ticks(1);
-	t.cs_rd_off = t.oe_off;
-	t.rd_cycle  = t.cs_rd_off + gpmc_round_ns_to_ticks(t_cez);
+	dev_t.mux = true;
+	dev_t.t_avdp_r = max_t(int, t_avdp, t_cer) * 1000;
+	dev_t.t_avdp_w = dev_t.t_avdp_r;
+	dev_t.t_aavdh = t_aavdh * 1000;
+	dev_t.t_aa = t_aa * 1000;
+	dev_t.t_ce = t_ce * 1000;
+	dev_t.t_oe = t_oe * 1000;
+	dev_t.t_cez_r = t_cez * 1000;
+	dev_t.t_cez_w = dev_t.t_cez_r;
+	dev_t.t_wpl = t_wpl * 1000;
+	dev_t.t_wph = t_wph * 1000;
 
-	/* Write */
-	t.adv_wr_off = t.adv_rd_off;
-	t.we_on  = t.oe_on;
-	if (cpu_is_omap34xx()) {
-		t.wr_data_mux_bus = t.we_on;
-		t.wr_access = t.we_on + gpmc_round_ns_to_ticks(t_ds);
-	}
-	t.we_off = t.we_on + gpmc_round_ns_to_ticks(t_wpl);
-	t.cs_wr_off = t.we_off + gpmc_round_ns_to_ticks(t_wph);
-	t.wr_cycle  = t.cs_wr_off + gpmc_round_ns_to_ticks(t_cez);
+	gpmc_calc_timings(&t, &dev_t);
 
 	return t;
 }
@@ -173,18 +162,15 @@
 omap2_onenand_calc_sync_timings(struct omap_onenand_platform_data *cfg,
 				int freq)
 {
+	struct gpmc_device_timings dev_t;
 	struct gpmc_timings t;
 	const int t_cer  = 15;
 	const int t_avdp = 12;
 	const int t_cez  = 20; /* max of t_cez, t_oez */
-	const int t_ds   = 30;
 	const int t_wpl  = 40;
 	const int t_wph  = 30;
 	int min_gpmc_clk_period, t_ces, t_avds, t_avdh, t_ach, t_aavdh, t_rdyo;
-	u32 reg;
-	int div, fclk_offset_ns, gpmc_clk_ns;
-	int ticks_cez;
-	int cs = cfg->cs;
+	int div, gpmc_clk_ns;
 
 	if (cfg->flags & ONENAND_SYNC_READ)
 		onenand_flags = ONENAND_FLAG_SYNCREAD;
@@ -251,77 +237,35 @@
 		latency = 4;
 
 	/* Set synchronous read timings */
-	memset(&t, 0, sizeof(t));
+	memset(&dev_t, 0, sizeof(dev_t));
 
-	if (div == 1) {
-		reg = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG2);
-		reg |= (1 << 7);
-		gpmc_cs_write_reg(cs, GPMC_CS_CONFIG2, reg);
-		reg = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG3);
-		reg |= (1 << 7);
-		gpmc_cs_write_reg(cs, GPMC_CS_CONFIG3, reg);
-		reg = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG4);
-		reg |= (1 << 7);
-		reg |= (1 << 23);
-		gpmc_cs_write_reg(cs, GPMC_CS_CONFIG4, reg);
-	} else {
-		reg = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG2);
-		reg &= ~(1 << 7);
-		gpmc_cs_write_reg(cs, GPMC_CS_CONFIG2, reg);
-		reg = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG3);
-		reg &= ~(1 << 7);
-		gpmc_cs_write_reg(cs, GPMC_CS_CONFIG3, reg);
-		reg = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG4);
-		reg &= ~(1 << 7);
-		reg &= ~(1 << 23);
-		gpmc_cs_write_reg(cs, GPMC_CS_CONFIG4, reg);
-	}
-
-	t.sync_clk = min_gpmc_clk_period;
-	t.cs_on = 0;
-	t.adv_on = 0;
-	fclk_offset_ns = gpmc_round_ns_to_ticks(max_t(int, t_ces, t_avds));
-	fclk_offset = gpmc_ns_to_ticks(fclk_offset_ns);
-	t.page_burst_access = gpmc_clk_ns;
-
-	/* Read */
-	t.adv_rd_off = gpmc_ticks_to_ns(fclk_offset + gpmc_ns_to_ticks(t_avdh));
-	t.oe_on = gpmc_ticks_to_ns(fclk_offset + gpmc_ns_to_ticks(t_ach));
-	/* Force at least 1 clk between AVD High to OE Low */
-	if (t.oe_on <= t.adv_rd_off)
-		t.oe_on = t.adv_rd_off + gpmc_round_ns_to_ticks(1);
-	t.access = gpmc_ticks_to_ns(fclk_offset + (latency + 1) * div);
-	t.oe_off = t.access + gpmc_round_ns_to_ticks(1);
-	t.cs_rd_off = t.oe_off;
-	ticks_cez = ((gpmc_ns_to_ticks(t_cez) + div - 1) / div) * div;
-	t.rd_cycle = gpmc_ticks_to_ns(fclk_offset + (latency + 1) * div +
-		     ticks_cez);
-
-	/* Write */
+	dev_t.mux = true;
+	dev_t.sync_read = true;
 	if (onenand_flags & ONENAND_FLAG_SYNCWRITE) {
-		t.adv_wr_off = t.adv_rd_off;
-		t.we_on  = 0;
-		t.we_off = t.cs_rd_off;
-		t.cs_wr_off = t.cs_rd_off;
-		t.wr_cycle  = t.rd_cycle;
-		if (cpu_is_omap34xx()) {
-			t.wr_data_mux_bus = gpmc_ticks_to_ns(fclk_offset +
-					gpmc_ps_to_ticks(min_gpmc_clk_period +
-					t_rdyo * 1000));
-			t.wr_access = t.access;
-		}
+		dev_t.sync_write = true;
 	} else {
-		t.adv_wr_off = gpmc_round_ns_to_ticks(max_t(int,
-							t_avdp, t_cer));
-		t.we_on  = t.adv_wr_off + gpmc_round_ns_to_ticks(t_aavdh);
-		t.we_off = t.we_on + gpmc_round_ns_to_ticks(t_wpl);
-		t.cs_wr_off = t.we_off + gpmc_round_ns_to_ticks(t_wph);
-		t.wr_cycle  = t.cs_wr_off + gpmc_round_ns_to_ticks(t_cez);
-		if (cpu_is_omap34xx()) {
-			t.wr_data_mux_bus = t.we_on;
-			t.wr_access = t.we_on + gpmc_round_ns_to_ticks(t_ds);
-		}
+		dev_t.t_avdp_w = max(t_avdp, t_cer) * 1000;
+		dev_t.t_wpl = t_wpl * 1000;
+		dev_t.t_wph = t_wph * 1000;
+		dev_t.t_aavdh = t_aavdh * 1000;
 	}
+	dev_t.ce_xdelay = true;
+	dev_t.avd_xdelay = true;
+	dev_t.oe_xdelay = true;
+	dev_t.we_xdelay = true;
+	dev_t.clk = min_gpmc_clk_period;
+	dev_t.t_bacc = dev_t.clk;
+	dev_t.t_ces = t_ces * 1000;
+	dev_t.t_avds = t_avds * 1000;
+	dev_t.t_avdh = t_avdh * 1000;
+	dev_t.t_ach = t_ach * 1000;
+	dev_t.cyc_iaa = (latency + 1);
+	dev_t.t_cez_r = t_cez * 1000;
+	dev_t.t_cez_w = dev_t.t_cez_r;
+	dev_t.cyc_aavdh_oe = 1;
+	dev_t.t_rdyo = t_rdyo * 1000 + min_gpmc_clk_period;
+
+	gpmc_calc_timings(&t, &dev_t);
 
 	return t;
 }
@@ -338,7 +282,6 @@
 			  (sync_read ? GPMC_CONFIG1_READTYPE_SYNC : 0) |
 			  (sync_write ? GPMC_CONFIG1_WRITEMULTIPLE_SUPP : 0) |
 			  (sync_write ? GPMC_CONFIG1_WRITETYPE_SYNC : 0) |
-			  GPMC_CONFIG1_CLKACTIVATIONTIME(fclk_offset) |
 			  GPMC_CONFIG1_PAGE_LEN(2) |
 			  (cpu_is_omap34xx() ? 0 :
 				(GPMC_CONFIG1_WAIT_READ_MON |
diff --git a/arch/arm/mach-omap2/gpmc-smc91x.c b/arch/arm/mach-omap2/gpmc-smc91x.c
index 6eed907..11d0b75 100644
--- a/arch/arm/mach-omap2/gpmc-smc91x.c
+++ b/arch/arm/mach-omap2/gpmc-smc91x.c
@@ -58,6 +58,7 @@
 static int smc91c96_gpmc_retime(void)
 {
 	struct gpmc_timings t;
+	struct gpmc_device_timings dev_t;
 	const int t3 = 10;	/* Figure 12.2 read and 12.4 write */
 	const int t4_r = 20;	/* Figure 12.2 read */
 	const int t4_w = 5;	/* Figure 12.4 write */
@@ -68,32 +69,6 @@
 	const int t20 = 185;	/* Figure 12.2 read and 12.4 write */
 	u32 l;
 
-	memset(&t, 0, sizeof(t));
-
-	/* Read timings */
-	t.cs_on = 0;
-	t.adv_on = t.cs_on;
-	t.oe_on = t.adv_on + t3;
-	t.access = t.oe_on + t5;
-	t.oe_off = t.access;
-	t.adv_rd_off = t.oe_off + max(t4_r, t6);
-	t.cs_rd_off = t.oe_off;
-	t.rd_cycle = t20 - t.oe_on;
-
-	/* Write timings */
-	t.we_on = t.adv_on + t3;
-
-	if (cpu_is_omap34xx() && (gpmc_cfg->flags & GPMC_MUX_ADD_DATA)) {
-		t.wr_data_mux_bus = t.we_on;
-		t.we_off = t.wr_data_mux_bus + t7;
-	} else
-		t.we_off = t.we_on + t7;
-	if (cpu_is_omap34xx())
-		t.wr_access = t.we_off;
-	t.adv_wr_off = t.we_off + max(t4_w, t8);
-	t.cs_wr_off = t.we_off + t4_w;
-	t.wr_cycle = t20 - t.we_on;
-
 	l = GPMC_CONFIG1_DEVICESIZE_16;
 	if (gpmc_cfg->flags & GPMC_MUX_ADD_DATA)
 		l |= GPMC_CONFIG1_MUXADDDATA;
@@ -115,6 +90,22 @@
 	if (gpmc_cfg->flags & GPMC_MUX_ADD_DATA)
 		return 0;
 
+	memset(&dev_t, 0, sizeof(dev_t));
+
+	dev_t.t_oeasu = t3 * 1000;
+	dev_t.t_oe = t5 * 1000;
+	dev_t.t_cez_r = t4_r * 1000;
+	dev_t.t_oez = t6 * 1000;
+	dev_t.t_rd_cycle = (t20 - t3) * 1000;
+
+	dev_t.t_weasu = t3 * 1000;
+	dev_t.t_wpl = t7 * 1000;
+	dev_t.t_wph = t8 * 1000;
+	dev_t.t_cez_w = t4_w * 1000;
+	dev_t.t_wr_cycle = (t20 - t3) * 1000;
+
+	gpmc_calc_timings(&t, &dev_t);
+
 	return gpmc_cs_set_timings(gpmc_cfg->cs, &t);
 }
 
diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index bf6117c..65468f6 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -74,6 +74,13 @@
 #define GPMC_ECC_CTRL_ECCREG8		0x008
 #define GPMC_ECC_CTRL_ECCREG9		0x009
 
+#define	GPMC_CONFIG2_CSEXTRADELAY		BIT(7)
+#define	GPMC_CONFIG3_ADVEXTRADELAY		BIT(7)
+#define	GPMC_CONFIG4_OEEXTRADELAY		BIT(7)
+#define	GPMC_CONFIG4_WEEXTRADELAY		BIT(23)
+#define	GPMC_CONFIG6_CYCLE2CYCLEDIFFCSEN	BIT(6)
+#define	GPMC_CONFIG6_CYCLE2CYCLESAMECSEN	BIT(7)
+
 #define GPMC_CS0_OFFSET		0x60
 #define GPMC_CS_SIZE		0x30
 #define	GPMC_BCH_SIZE		0x10
@@ -223,6 +230,51 @@
 	return ticks * gpmc_get_fclk_period() / 1000;
 }
 
+static unsigned int gpmc_ticks_to_ps(unsigned int ticks)
+{
+	return ticks * gpmc_get_fclk_period();
+}
+
+static unsigned int gpmc_round_ps_to_ticks(unsigned int time_ps)
+{
+	unsigned long ticks = gpmc_ps_to_ticks(time_ps);
+
+	return ticks * gpmc_get_fclk_period();
+}
+
+static inline void gpmc_cs_modify_reg(int cs, int reg, u32 mask, bool value)
+{
+	u32 l;
+
+	l = gpmc_cs_read_reg(cs, reg);
+	if (value)
+		l |= mask;
+	else
+		l &= ~mask;
+	gpmc_cs_write_reg(cs, reg, l);
+}
+
+static void gpmc_cs_bool_timings(int cs, const struct gpmc_bool_timings *p)
+{
+	gpmc_cs_modify_reg(cs, GPMC_CS_CONFIG1,
+			   GPMC_CONFIG1_TIME_PARA_GRAN,
+			   p->time_para_granularity);
+	gpmc_cs_modify_reg(cs, GPMC_CS_CONFIG2,
+			   GPMC_CONFIG2_CSEXTRADELAY, p->cs_extra_delay);
+	gpmc_cs_modify_reg(cs, GPMC_CS_CONFIG3,
+			   GPMC_CONFIG3_ADVEXTRADELAY, p->adv_extra_delay);
+	gpmc_cs_modify_reg(cs, GPMC_CS_CONFIG4,
+			   GPMC_CONFIG4_OEEXTRADELAY, p->oe_extra_delay);
+	gpmc_cs_modify_reg(cs, GPMC_CS_CONFIG4,
+			   GPMC_CONFIG4_OEEXTRADELAY, p->we_extra_delay);
+	gpmc_cs_modify_reg(cs, GPMC_CS_CONFIG6,
+			   GPMC_CONFIG6_CYCLE2CYCLESAMECSEN,
+			   p->cycle2cyclesamecsen);
+	gpmc_cs_modify_reg(cs, GPMC_CS_CONFIG6,
+			   GPMC_CONFIG6_CYCLE2CYCLEDIFFCSEN,
+			   p->cycle2cyclediffcsen);
+}
+
 #ifdef DEBUG
 static int set_gpmc_timing_reg(int cs, int reg, int st_bit, int end_bit,
 			       int time, const char *name)
@@ -316,6 +368,12 @@
 
 	GPMC_SET_ONE(GPMC_CS_CONFIG5, 24, 27, page_burst_access);
 
+	GPMC_SET_ONE(GPMC_CS_CONFIG6, 0, 3, bus_turnaround);
+	GPMC_SET_ONE(GPMC_CS_CONFIG6, 8, 11, cycle2cycle_delay);
+
+	GPMC_SET_ONE(GPMC_CS_CONFIG1, 18, 19, wait_monitoring);
+	GPMC_SET_ONE(GPMC_CS_CONFIG1, 25, 26, clk_activation);
+
 	if (gpmc_capability & GPMC_HAS_WR_DATA_MUX_BUS)
 		GPMC_SET_ONE(GPMC_CS_CONFIG6, 16, 19, wr_data_mux_bus);
 	if (gpmc_capability & GPMC_HAS_WR_ACCESS)
@@ -335,6 +393,8 @@
 		gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1, l);
 	}
 
+	gpmc_cs_bool_timings(cs, &t->bool_timings);
+
 	return 0;
 }
 
@@ -748,6 +808,319 @@
 	return 0;
 }
 
+static u32 gpmc_round_ps_to_sync_clk(u32 time_ps, u32 sync_clk)
+{
+	u32 temp;
+	int div;
+
+	div = gpmc_calc_divider(sync_clk);
+	temp = gpmc_ps_to_ticks(time_ps);
+	temp = (temp + div - 1) / div;
+	return gpmc_ticks_to_ps(temp * div);
+}
+
+/* XXX: can the cycles be avoided ? */
+static int gpmc_calc_sync_read_timings(struct gpmc_timings *gpmc_t,
+				struct gpmc_device_timings *dev_t)
+{
+	bool mux = dev_t->mux;
+	u32 temp;
+
+	/* adv_rd_off */
+	temp = dev_t->t_avdp_r;
+	/* XXX: mux check required ? */
+	if (mux) {
+		/* XXX: t_avdp not to be required for sync, only added for tusb
+		 * this indirectly necessitates requirement of t_avdp_r and
+		 * t_avdp_w instead of having a single t_avdp
+		 */
+		temp = max_t(u32, temp,	gpmc_t->clk_activation + dev_t->t_avdh);
+		temp = max_t(u32, gpmc_t->adv_on + gpmc_ticks_to_ps(1), temp);
+	}
+	gpmc_t->adv_rd_off = gpmc_round_ps_to_ticks(temp);
+
+	/* oe_on */
+	temp = dev_t->t_oeasu; /* XXX: remove this ? */
+	if (mux) {
+		temp = max_t(u32, temp,	gpmc_t->clk_activation + dev_t->t_ach);
+		temp = max_t(u32, temp, gpmc_t->adv_rd_off +
+				gpmc_ticks_to_ps(dev_t->cyc_aavdh_oe));
+	}
+	gpmc_t->oe_on = gpmc_round_ps_to_ticks(temp);
+
+	/* access */
+	/* XXX: any scope for improvement ?, by combining oe_on
+	 * and clk_activation, need to check whether
+	 * access = clk_activation + round to sync clk ?
+	 */
+	temp = max_t(u32, dev_t->t_iaa,	dev_t->cyc_iaa * gpmc_t->sync_clk);
+	temp += gpmc_t->clk_activation;
+	if (dev_t->cyc_oe)
+		temp = max_t(u32, temp, gpmc_t->oe_on +
+				gpmc_ticks_to_ps(dev_t->cyc_oe));
+	gpmc_t->access = gpmc_round_ps_to_ticks(temp);
+
+	gpmc_t->oe_off = gpmc_t->access + gpmc_ticks_to_ps(1);
+	gpmc_t->cs_rd_off = gpmc_t->oe_off;
+
+	/* rd_cycle */
+	temp = max_t(u32, dev_t->t_cez_r, dev_t->t_oez);
+	temp = gpmc_round_ps_to_sync_clk(temp, gpmc_t->sync_clk) +
+							gpmc_t->access;
+	/* XXX: barter t_ce_rdyz with t_cez_r ? */
+	if (dev_t->t_ce_rdyz)
+		temp = max_t(u32, temp,	gpmc_t->cs_rd_off + dev_t->t_ce_rdyz);
+	gpmc_t->rd_cycle = gpmc_round_ps_to_ticks(temp);
+
+	return 0;
+}
+
+static int gpmc_calc_sync_write_timings(struct gpmc_timings *gpmc_t,
+				struct gpmc_device_timings *dev_t)
+{
+	bool mux = dev_t->mux;
+	u32 temp;
+
+	/* adv_wr_off */
+	temp = dev_t->t_avdp_w;
+	if (mux) {
+		temp = max_t(u32, temp,
+			gpmc_t->clk_activation + dev_t->t_avdh);
+		temp = max_t(u32, gpmc_t->adv_on + gpmc_ticks_to_ps(1), temp);
+	}
+	gpmc_t->adv_wr_off = gpmc_round_ps_to_ticks(temp);
+
+	/* wr_data_mux_bus */
+	temp = max_t(u32, dev_t->t_weasu,
+			gpmc_t->clk_activation + dev_t->t_rdyo);
+	/* XXX: shouldn't mux be kept as a whole for wr_data_mux_bus ?,
+	 * and in that case remember to handle we_on properly
+	 */
+	if (mux) {
+		temp = max_t(u32, temp,
+			gpmc_t->adv_wr_off + dev_t->t_aavdh);
+		temp = max_t(u32, temp, gpmc_t->adv_wr_off +
+				gpmc_ticks_to_ps(dev_t->cyc_aavdh_we));
+	}
+	gpmc_t->wr_data_mux_bus = gpmc_round_ps_to_ticks(temp);
+
+	/* we_on */
+	if (gpmc_capability & GPMC_HAS_WR_DATA_MUX_BUS)
+		gpmc_t->we_on = gpmc_round_ps_to_ticks(dev_t->t_weasu);
+	else
+		gpmc_t->we_on = gpmc_t->wr_data_mux_bus;
+
+	/* wr_access */
+	/* XXX: gpmc_capability check reqd ? , even if not, will not harm */
+	gpmc_t->wr_access = gpmc_t->access;
+
+	/* we_off */
+	temp = gpmc_t->we_on + dev_t->t_wpl;
+	temp = max_t(u32, temp,
+			gpmc_t->wr_access + gpmc_ticks_to_ps(1));
+	temp = max_t(u32, temp,
+		gpmc_t->we_on + gpmc_ticks_to_ps(dev_t->cyc_wpl));
+	gpmc_t->we_off = gpmc_round_ps_to_ticks(temp);
+
+	gpmc_t->cs_wr_off = gpmc_round_ps_to_ticks(gpmc_t->we_off +
+							dev_t->t_wph);
+
+	/* wr_cycle */
+	temp = gpmc_round_ps_to_sync_clk(dev_t->t_cez_w, gpmc_t->sync_clk);
+	temp += gpmc_t->wr_access;
+	/* XXX: barter t_ce_rdyz with t_cez_w ? */
+	if (dev_t->t_ce_rdyz)
+		temp = max_t(u32, temp,
+				 gpmc_t->cs_wr_off + dev_t->t_ce_rdyz);
+	gpmc_t->wr_cycle = gpmc_round_ps_to_ticks(temp);
+
+	return 0;
+}
+
+static int gpmc_calc_async_read_timings(struct gpmc_timings *gpmc_t,
+				struct gpmc_device_timings *dev_t)
+{
+	bool mux = dev_t->mux;
+	u32 temp;
+
+	/* adv_rd_off */
+	temp = dev_t->t_avdp_r;
+	if (mux)
+		temp = max_t(u32, gpmc_t->adv_on + gpmc_ticks_to_ps(1), temp);
+	gpmc_t->adv_rd_off = gpmc_round_ps_to_ticks(temp);
+
+	/* oe_on */
+	temp = dev_t->t_oeasu;
+	if (mux)
+		temp = max_t(u32, temp,
+			gpmc_t->adv_rd_off + dev_t->t_aavdh);
+	gpmc_t->oe_on = gpmc_round_ps_to_ticks(temp);
+
+	/* access */
+	temp = max_t(u32, dev_t->t_iaa, /* XXX: remove t_iaa in async ? */
+				gpmc_t->oe_on + dev_t->t_oe);
+	temp = max_t(u32, temp,
+				gpmc_t->cs_on + dev_t->t_ce);
+	temp = max_t(u32, temp,
+				gpmc_t->adv_on + dev_t->t_aa);
+	gpmc_t->access = gpmc_round_ps_to_ticks(temp);
+
+	gpmc_t->oe_off = gpmc_t->access + gpmc_ticks_to_ps(1);
+	gpmc_t->cs_rd_off = gpmc_t->oe_off;
+
+	/* rd_cycle */
+	temp = max_t(u32, dev_t->t_rd_cycle,
+			gpmc_t->cs_rd_off + dev_t->t_cez_r);
+	temp = max_t(u32, temp, gpmc_t->oe_off + dev_t->t_oez);
+	gpmc_t->rd_cycle = gpmc_round_ps_to_ticks(temp);
+
+	return 0;
+}
+
+static int gpmc_calc_async_write_timings(struct gpmc_timings *gpmc_t,
+				struct gpmc_device_timings *dev_t)
+{
+	bool mux = dev_t->mux;
+	u32 temp;
+
+	/* adv_wr_off */
+	temp = dev_t->t_avdp_w;
+	if (mux)
+		temp = max_t(u32, gpmc_t->adv_on + gpmc_ticks_to_ps(1), temp);
+	gpmc_t->adv_wr_off = gpmc_round_ps_to_ticks(temp);
+
+	/* wr_data_mux_bus */
+	temp = dev_t->t_weasu;
+	if (mux) {
+		temp = max_t(u32, temp,	gpmc_t->adv_wr_off + dev_t->t_aavdh);
+		temp = max_t(u32, temp, gpmc_t->adv_wr_off +
+				gpmc_ticks_to_ps(dev_t->cyc_aavdh_we));
+	}
+	gpmc_t->wr_data_mux_bus = gpmc_round_ps_to_ticks(temp);
+
+	/* we_on */
+	if (gpmc_capability & GPMC_HAS_WR_DATA_MUX_BUS)
+		gpmc_t->we_on = gpmc_round_ps_to_ticks(dev_t->t_weasu);
+	else
+		gpmc_t->we_on = gpmc_t->wr_data_mux_bus;
+
+	/* we_off */
+	temp = gpmc_t->we_on + dev_t->t_wpl;
+	gpmc_t->we_off = gpmc_round_ps_to_ticks(temp);
+
+	gpmc_t->cs_wr_off = gpmc_round_ps_to_ticks(gpmc_t->we_off +
+							dev_t->t_wph);
+
+	/* wr_cycle */
+	temp = max_t(u32, dev_t->t_wr_cycle,
+				gpmc_t->cs_wr_off + dev_t->t_cez_w);
+	gpmc_t->wr_cycle = gpmc_round_ps_to_ticks(temp);
+
+	return 0;
+}
+
+static int gpmc_calc_sync_common_timings(struct gpmc_timings *gpmc_t,
+			struct gpmc_device_timings *dev_t)
+{
+	u32 temp;
+
+	gpmc_t->sync_clk = gpmc_calc_divider(dev_t->clk) *
+						gpmc_get_fclk_period();
+
+	gpmc_t->page_burst_access = gpmc_round_ps_to_sync_clk(
+					dev_t->t_bacc,
+					gpmc_t->sync_clk);
+
+	temp = max_t(u32, dev_t->t_ces, dev_t->t_avds);
+	gpmc_t->clk_activation = gpmc_round_ps_to_ticks(temp);
+
+	if (gpmc_calc_divider(gpmc_t->sync_clk) != 1)
+		return 0;
+
+	if (dev_t->ce_xdelay)
+		gpmc_t->bool_timings.cs_extra_delay = true;
+	if (dev_t->avd_xdelay)
+		gpmc_t->bool_timings.adv_extra_delay = true;
+	if (dev_t->oe_xdelay)
+		gpmc_t->bool_timings.oe_extra_delay = true;
+	if (dev_t->we_xdelay)
+		gpmc_t->bool_timings.we_extra_delay = true;
+
+	return 0;
+}
+
+static int gpmc_calc_common_timings(struct gpmc_timings *gpmc_t,
+			struct gpmc_device_timings *dev_t)
+{
+	u32 temp;
+
+	/* cs_on */
+	gpmc_t->cs_on = gpmc_round_ps_to_ticks(dev_t->t_ceasu);
+
+	/* adv_on */
+	temp = dev_t->t_avdasu;
+	if (dev_t->t_ce_avd)
+		temp = max_t(u32, temp,
+				gpmc_t->cs_on + dev_t->t_ce_avd);
+	gpmc_t->adv_on = gpmc_round_ps_to_ticks(temp);
+
+	if (dev_t->sync_write || dev_t->sync_read)
+		gpmc_calc_sync_common_timings(gpmc_t, dev_t);
+
+	return 0;
+}
+
+/* TODO: remove this function once all peripherals are confirmed to
+ * work with generic timing. Simultaneously gpmc_cs_set_timings()
+ * has to be modified to handle timings in ps instead of ns
+*/
+static void gpmc_convert_ps_to_ns(struct gpmc_timings *t)
+{
+	t->cs_on /= 1000;
+	t->cs_rd_off /= 1000;
+	t->cs_wr_off /= 1000;
+	t->adv_on /= 1000;
+	t->adv_rd_off /= 1000;
+	t->adv_wr_off /= 1000;
+	t->we_on /= 1000;
+	t->we_off /= 1000;
+	t->oe_on /= 1000;
+	t->oe_off /= 1000;
+	t->page_burst_access /= 1000;
+	t->access /= 1000;
+	t->rd_cycle /= 1000;
+	t->wr_cycle /= 1000;
+	t->bus_turnaround /= 1000;
+	t->cycle2cycle_delay /= 1000;
+	t->wait_monitoring /= 1000;
+	t->clk_activation /= 1000;
+	t->wr_access /= 1000;
+	t->wr_data_mux_bus /= 1000;
+}
+
+int gpmc_calc_timings(struct gpmc_timings *gpmc_t,
+			struct gpmc_device_timings *dev_t)
+{
+	memset(gpmc_t, 0, sizeof(*gpmc_t));
+
+	gpmc_calc_common_timings(gpmc_t, dev_t);
+
+	if (dev_t->sync_read)
+		gpmc_calc_sync_read_timings(gpmc_t, dev_t);
+	else
+		gpmc_calc_async_read_timings(gpmc_t, dev_t);
+
+	if (dev_t->sync_write)
+		gpmc_calc_sync_write_timings(gpmc_t, dev_t);
+	else
+		gpmc_calc_async_write_timings(gpmc_t, dev_t);
+
+	/* TODO: remove, see function definition */
+	gpmc_convert_ps_to_ns(gpmc_t);
+
+	return 0;
+}
+
 static __devinit int gpmc_probe(struct platform_device *pdev)
 {
 	int rc;
diff --git a/arch/arm/mach-omap2/gpmc.h b/arch/arm/mach-omap2/gpmc.h
index 79f4dfc..fe0a844 100644
--- a/arch/arm/mach-omap2/gpmc.h
+++ b/arch/arm/mach-omap2/gpmc.h
@@ -74,6 +74,17 @@
 #define GPMC_IRQ_COUNT_EVENT		0x02
 
 
+/* bool type time settings */
+struct gpmc_bool_timings {
+	bool cycle2cyclediffcsen;
+	bool cycle2cyclesamecsen;
+	bool we_extra_delay;
+	bool oe_extra_delay;
+	bool adv_extra_delay;
+	bool cs_extra_delay;
+	bool time_para_granularity;
+};
+
 /*
  * Note that all values in this struct are in nanoseconds except sync_clk
  * (which is in picoseconds), while the register values are in gpmc_fck cycles.
@@ -83,34 +94,104 @@
 	u32 sync_clk;
 
 	/* Chip-select signal timings corresponding to GPMC_CS_CONFIG2 */
-	u16 cs_on;		/* Assertion time */
-	u16 cs_rd_off;		/* Read deassertion time */
-	u16 cs_wr_off;		/* Write deassertion time */
+	u32 cs_on;		/* Assertion time */
+	u32 cs_rd_off;		/* Read deassertion time */
+	u32 cs_wr_off;		/* Write deassertion time */
 
 	/* ADV signal timings corresponding to GPMC_CONFIG3 */
-	u16 adv_on;		/* Assertion time */
-	u16 adv_rd_off;		/* Read deassertion time */
-	u16 adv_wr_off;		/* Write deassertion time */
+	u32 adv_on;		/* Assertion time */
+	u32 adv_rd_off;		/* Read deassertion time */
+	u32 adv_wr_off;		/* Write deassertion time */
 
 	/* WE signals timings corresponding to GPMC_CONFIG4 */
-	u16 we_on;		/* WE assertion time */
-	u16 we_off;		/* WE deassertion time */
+	u32 we_on;		/* WE assertion time */
+	u32 we_off;		/* WE deassertion time */
 
 	/* OE signals timings corresponding to GPMC_CONFIG4 */
-	u16 oe_on;		/* OE assertion time */
-	u16 oe_off;		/* OE deassertion time */
+	u32 oe_on;		/* OE assertion time */
+	u32 oe_off;		/* OE deassertion time */
 
 	/* Access time and cycle time timings corresponding to GPMC_CONFIG5 */
-	u16 page_burst_access;	/* Multiple access word delay */
-	u16 access;		/* Start-cycle to first data valid delay */
-	u16 rd_cycle;		/* Total read cycle time */
-	u16 wr_cycle;		/* Total write cycle time */
+	u32 page_burst_access;	/* Multiple access word delay */
+	u32 access;		/* Start-cycle to first data valid delay */
+	u32 rd_cycle;		/* Total read cycle time */
+	u32 wr_cycle;		/* Total write cycle time */
+
+	u32 bus_turnaround;
+	u32 cycle2cycle_delay;
+
+	u32 wait_monitoring;
+	u32 clk_activation;
 
 	/* The following are only on OMAP3430 */
-	u16 wr_access;		/* WRACCESSTIME */
-	u16 wr_data_mux_bus;	/* WRDATAONADMUXBUS */
+	u32 wr_access;		/* WRACCESSTIME */
+	u32 wr_data_mux_bus;	/* WRDATAONADMUXBUS */
+
+	struct gpmc_bool_timings bool_timings;
 };
 
+/* Device timings in picoseconds */
+struct gpmc_device_timings {
+	u32 t_ceasu;	/* address setup to CS valid */
+	u32 t_avdasu;	/* address setup to ADV valid */
+	/* XXX: try to combine t_avdp_r & t_avdp_w. Issue is
+	 * of tusb using these timings even for sync whilst
+	 * ideally for adv_rd/(wr)_off it should have considered
+	 * t_avdh instead. This indirectly necessitates r/w
+	 * variations of t_avdp as it is possible to have one
+	 * sync & other async
+	 */
+	u32 t_avdp_r;	/* ADV low time (what about t_cer ?) */
+	u32 t_avdp_w;
+	u32 t_aavdh;	/* address hold time */
+	u32 t_oeasu;	/* address setup to OE valid */
+	u32 t_aa;	/* access time from ADV assertion */
+	u32 t_iaa;	/* initial access time */
+	u32 t_oe;	/* access time from OE assertion */
+	u32 t_ce;	/* access time from CS asertion */
+	u32 t_rd_cycle;	/* read cycle time */
+	u32 t_cez_r;	/* read CS deassertion to high Z */
+	u32 t_cez_w;	/* write CS deassertion to high Z */
+	u32 t_oez;	/* OE deassertion to high Z */
+	u32 t_weasu;	/* address setup to WE valid */
+	u32 t_wpl;	/* write assertion time */
+	u32 t_wph;	/* write deassertion time */
+	u32 t_wr_cycle;	/* write cycle time */
+
+	u32 clk;
+	u32 t_bacc;	/* burst access valid clock to output delay */
+	u32 t_ces;	/* CS setup time to clk */
+	u32 t_avds;	/* ADV setup time to clk */
+	u32 t_avdh;	/* ADV hold time from clk */
+	u32 t_ach;	/* address hold time from clk */
+	u32 t_rdyo;	/* clk to ready valid */
+
+	u32 t_ce_rdyz;	/* XXX: description ?, or use t_cez instead */
+	u32 t_ce_avd;	/* CS on to ADV on delay */
+
+	/* XXX: check the possibility of combining
+	 * cyc_aavhd_oe & cyc_aavdh_we
+	 */
+	u8 cyc_aavdh_oe;/* read address hold time in cycles */
+	u8 cyc_aavdh_we;/* write address hold time in cycles */
+	u8 cyc_oe;	/* access time from OE assertion in cycles */
+	u8 cyc_wpl;	/* write deassertion time in cycles */
+	u32 cyc_iaa;	/* initial access time in cycles */
+
+	bool mux;	/* address & data muxed */
+	bool sync_write;/* synchronous write */
+	bool sync_read;	/* synchronous read */
+
+	/* extra delays */
+	bool ce_xdelay;
+	bool avd_xdelay;
+	bool oe_xdelay;
+	bool we_xdelay;
+};
+
+extern int gpmc_calc_timings(struct gpmc_timings *gpmc_t,
+				struct gpmc_device_timings *dev_t);
+
 extern void gpmc_update_nand_reg(struct gpmc_nand_regs *reg, int cs);
 extern int gpmc_get_client_irq(unsigned irq_config);
 
diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c
index 9df7576..2c3fdd6 100644
--- a/arch/arm/mach-omap2/io.c
+++ b/arch/arm/mach-omap2/io.c
@@ -25,7 +25,7 @@
 #include <asm/tlb.h>
 #include <asm/mach/map.h>
 
-#include <plat-omap/dma-omap.h>
+#include <linux/omap-dma.h>
 
 #include "omap_hwmod.h"
 #include "soc.h"
@@ -50,6 +50,9 @@
 #include "prcm_mpu44xx.h"
 #include "prminst44xx.h"
 #include "cminst44xx.h"
+#include "prm2xxx.h"
+#include "prm3xxx.h"
+#include "prm44xx.h"
 
 /*
  * The machine specific code may provide the extra mapping besides the
@@ -387,6 +390,7 @@
 	omap2_set_globals_prm(OMAP2_L4_IO_ADDRESS(OMAP2420_PRM_BASE));
 	omap2_set_globals_cm(OMAP2_L4_IO_ADDRESS(OMAP2420_CM_BASE), NULL);
 	omap2xxx_check_revision();
+	omap2xxx_prm_init();
 	omap2xxx_cm_init();
 	omap2xxx_voltagedomains_init();
 	omap242x_powerdomains_init();
@@ -401,6 +405,7 @@
 	omap_mux_late_init();
 	omap2_common_pm_late_init();
 	omap2_pm_init();
+	omap2_clk_enable_autoidle_all();
 }
 #endif
 
@@ -415,6 +420,7 @@
 	omap2_set_globals_prm(OMAP2_L4_IO_ADDRESS(OMAP2430_PRM_BASE));
 	omap2_set_globals_cm(OMAP2_L4_IO_ADDRESS(OMAP2430_CM_BASE), NULL);
 	omap2xxx_check_revision();
+	omap2xxx_prm_init();
 	omap2xxx_cm_init();
 	omap2xxx_voltagedomains_init();
 	omap243x_powerdomains_init();
@@ -429,6 +435,7 @@
 	omap_mux_late_init();
 	omap2_common_pm_late_init();
 	omap2_pm_init();
+	omap2_clk_enable_autoidle_all();
 }
 #endif
 
@@ -448,6 +455,7 @@
 	omap2_set_globals_cm(OMAP2_L4_IO_ADDRESS(OMAP3430_CM_BASE), NULL);
 	omap3xxx_check_revision();
 	omap3xxx_check_features();
+	omap3xxx_prm_init();
 	omap3xxx_cm_init();
 	omap3xxx_voltagedomains_init();
 	omap3xxx_powerdomains_init();
@@ -500,6 +508,7 @@
 	omap_mux_late_init();
 	omap2_common_pm_late_init();
 	omap3_pm_init();
+	omap2_clk_enable_autoidle_all();
 }
 
 void __init omap3430_init_late(void)
@@ -507,6 +516,7 @@
 	omap_mux_late_init();
 	omap2_common_pm_late_init();
 	omap3_pm_init();
+	omap2_clk_enable_autoidle_all();
 }
 
 void __init omap35xx_init_late(void)
@@ -514,6 +524,7 @@
 	omap_mux_late_init();
 	omap2_common_pm_late_init();
 	omap3_pm_init();
+	omap2_clk_enable_autoidle_all();
 }
 
 void __init omap3630_init_late(void)
@@ -521,6 +532,7 @@
 	omap_mux_late_init();
 	omap2_common_pm_late_init();
 	omap3_pm_init();
+	omap2_clk_enable_autoidle_all();
 }
 
 void __init am35xx_init_late(void)
@@ -528,6 +540,7 @@
 	omap_mux_late_init();
 	omap2_common_pm_late_init();
 	omap3_pm_init();
+	omap2_clk_enable_autoidle_all();
 }
 
 void __init ti81xx_init_late(void)
@@ -535,6 +548,7 @@
 	omap_mux_late_init();
 	omap2_common_pm_late_init();
 	omap3_pm_init();
+	omap2_clk_enable_autoidle_all();
 }
 #endif
 
@@ -573,6 +587,7 @@
 	omap_cm_base_init();
 	omap4xxx_check_revision();
 	omap4xxx_check_features();
+	omap44xx_prm_init();
 	omap44xx_voltagedomains_init();
 	omap44xx_powerdomains_init();
 	omap44xx_clockdomains_init();
@@ -586,6 +601,7 @@
 	omap_mux_late_init();
 	omap2_common_pm_late_init();
 	omap4_pm_init();
+	omap2_clk_enable_autoidle_all();
 }
 #endif
 
diff --git a/arch/arm/mach-omap2/mcbsp.c b/arch/arm/mach-omap2/mcbsp.c
index bf49651..df49f2a 100644
--- a/arch/arm/mach-omap2/mcbsp.c
+++ b/arch/arm/mach-omap2/mcbsp.c
@@ -21,7 +21,7 @@
 #include <linux/platform_data/asoc-ti-mcbsp.h>
 #include <linux/pm_runtime.h>
 
-#include <plat-omap/dma-omap.h>
+#include <linux/omap-dma.h>
 
 #include "omap_device.h"
 
diff --git a/arch/arm/mach-omap2/omap_device.c b/arch/arm/mach-omap2/omap_device.c
index 0ef934f..e065daa 100644
--- a/arch/arm/mach-omap2/omap_device.c
+++ b/arch/arm/mach-omap2/omap_device.c
@@ -441,19 +441,21 @@
 /**
  * omap_device_count_resources - count number of struct resource entries needed
  * @od: struct omap_device *
+ * @flags: Type of resources to include when counting (IRQ/DMA/MEM)
  *
  * Count the number of struct resource entries needed for this
  * omap_device @od.  Used by omap_device_build_ss() to determine how
  * much memory to allocate before calling
  * omap_device_fill_resources().  Returns the count.
  */
-static int omap_device_count_resources(struct omap_device *od)
+static int omap_device_count_resources(struct omap_device *od,
+				       unsigned long flags)
 {
 	int c = 0;
 	int i;
 
 	for (i = 0; i < od->hwmods_cnt; i++)
-		c += omap_hwmod_count_resources(od->hwmods[i]);
+		c += omap_hwmod_count_resources(od->hwmods[i], flags);
 
 	pr_debug("omap_device: %s: counted %d total resources across %d hwmods\n",
 		 od->pdev->name, c, od->hwmods_cnt);
@@ -557,52 +559,73 @@
 	od->hwmods = hwmods;
 	od->pdev = pdev;
 
-	res_count = omap_device_count_resources(od);
 	/*
+	 * Non-DT Boot:
+	 *   Here, pdev->num_resources = 0, and we should get all the
+	 *   resources from hwmod.
+	 *
 	 * DT Boot:
 	 *   OF framework will construct the resource structure (currently
 	 *   does for MEM & IRQ resource) and we should respect/use these
 	 *   resources, killing hwmod dependency.
 	 *   If pdev->num_resources > 0, we assume that MEM & IRQ resources
 	 *   have been allocated by OF layer already (through DTB).
-	 *
-	 * Non-DT Boot:
-	 *   Here, pdev->num_resources = 0, and we should get all the
-	 *   resources from hwmod.
+	 *   As preparation for the future we examine the OF provided resources
+	 *   to see if we have DMA resources provided already. In this case
+	 *   there is no need to update the resources for the device, we use the
+	 *   OF provided ones.
 	 *
 	 * TODO: Once DMA resource is available from OF layer, we should
 	 *   kill filling any resources from hwmod.
 	 */
-	if (res_count > pdev->num_resources) {
-		/* Allocate resources memory to account for new resources */
-		res = kzalloc(sizeof(struct resource) * res_count, GFP_KERNEL);
-		if (!res)
-			goto oda_exit3;
+	if (!pdev->num_resources) {
+		/* Count all resources for the device */
+		res_count = omap_device_count_resources(od, IORESOURCE_IRQ |
+							    IORESOURCE_DMA |
+							    IORESOURCE_MEM);
+	} else {
+		/* Take a look if we already have DMA resource via DT */
+		for (i = 0; i < pdev->num_resources; i++) {
+			struct resource *r = &pdev->resource[i];
 
-		/*
-		 * If pdev->num_resources > 0, then assume that,
-		 * MEM and IRQ resources will only come from DT and only
-		 * fill DMA resource from hwmod layer.
-		 */
-		if (pdev->num_resources && pdev->resource) {
-			dev_dbg(&pdev->dev, "%s(): resources already allocated %d\n",
-				__func__, res_count);
-			memcpy(res, pdev->resource,
-			       sizeof(struct resource) * pdev->num_resources);
-			_od_fill_dma_resources(od, &res[pdev->num_resources]);
-		} else {
-			dev_dbg(&pdev->dev, "%s(): using resources from hwmod %d\n",
-				__func__, res_count);
-			omap_device_fill_resources(od, res);
+			/* We have it, no need to touch the resources */
+			if (r->flags == IORESOURCE_DMA)
+				goto have_everything;
 		}
+		/* Count only DMA resources for the device */
+		res_count = omap_device_count_resources(od, IORESOURCE_DMA);
+		/* The device has no DMA resource, no need for update */
+		if (!res_count)
+			goto have_everything;
 
-		ret = platform_device_add_resources(pdev, res, res_count);
-		kfree(res);
-
-		if (ret)
-			goto oda_exit3;
+		res_count += pdev->num_resources;
 	}
 
+	/* Allocate resources memory to account for new resources */
+	res = kzalloc(sizeof(struct resource) * res_count, GFP_KERNEL);
+	if (!res)
+		goto oda_exit3;
+
+	if (!pdev->num_resources) {
+		dev_dbg(&pdev->dev, "%s: using %d resources from hwmod\n",
+			__func__, res_count);
+		omap_device_fill_resources(od, res);
+	} else {
+		dev_dbg(&pdev->dev,
+			"%s: appending %d DMA resources from hwmod\n",
+			__func__, res_count - pdev->num_resources);
+		memcpy(res, pdev->resource,
+		       sizeof(struct resource) * pdev->num_resources);
+		_od_fill_dma_resources(od, &res[pdev->num_resources]);
+	}
+
+	ret = platform_device_add_resources(pdev, res, res_count);
+	kfree(res);
+
+	if (ret)
+		goto oda_exit3;
+
+have_everything:
 	if (!pm_lats) {
 		pm_lats = omap_default_latency;
 		pm_lats_cnt = ARRAY_SIZE(omap_default_latency);
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index b3b00f4..4653efb 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -130,7 +130,7 @@
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/io.h>
-#include <linux/clk.h>
+#include <linux/clk-provider.h>
 #include <linux/delay.h>
 #include <linux/err.h>
 #include <linux/list.h>
@@ -187,6 +187,8 @@
 	int (*is_hardreset_asserted)(struct omap_hwmod *oh,
 				     struct omap_hwmod_rst_info *ohri);
 	int (*init_clkdm)(struct omap_hwmod *oh);
+	void (*update_context_lost)(struct omap_hwmod *oh);
+	int (*get_context_lost)(struct omap_hwmod *oh);
 };
 
 /* soc_ops: adapts the omap_hwmod code to the currently-booted SoC */
@@ -646,6 +648,19 @@
 	return 0;
 }
 
+static struct clockdomain *_get_clkdm(struct omap_hwmod *oh)
+{
+	struct clk_hw_omap *clk;
+
+	if (oh->clkdm) {
+		return oh->clkdm;
+	} else if (oh->_clk) {
+		clk = to_clk_hw_omap(__clk_get_hw(oh->_clk));
+		return  clk->clkdm;
+	}
+	return NULL;
+}
+
 /**
  * _add_initiator_dep: prevent @oh from smart-idling while @init_oh is active
  * @oh: struct omap_hwmod *
@@ -661,13 +676,18 @@
  */
 static int _add_initiator_dep(struct omap_hwmod *oh, struct omap_hwmod *init_oh)
 {
-	if (!oh->_clk)
+	struct clockdomain *clkdm, *init_clkdm;
+
+	clkdm = _get_clkdm(oh);
+	init_clkdm = _get_clkdm(init_oh);
+
+	if (!clkdm || !init_clkdm)
 		return -EINVAL;
 
-	if (oh->_clk->clkdm && oh->_clk->clkdm->flags & CLKDM_NO_AUTODEPS)
+	if (clkdm && clkdm->flags & CLKDM_NO_AUTODEPS)
 		return 0;
 
-	return clkdm_add_sleepdep(oh->_clk->clkdm, init_oh->_clk->clkdm);
+	return clkdm_add_sleepdep(clkdm, init_clkdm);
 }
 
 /**
@@ -685,13 +705,18 @@
  */
 static int _del_initiator_dep(struct omap_hwmod *oh, struct omap_hwmod *init_oh)
 {
-	if (!oh->_clk)
+	struct clockdomain *clkdm, *init_clkdm;
+
+	clkdm = _get_clkdm(oh);
+	init_clkdm = _get_clkdm(init_oh);
+
+	if (!clkdm || !init_clkdm)
 		return -EINVAL;
 
-	if (oh->_clk->clkdm && oh->_clk->clkdm->flags & CLKDM_NO_AUTODEPS)
+	if (clkdm && clkdm->flags & CLKDM_NO_AUTODEPS)
 		return 0;
 
-	return clkdm_del_sleepdep(oh->_clk->clkdm, init_oh->_clk->clkdm);
+	return clkdm_del_sleepdep(clkdm, init_clkdm);
 }
 
 /**
@@ -725,7 +750,7 @@
 	 */
 	clk_prepare(oh->_clk);
 
-	if (!oh->_clk->clkdm)
+	if (!_get_clkdm(oh))
 		pr_debug("omap_hwmod: %s: missing clockdomain for %s.\n",
 			   oh->name, oh->main_clk);
 
@@ -1308,6 +1333,7 @@
 	u8 idlemode, sf;
 	u32 v;
 	bool clkdm_act;
+	struct clockdomain *clkdm;
 
 	if (!oh->class->sysc)
 		return;
@@ -1327,11 +1353,9 @@
 	v = oh->_sysc_cache;
 	sf = oh->class->sysc->sysc_flags;
 
+	clkdm = _get_clkdm(oh);
 	if (sf & SYSC_HAS_SIDLEMODE) {
-		clkdm_act = ((oh->clkdm &&
-			      oh->clkdm->flags & CLKDM_ACTIVE_WITH_MPU) ||
-			     (oh->_clk && oh->_clk->clkdm &&
-			      oh->_clk->clkdm->flags & CLKDM_ACTIVE_WITH_MPU));
+		clkdm_act = (clkdm && clkdm->flags & CLKDM_ACTIVE_WITH_MPU);
 		if (clkdm_act && !(oh->class->sysc->idlemodes &
 				   (SIDLE_SMART | SIDLE_SMART_WKUP)))
 			idlemode = HWMOD_IDLEMODE_FORCE;
@@ -1533,11 +1557,12 @@
 
 	pr_debug("omap_hwmod: %s: looking up clocks\n", oh->name);
 
+	if (soc_ops.init_clkdm)
+		ret |= soc_ops.init_clkdm(oh);
+
 	ret |= _init_main_clk(oh);
 	ret |= _init_interface_clks(oh);
 	ret |= _init_opt_clks(oh);
-	if (soc_ops.init_clkdm)
-		ret |= soc_ops.init_clkdm(oh);
 
 	if (!ret)
 		oh->_state = _HWMOD_STATE_CLKS_INITED;
@@ -1992,6 +2017,42 @@
 }
 
 /**
+ * _omap4_update_context_lost - increment hwmod context loss counter if
+ * hwmod context was lost, and clear hardware context loss reg
+ * @oh: hwmod to check for context loss
+ *
+ * If the PRCM indicates that the hwmod @oh lost context, increment
+ * our in-memory context loss counter, and clear the RM_*_CONTEXT
+ * bits. No return value.
+ */
+static void _omap4_update_context_lost(struct omap_hwmod *oh)
+{
+	if (oh->prcm.omap4.flags & HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT)
+		return;
+
+	if (!prm_was_any_context_lost_old(oh->clkdm->pwrdm.ptr->prcm_partition,
+					  oh->clkdm->pwrdm.ptr->prcm_offs,
+					  oh->prcm.omap4.context_offs))
+		return;
+
+	oh->prcm.omap4.context_lost_counter++;
+	prm_clear_context_loss_flags_old(oh->clkdm->pwrdm.ptr->prcm_partition,
+					 oh->clkdm->pwrdm.ptr->prcm_offs,
+					 oh->prcm.omap4.context_offs);
+}
+
+/**
+ * _omap4_get_context_lost - get context loss counter for a hwmod
+ * @oh: hwmod to get context loss counter for
+ *
+ * Returns the in-memory context loss counter for a hwmod.
+ */
+static int _omap4_get_context_lost(struct omap_hwmod *oh)
+{
+	return oh->prcm.omap4.context_lost_counter;
+}
+
+/**
  * _enable - enable an omap_hwmod
  * @oh: struct omap_hwmod *
  *
@@ -2074,6 +2135,9 @@
 	if (soc_ops.enable_module)
 		soc_ops.enable_module(oh);
 
+	if (soc_ops.update_context_lost)
+		soc_ops.update_context_lost(oh);
+
 	r = (soc_ops.wait_target_ready) ? soc_ops.wait_target_ready(oh) :
 		-EINVAL;
 	if (!r) {
@@ -3398,7 +3462,7 @@
 /**
  * omap_hwmod_count_resources - count number of struct resources needed by hwmod
  * @oh: struct omap_hwmod *
- * @res: pointer to the first element of an array of struct resource to fill
+ * @flags: Type of resources to include when counting (IRQ/DMA/MEM)
  *
  * Count the number of struct resource array elements necessary to
  * contain omap_hwmod @oh resources.  Intended to be called by code
@@ -3411,20 +3475,25 @@
  * resource IDs.
  *
  */
-int omap_hwmod_count_resources(struct omap_hwmod *oh)
+int omap_hwmod_count_resources(struct omap_hwmod *oh, unsigned long flags)
 {
-	struct omap_hwmod_ocp_if *os;
-	struct list_head *p;
-	int ret;
-	int i = 0;
+	int ret = 0;
 
-	ret = _count_mpu_irqs(oh) + _count_sdma_reqs(oh);
+	if (flags & IORESOURCE_IRQ)
+		ret += _count_mpu_irqs(oh);
 
-	p = oh->slave_ports.next;
+	if (flags & IORESOURCE_DMA)
+		ret += _count_sdma_reqs(oh);
 
-	while (i < oh->slaves_cnt) {
-		os = _fetch_next_ocp_if(&p, &i);
-		ret += _count_ocp_if_addr_spaces(os);
+	if (flags & IORESOURCE_MEM) {
+		int i = 0;
+		struct omap_hwmod_ocp_if *os;
+		struct list_head *p = oh->slave_ports.next;
+
+		while (i < oh->slaves_cnt) {
+			os = _fetch_next_ocp_if(&p, &i);
+			ret += _count_ocp_if_addr_spaces(os);
+		}
 	}
 
 	return ret;
@@ -3591,10 +3660,15 @@
 {
 	struct clk *c;
 	struct omap_hwmod_ocp_if *oi;
+	struct clockdomain *clkdm;
+	struct clk_hw_omap *clk;
 
 	if (!oh)
 		return NULL;
 
+	if (oh->clkdm)
+		return oh->clkdm->pwrdm.ptr;
+
 	if (oh->_clk) {
 		c = oh->_clk;
 	} else {
@@ -3604,11 +3678,12 @@
 		c = oi->_clk;
 	}
 
-	if (!c->clkdm)
+	clk = to_clk_hw_omap(__clk_get_hw(c));
+	clkdm = clk->clkdm;
+	if (!clkdm)
 		return NULL;
 
-	return c->clkdm->pwrdm.ptr;
-
+	return clkdm->pwrdm.ptr;
 }
 
 /**
@@ -3913,17 +3988,21 @@
  * omap_hwmod_get_context_loss_count - get lost context count
  * @oh: struct omap_hwmod *
  *
- * Query the powerdomain of of @oh to get the context loss
- * count for this device.
+ * Returns the context loss count of associated @oh
+ * upon success, or zero if no context loss data is available.
  *
- * Returns the context loss count of the powerdomain assocated with @oh
- * upon success, or zero if no powerdomain exists for @oh.
+ * On OMAP4, this queries the per-hwmod context loss register,
+ * assuming one exists.  If not, or on OMAP2/3, this queries the
+ * enclosing powerdomain context loss count.
  */
 int omap_hwmod_get_context_loss_count(struct omap_hwmod *oh)
 {
 	struct powerdomain *pwrdm;
 	int ret = 0;
 
+	if (soc_ops.get_context_lost)
+		return soc_ops.get_context_lost(oh);
+
 	pwrdm = omap_hwmod_get_pwrdm(oh);
 	if (pwrdm)
 		ret = pwrdm_get_context_loss_count(pwrdm);
@@ -4038,6 +4117,8 @@
 		soc_ops.deassert_hardreset = _omap4_deassert_hardreset;
 		soc_ops.is_hardreset_asserted = _omap4_is_hardreset_asserted;
 		soc_ops.init_clkdm = _init_clkdm;
+		soc_ops.update_context_lost = _omap4_update_context_lost;
+		soc_ops.get_context_lost = _omap4_get_context_lost;
 	} else if (soc_is_am33xx()) {
 		soc_ops.enable_module = _am33xx_enable_module;
 		soc_ops.disable_module = _am33xx_disable_module;
diff --git a/arch/arm/mach-omap2/omap_hwmod.h b/arch/arm/mach-omap2/omap_hwmod.h
index 87a3c5b..3ae852a 100644
--- a/arch/arm/mach-omap2/omap_hwmod.h
+++ b/arch/arm/mach-omap2/omap_hwmod.h
@@ -2,7 +2,7 @@
  * omap_hwmod macros, structures
  *
  * Copyright (C) 2009-2011 Nokia Corporation
- * Copyright (C) 2012 Texas Instruments, Inc.
+ * Copyright (C) 2011-2012 Texas Instruments, Inc.
  * Paul Walmsley
  *
  * Created in collaboration with (alphabetical order): Benoît Cousson,
@@ -394,12 +394,15 @@
 
 /**
  * struct omap_hwmod_omap4_prcm - OMAP4-specific PRCM data
- * @clkctrl_reg: PRCM address of the clock control register
- * @rstctrl_reg: address of the XXX_RSTCTRL register located in the PRM
+ * @clkctrl_offs: offset of the PRCM clock control register
+ * @rstctrl_offs: offset of the XXX_RSTCTRL register located in the PRM
+ * @context_offs: offset of the RM_*_CONTEXT register
  * @lostcontext_mask: bitmask for selecting bits from RM_*_CONTEXT register
  * @rstst_reg: (AM33XX only) address of the XXX_RSTST register in the PRM
  * @submodule_wkdep_bit: bit shift of the WKDEP range
  * @flags: PRCM register capabilities for this IP block
+ * @modulemode: allowable modulemodes
+ * @context_lost_counter: Count of module level context lost
  *
  * If @lostcontext_mask is not defined, context loss check code uses
  * whole register without masking. @lostcontext_mask should only be
@@ -415,6 +418,7 @@
 	u8		submodule_wkdep_bit;
 	u8		modulemode;
 	u8		flags;
+	int		context_lost_counter;
 };
 
 
@@ -633,7 +637,7 @@
 u32 omap_hwmod_read(struct omap_hwmod *oh, u16 reg_offs);
 int omap_hwmod_softreset(struct omap_hwmod *oh);
 
-int omap_hwmod_count_resources(struct omap_hwmod *oh);
+int omap_hwmod_count_resources(struct omap_hwmod *oh, unsigned long flags);
 int omap_hwmod_fill_resources(struct omap_hwmod *oh, struct resource *res);
 int omap_hwmod_fill_dma_resources(struct omap_hwmod *oh, struct resource *res);
 int omap_hwmod_get_resource_byname(struct omap_hwmod *oh, unsigned int type,
diff --git a/arch/arm/mach-omap2/omap_hwmod_2420_data.c b/arch/arm/mach-omap2/omap_hwmod_2420_data.c
index e8efe3d..b5efe58 100644
--- a/arch/arm/mach-omap2/omap_hwmod_2420_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_2420_data.c
@@ -15,8 +15,8 @@
 
 #include <linux/i2c-omap.h>
 #include <linux/platform_data/spi-omap2-mcspi.h>
-
-#include <plat-omap/dma-omap.h>
+#include <linux/omap-dma.h>
+#include <plat/dmtimer.h>
 
 #include "omap_hwmod.h"
 #include "l3_2xxx.h"
diff --git a/arch/arm/mach-omap2/omap_hwmod_2430_data.c b/arch/arm/mach-omap2/omap_hwmod_2430_data.c
index 32d17e3..6c8fa70 100644
--- a/arch/arm/mach-omap2/omap_hwmod_2430_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_2430_data.c
@@ -16,8 +16,8 @@
 #include <linux/i2c-omap.h>
 #include <linux/platform_data/asoc-ti-mcbsp.h>
 #include <linux/platform_data/spi-omap2-mcspi.h>
-
-#include <plat-omap/dma-omap.h>
+#include <linux/omap-dma.h>
+#include <plat/dmtimer.h>
 
 #include "omap_hwmod.h"
 #include "mmc.h"
diff --git a/arch/arm/mach-omap2/omap_hwmod_2xxx_3xxx_ipblock_data.c b/arch/arm/mach-omap2/omap_hwmod_2xxx_3xxx_ipblock_data.c
index 40d6c93..534974e 100644
--- a/arch/arm/mach-omap2/omap_hwmod_2xxx_3xxx_ipblock_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_2xxx_3xxx_ipblock_data.c
@@ -10,7 +10,8 @@
  * published by the Free Software Foundation.
  */
 
-#include <plat-omap/dma-omap.h>
+#include <linux/dmaengine.h>
+#include <linux/omap-dma.h>
 
 #include "omap_hwmod.h"
 #include "hdq1w.h"
diff --git a/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c b/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c
index 0db8f45..e596117 100644
--- a/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c
@@ -10,7 +10,7 @@
  */
 
 #include <linux/platform_data/gpio-omap.h>
-#include <plat-omap/dma-omap.h>
+#include <linux/omap-dma.h>
 #include <plat/dmtimer.h>
 #include <linux/platform_data/spi-omap2-mcspi.h>
 
diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
index 7f73f21..ec4499e 100644
--- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
@@ -19,7 +19,7 @@
 #include <linux/power/smartreflex.h>
 #include <linux/platform_data/gpio-omap.h>
 
-#include <plat-omap/dma-omap.h>
+#include <linux/omap-dma.h>
 #include "l3_3xxx.h"
 #include "l4_3xxx.h"
 #include <linux/platform_data/asoc-ti-mcbsp.h>
diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
index 26f8e9f..eb61cfd 100644
--- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
@@ -21,9 +21,10 @@
 #include <linux/io.h>
 #include <linux/platform_data/gpio-omap.h>
 #include <linux/power/smartreflex.h>
+#include <linux/platform_data/omap_ocp2scp.h>
 #include <linux/i2c-omap.h>
 
-#include <plat-omap/dma-omap.h>
+#include <linux/omap-dma.h>
 
 #include <linux/platform_data/omap_ocp2scp.h>
 #include <linux/platform_data/spi-omap2-mcspi.h>
diff --git a/arch/arm/mach-omap2/omap_opp_data.h b/arch/arm/mach-omap2/omap_opp_data.h
index 7e437bf..336fdfc 100644
--- a/arch/arm/mach-omap2/omap_opp_data.h
+++ b/arch/arm/mach-omap2/omap_opp_data.h
@@ -89,8 +89,11 @@
 extern struct omap_volt_data omap36xx_vddmpu_volt_data[];
 extern struct omap_volt_data omap36xx_vddcore_volt_data[];
 
-extern struct omap_volt_data omap44xx_vdd_mpu_volt_data[];
-extern struct omap_volt_data omap44xx_vdd_iva_volt_data[];
-extern struct omap_volt_data omap44xx_vdd_core_volt_data[];
+extern struct omap_volt_data omap443x_vdd_mpu_volt_data[];
+extern struct omap_volt_data omap443x_vdd_iva_volt_data[];
+extern struct omap_volt_data omap443x_vdd_core_volt_data[];
+extern struct omap_volt_data omap446x_vdd_mpu_volt_data[];
+extern struct omap_volt_data omap446x_vdd_iva_volt_data[];
+extern struct omap_volt_data omap446x_vdd_core_volt_data[];
 
 #endif		/* __ARCH_ARM_MACH_OMAP2_OMAP_OPP_DATA_H */
diff --git a/arch/arm/mach-omap2/omap_phy_internal.c b/arch/arm/mach-omap2/omap_phy_internal.c
index 4d76a3c..e237602 100644
--- a/arch/arm/mach-omap2/omap_phy_internal.c
+++ b/arch/arm/mach-omap2/omap_phy_internal.c
@@ -33,6 +33,38 @@
 #include "control.h"
 #include "usb.h"
 
+#define CONTROL_DEV_CONF		0x300
+#define PHY_PD				0x1
+
+/**
+ * omap4430_phy_power_down: disable MUSB PHY during early init
+ *
+ * OMAP4 MUSB PHY module is enabled by default on reset, but this will
+ * prevent core retention if not disabled by SW. USB driver will
+ * later on enable this, once and if the driver needs it.
+ */
+static int __init omap4430_phy_power_down(void)
+{
+	void __iomem *ctrl_base;
+
+	if (!cpu_is_omap44xx())
+		return 0;
+
+	ctrl_base = ioremap(OMAP443X_SCM_BASE, SZ_1K);
+	if (!ctrl_base) {
+		pr_err("control module ioremap failed\n");
+		return -ENOMEM;
+	}
+
+	/* Power down the phy */
+	__raw_writel(PHY_PD, ctrl_base + CONTROL_DEV_CONF);
+
+	iounmap(ctrl_base);
+
+	return 0;
+}
+early_initcall(omap4430_phy_power_down);
+
 void am35x_musb_reset(void)
 {
 	u32	regval;
diff --git a/arch/arm/mach-omap2/omap_twl.c b/arch/arm/mach-omap2/omap_twl.c
index 2bf35dc..fefd401 100644
--- a/arch/arm/mach-omap2/omap_twl.c
+++ b/arch/arm/mach-omap2/omap_twl.c
@@ -31,16 +31,6 @@
 #define OMAP3_VP_VSTEPMAX_VSTEPMAX	0x04
 #define OMAP3_VP_VLIMITTO_TIMEOUT_US	200
 
-#define OMAP3430_VP1_VLIMITTO_VDDMIN	0x14
-#define OMAP3430_VP1_VLIMITTO_VDDMAX	0x42
-#define OMAP3430_VP2_VLIMITTO_VDDMIN	0x18
-#define OMAP3430_VP2_VLIMITTO_VDDMAX	0x2c
-
-#define OMAP3630_VP1_VLIMITTO_VDDMIN	0x18
-#define OMAP3630_VP1_VLIMITTO_VDDMAX	0x3c
-#define OMAP3630_VP2_VLIMITTO_VDDMIN	0x18
-#define OMAP3630_VP2_VLIMITTO_VDDMAX	0x30
-
 #define OMAP4_SRI2C_SLAVE_ADDR		0x12
 #define OMAP4_VDD_MPU_SR_VOLT_REG	0x55
 #define OMAP4_VDD_MPU_SR_CMD_REG	0x56
@@ -54,13 +44,6 @@
 #define OMAP4_VP_VSTEPMAX_VSTEPMAX	0x04
 #define OMAP4_VP_VLIMITTO_TIMEOUT_US	200
 
-#define OMAP4_VP_MPU_VLIMITTO_VDDMIN	0xA
-#define OMAP4_VP_MPU_VLIMITTO_VDDMAX	0x39
-#define OMAP4_VP_IVA_VLIMITTO_VDDMIN	0xA
-#define OMAP4_VP_IVA_VLIMITTO_VDDMAX	0x2D
-#define OMAP4_VP_CORE_VLIMITTO_VDDMIN	0xA
-#define OMAP4_VP_CORE_VLIMITTO_VDDMAX	0x28
-
 static bool is_offset_valid;
 static u8 smps_offset;
 /*
@@ -159,16 +142,11 @@
 static struct omap_voltdm_pmic omap3_mpu_pmic = {
 	.slew_rate		= 4000,
 	.step_size		= 12500,
-	.on_volt		= 1200000,
-	.onlp_volt		= 1000000,
-	.ret_volt		= 975000,
-	.off_volt		= 600000,
-	.volt_setup_time	= 0xfff,
 	.vp_erroroffset		= OMAP3_VP_CONFIG_ERROROFFSET,
 	.vp_vstepmin		= OMAP3_VP_VSTEPMIN_VSTEPMIN,
 	.vp_vstepmax		= OMAP3_VP_VSTEPMAX_VSTEPMAX,
-	.vp_vddmin		= OMAP3430_VP1_VLIMITTO_VDDMIN,
-	.vp_vddmax		= OMAP3430_VP1_VLIMITTO_VDDMAX,
+	.vddmin			= 600000,
+	.vddmax			= 1450000,
 	.vp_timeout_us		= OMAP3_VP_VLIMITTO_TIMEOUT_US,
 	.i2c_slave_addr		= OMAP3_SRI2C_SLAVE_ADDR,
 	.volt_reg_addr		= OMAP3_VDD_MPU_SR_CONTROL_REG,
@@ -180,16 +158,11 @@
 static struct omap_voltdm_pmic omap3_core_pmic = {
 	.slew_rate		= 4000,
 	.step_size		= 12500,
-	.on_volt                = 1200000,
-	.onlp_volt              = 1000000,
-	.ret_volt               = 975000,
-	.off_volt               = 600000,
-	.volt_setup_time        = 0xfff,
 	.vp_erroroffset		= OMAP3_VP_CONFIG_ERROROFFSET,
 	.vp_vstepmin		= OMAP3_VP_VSTEPMIN_VSTEPMIN,
 	.vp_vstepmax		= OMAP3_VP_VSTEPMAX_VSTEPMAX,
-	.vp_vddmin		= OMAP3430_VP2_VLIMITTO_VDDMIN,
-	.vp_vddmax		= OMAP3430_VP2_VLIMITTO_VDDMAX,
+	.vddmin			= 600000,
+	.vddmax			= 1450000,
 	.vp_timeout_us		= OMAP3_VP_VLIMITTO_TIMEOUT_US,
 	.i2c_slave_addr		= OMAP3_SRI2C_SLAVE_ADDR,
 	.volt_reg_addr		= OMAP3_VDD_CORE_SR_CONTROL_REG,
@@ -201,21 +174,17 @@
 static struct omap_voltdm_pmic omap4_mpu_pmic = {
 	.slew_rate		= 4000,
 	.step_size		= 12660,
-	.on_volt		= 1375000,
-	.onlp_volt		= 1375000,
-	.ret_volt		= 830000,
-	.off_volt		= 0,
-	.volt_setup_time	= 0,
 	.vp_erroroffset		= OMAP4_VP_CONFIG_ERROROFFSET,
 	.vp_vstepmin		= OMAP4_VP_VSTEPMIN_VSTEPMIN,
 	.vp_vstepmax		= OMAP4_VP_VSTEPMAX_VSTEPMAX,
-	.vp_vddmin		= OMAP4_VP_MPU_VLIMITTO_VDDMIN,
-	.vp_vddmax		= OMAP4_VP_MPU_VLIMITTO_VDDMAX,
+	.vddmin			= 0,
+	.vddmax			= 2100000,
 	.vp_timeout_us		= OMAP4_VP_VLIMITTO_TIMEOUT_US,
 	.i2c_slave_addr		= OMAP4_SRI2C_SLAVE_ADDR,
 	.volt_reg_addr		= OMAP4_VDD_MPU_SR_VOLT_REG,
 	.cmd_reg_addr		= OMAP4_VDD_MPU_SR_CMD_REG,
 	.i2c_high_speed		= true,
+	.i2c_pad_load		= 3,
 	.vsel_to_uv		= twl6030_vsel_to_uv,
 	.uv_to_vsel		= twl6030_uv_to_vsel,
 };
@@ -223,21 +192,17 @@
 static struct omap_voltdm_pmic omap4_iva_pmic = {
 	.slew_rate		= 4000,
 	.step_size		= 12660,
-	.on_volt		= 1188000,
-	.onlp_volt		= 1188000,
-	.ret_volt		= 830000,
-	.off_volt		= 0,
-	.volt_setup_time	= 0,
 	.vp_erroroffset		= OMAP4_VP_CONFIG_ERROROFFSET,
 	.vp_vstepmin		= OMAP4_VP_VSTEPMIN_VSTEPMIN,
 	.vp_vstepmax		= OMAP4_VP_VSTEPMAX_VSTEPMAX,
-	.vp_vddmin		= OMAP4_VP_IVA_VLIMITTO_VDDMIN,
-	.vp_vddmax		= OMAP4_VP_IVA_VLIMITTO_VDDMAX,
+	.vddmin			= 0,
+	.vddmax			= 2100000,
 	.vp_timeout_us		= OMAP4_VP_VLIMITTO_TIMEOUT_US,
 	.i2c_slave_addr		= OMAP4_SRI2C_SLAVE_ADDR,
 	.volt_reg_addr		= OMAP4_VDD_IVA_SR_VOLT_REG,
 	.cmd_reg_addr		= OMAP4_VDD_IVA_SR_CMD_REG,
 	.i2c_high_speed		= true,
+	.i2c_pad_load		= 3,
 	.vsel_to_uv		= twl6030_vsel_to_uv,
 	.uv_to_vsel		= twl6030_uv_to_vsel,
 };
@@ -245,20 +210,17 @@
 static struct omap_voltdm_pmic omap4_core_pmic = {
 	.slew_rate		= 4000,
 	.step_size		= 12660,
-	.on_volt		= 1200000,
-	.onlp_volt		= 1200000,
-	.ret_volt		= 830000,
-	.off_volt		= 0,
-	.volt_setup_time	= 0,
 	.vp_erroroffset		= OMAP4_VP_CONFIG_ERROROFFSET,
 	.vp_vstepmin		= OMAP4_VP_VSTEPMIN_VSTEPMIN,
 	.vp_vstepmax		= OMAP4_VP_VSTEPMAX_VSTEPMAX,
-	.vp_vddmin		= OMAP4_VP_CORE_VLIMITTO_VDDMIN,
-	.vp_vddmax		= OMAP4_VP_CORE_VLIMITTO_VDDMAX,
+	.vddmin			= 0,
+	.vddmax			= 2100000,
 	.vp_timeout_us		= OMAP4_VP_VLIMITTO_TIMEOUT_US,
 	.i2c_slave_addr		= OMAP4_SRI2C_SLAVE_ADDR,
 	.volt_reg_addr		= OMAP4_VDD_CORE_SR_VOLT_REG,
 	.cmd_reg_addr		= OMAP4_VDD_CORE_SR_CMD_REG,
+	.i2c_high_speed		= true,
+	.i2c_pad_load		= 3,
 	.vsel_to_uv		= twl6030_vsel_to_uv,
 	.uv_to_vsel		= twl6030_uv_to_vsel,
 };
@@ -289,13 +251,6 @@
 	if (!cpu_is_omap34xx())
 		return -ENODEV;
 
-	if (cpu_is_omap3630()) {
-		omap3_mpu_pmic.vp_vddmin = OMAP3630_VP1_VLIMITTO_VDDMIN;
-		omap3_mpu_pmic.vp_vddmax = OMAP3630_VP1_VLIMITTO_VDDMAX;
-		omap3_core_pmic.vp_vddmin = OMAP3630_VP2_VLIMITTO_VDDMIN;
-		omap3_core_pmic.vp_vddmax = OMAP3630_VP2_VLIMITTO_VDDMAX;
-	}
-
 	/*
 	 * The smartreflex bit on twl4030 specifies if the setting of voltage
 	 * is done over the I2C_SR path. Since this setting is independent of
diff --git a/arch/arm/mach-omap2/opp4xxx_data.c b/arch/arm/mach-omap2/opp4xxx_data.c
index a9fd6d5..d470b72 100644
--- a/arch/arm/mach-omap2/opp4xxx_data.c
+++ b/arch/arm/mach-omap2/opp4xxx_data.c
@@ -1,7 +1,7 @@
 /*
  * OMAP4 OPP table definitions.
  *
- * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/
+ * Copyright (C) 2010-2012 Texas Instruments Incorporated - http://www.ti.com/
  *	Nishanth Menon
  *	Kevin Hilman
  *	Thara Gopinath
@@ -35,7 +35,7 @@
 #define OMAP4430_VDD_MPU_OPPTURBO_UV		1313000
 #define OMAP4430_VDD_MPU_OPPNITRO_UV		1375000
 
-struct omap_volt_data omap44xx_vdd_mpu_volt_data[] = {
+struct omap_volt_data omap443x_vdd_mpu_volt_data[] = {
 	VOLT_DATA_DEFINE(OMAP4430_VDD_MPU_OPP50_UV, OMAP44XX_CONTROL_FUSE_MPU_OPP50, 0xf4, 0x0c),
 	VOLT_DATA_DEFINE(OMAP4430_VDD_MPU_OPP100_UV, OMAP44XX_CONTROL_FUSE_MPU_OPP100, 0xf9, 0x16),
 	VOLT_DATA_DEFINE(OMAP4430_VDD_MPU_OPPTURBO_UV, OMAP44XX_CONTROL_FUSE_MPU_OPPTURBO, 0xfa, 0x23),
@@ -47,7 +47,7 @@
 #define OMAP4430_VDD_IVA_OPP100_UV		1188000
 #define OMAP4430_VDD_IVA_OPPTURBO_UV		1300000
 
-struct omap_volt_data omap44xx_vdd_iva_volt_data[] = {
+struct omap_volt_data omap443x_vdd_iva_volt_data[] = {
 	VOLT_DATA_DEFINE(OMAP4430_VDD_IVA_OPP50_UV, OMAP44XX_CONTROL_FUSE_IVA_OPP50, 0xf4, 0x0c),
 	VOLT_DATA_DEFINE(OMAP4430_VDD_IVA_OPP100_UV, OMAP44XX_CONTROL_FUSE_IVA_OPP100, 0xf9, 0x16),
 	VOLT_DATA_DEFINE(OMAP4430_VDD_IVA_OPPTURBO_UV, OMAP44XX_CONTROL_FUSE_IVA_OPPTURBO, 0xfa, 0x23),
@@ -57,14 +57,14 @@
 #define OMAP4430_VDD_CORE_OPP50_UV		1025000
 #define OMAP4430_VDD_CORE_OPP100_UV		1200000
 
-struct omap_volt_data omap44xx_vdd_core_volt_data[] = {
+struct omap_volt_data omap443x_vdd_core_volt_data[] = {
 	VOLT_DATA_DEFINE(OMAP4430_VDD_CORE_OPP50_UV, OMAP44XX_CONTROL_FUSE_CORE_OPP50, 0xf4, 0x0c),
 	VOLT_DATA_DEFINE(OMAP4430_VDD_CORE_OPP100_UV, OMAP44XX_CONTROL_FUSE_CORE_OPP100, 0xf9, 0x16),
 	VOLT_DATA_DEFINE(0, 0, 0, 0),
 };
 
 
-static struct omap_opp_def __initdata omap44xx_opp_def_list[] = {
+static struct omap_opp_def __initdata omap443x_opp_def_list[] = {
 	/* MPU OPP1 - OPP50 */
 	OPP_INITIALIZER("mpu", true, 300000000, OMAP4430_VDD_MPU_OPP50_UV),
 	/* MPU OPP2 - OPP100 */
@@ -86,6 +86,82 @@
 	/* TODO: add DSP, aess, fdif, gpu */
 };
 
+#define OMAP4460_VDD_MPU_OPP50_UV		1025000
+#define OMAP4460_VDD_MPU_OPP100_UV		1200000
+#define OMAP4460_VDD_MPU_OPPTURBO_UV		1313000
+#define OMAP4460_VDD_MPU_OPPNITRO_UV		1375000
+
+struct omap_volt_data omap446x_vdd_mpu_volt_data[] = {
+	VOLT_DATA_DEFINE(OMAP4460_VDD_MPU_OPP50_UV, OMAP44XX_CONTROL_FUSE_MPU_OPP50, 0xf4, 0x0c),
+	VOLT_DATA_DEFINE(OMAP4460_VDD_MPU_OPP100_UV, OMAP44XX_CONTROL_FUSE_MPU_OPP100, 0xf9, 0x16),
+	VOLT_DATA_DEFINE(OMAP4460_VDD_MPU_OPPTURBO_UV, OMAP44XX_CONTROL_FUSE_MPU_OPPTURBO, 0xfa, 0x23),
+	VOLT_DATA_DEFINE(OMAP4460_VDD_MPU_OPPNITRO_UV, OMAP44XX_CONTROL_FUSE_MPU_OPPNITRO, 0xfa, 0x27),
+	VOLT_DATA_DEFINE(0, 0, 0, 0),
+};
+
+#define OMAP4460_VDD_IVA_OPP50_UV		1025000
+#define OMAP4460_VDD_IVA_OPP100_UV		1200000
+#define OMAP4460_VDD_IVA_OPPTURBO_UV		1313000
+#define OMAP4460_VDD_IVA_OPPNITRO_UV		1375000
+
+struct omap_volt_data omap446x_vdd_iva_volt_data[] = {
+	VOLT_DATA_DEFINE(OMAP4460_VDD_IVA_OPP50_UV, OMAP44XX_CONTROL_FUSE_IVA_OPP50, 0xf4, 0x0c),
+	VOLT_DATA_DEFINE(OMAP4460_VDD_IVA_OPP100_UV, OMAP44XX_CONTROL_FUSE_IVA_OPP100, 0xf9, 0x16),
+	VOLT_DATA_DEFINE(OMAP4460_VDD_IVA_OPPTURBO_UV, OMAP44XX_CONTROL_FUSE_IVA_OPPTURBO, 0xfa, 0x23),
+	VOLT_DATA_DEFINE(OMAP4460_VDD_IVA_OPPNITRO_UV, OMAP44XX_CONTROL_FUSE_IVA_OPPNITRO, 0xfa, 0x23),
+	VOLT_DATA_DEFINE(0, 0, 0, 0),
+};
+
+#define OMAP4460_VDD_CORE_OPP50_UV		1025000
+#define OMAP4460_VDD_CORE_OPP100_UV		1200000
+#define OMAP4460_VDD_CORE_OPP100_OV_UV		1250000
+
+struct omap_volt_data omap446x_vdd_core_volt_data[] = {
+	VOLT_DATA_DEFINE(OMAP4460_VDD_CORE_OPP50_UV, OMAP44XX_CONTROL_FUSE_CORE_OPP50, 0xf4, 0x0c),
+	VOLT_DATA_DEFINE(OMAP4460_VDD_CORE_OPP100_UV, OMAP44XX_CONTROL_FUSE_CORE_OPP100, 0xf9, 0x16),
+	VOLT_DATA_DEFINE(OMAP4460_VDD_CORE_OPP100_OV_UV, OMAP44XX_CONTROL_FUSE_CORE_OPP100OV, 0xf9, 0x16),
+	VOLT_DATA_DEFINE(0, 0, 0, 0),
+};
+
+static struct omap_opp_def __initdata omap446x_opp_def_list[] = {
+	/* MPU OPP1 - OPP50 */
+	OPP_INITIALIZER("mpu", true, 350000000, OMAP4460_VDD_MPU_OPP50_UV),
+	/* MPU OPP2 - OPP100 */
+	OPP_INITIALIZER("mpu", true, 700000000, OMAP4460_VDD_MPU_OPP100_UV),
+	/* MPU OPP3 - OPP-Turbo */
+	OPP_INITIALIZER("mpu", true, 920000000, OMAP4460_VDD_MPU_OPPTURBO_UV),
+	/*
+	 * MPU OPP4 - OPP-Nitro + Disabled as the reference schematics
+	 * recommends TPS623631 - confirm and enable the opp in board file
+	 * XXX: May be we should enable these based on mpu capability and
+	 * Exception board files disable it...
+	 */
+	OPP_INITIALIZER("mpu", false, 1200000000, OMAP4460_VDD_MPU_OPPNITRO_UV),
+	/* MPU OPP4 - OPP-Nitro SpeedBin */
+	OPP_INITIALIZER("mpu", false, 1500000000, OMAP4460_VDD_MPU_OPPNITRO_UV),
+	/* L3 OPP1 - OPP50 */
+	OPP_INITIALIZER("l3_main_1", true, 100000000, OMAP4460_VDD_CORE_OPP50_UV),
+	/* L3 OPP2 - OPP100 */
+	OPP_INITIALIZER("l3_main_1", true, 200000000, OMAP4460_VDD_CORE_OPP100_UV),
+	/* IVA OPP1 - OPP50 */
+	OPP_INITIALIZER("iva", true, 133000000, OMAP4460_VDD_IVA_OPP50_UV),
+	/* IVA OPP2 - OPP100 */
+	OPP_INITIALIZER("iva", true, 266100000, OMAP4460_VDD_IVA_OPP100_UV),
+	/*
+	 * IVA OPP3 - OPP-Turbo + Disabled as the reference schematics
+	 * recommends Phoenix VCORE2 which can supply only 600mA - so the ones
+	 * above this OPP frequency, even though OMAP is capable, should be
+	 * enabled by board file which is sure of the chip power capability
+	 */
+	OPP_INITIALIZER("iva", false, 332000000, OMAP4460_VDD_IVA_OPPTURBO_UV),
+	/* IVA OPP4 - OPP-Nitro */
+	OPP_INITIALIZER("iva", false, 430000000, OMAP4460_VDD_IVA_OPPNITRO_UV),
+	/* IVA OPP5 - OPP-Nitro SpeedBin*/
+	OPP_INITIALIZER("iva", false, 500000000, OMAP4460_VDD_IVA_OPPNITRO_UV),
+
+	/* TODO: add DSP, aess, fdif, gpu */
+};
+
 /**
  * omap4_opp_init() - initialize omap4 opp table
  */
@@ -93,12 +169,12 @@
 {
 	int r = -ENODEV;
 
-	if (!cpu_is_omap443x())
-		return r;
-
-	r = omap_init_opp_table(omap44xx_opp_def_list,
-			ARRAY_SIZE(omap44xx_opp_def_list));
-
+	if (cpu_is_omap443x())
+		r = omap_init_opp_table(omap443x_opp_def_list,
+			ARRAY_SIZE(omap443x_opp_def_list));
+	else if (cpu_is_omap446x())
+		r = omap_init_opp_table(omap446x_opp_def_list,
+			ARRAY_SIZE(omap446x_opp_def_list));
 	return r;
 }
 device_initcall(omap4_opp_init);
diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c
index 331478f..f4b3143 100644
--- a/arch/arm/mach-omap2/pm.c
+++ b/arch/arm/mach-omap2/pm.c
@@ -40,6 +40,38 @@
  */
 int (*omap_pm_suspend)(void);
 
+#ifdef CONFIG_PM
+/**
+ * struct omap2_oscillator - Describe the board main oscillator latencies
+ * @startup_time: oscillator startup latency
+ * @shutdown_time: oscillator shutdown latency
+ */
+struct omap2_oscillator {
+	u32 startup_time;
+	u32 shutdown_time;
+};
+
+static struct omap2_oscillator oscillator = {
+	.startup_time = ULONG_MAX,
+	.shutdown_time = ULONG_MAX,
+};
+
+void omap_pm_setup_oscillator(u32 tstart, u32 tshut)
+{
+	oscillator.startup_time = tstart;
+	oscillator.shutdown_time = tshut;
+}
+
+void omap_pm_get_oscillator(u32 *tstart, u32 *tshut)
+{
+	if (!tstart || !tshut)
+		return;
+
+	*tstart = oscillator.startup_time;
+	*tshut = oscillator.shutdown_time;
+}
+#endif
+
 static int __init _init_omap_device(char *name)
 {
 	struct omap_hwmod *oh;
diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h
index fc3c96d..c22503b 100644
--- a/arch/arm/mach-omap2/pm.h
+++ b/arch/arm/mach-omap2/pm.h
@@ -138,4 +138,14 @@
 }
 #endif
 
+#ifdef CONFIG_PM
+extern void omap_pm_setup_oscillator(u32 tstart, u32 tshut);
+extern void omap_pm_get_oscillator(u32 *tstart, u32 *tshut);
+extern void omap_pm_setup_sr_i2c_pcb_length(u32 mm);
+#else
+static inline void omap_pm_setup_oscillator(u32 tstart, u32 tshut) { }
+static inline void omap_pm_get_oscillator(u32 *tstart, u32 *tshut) { *tstart = *tshut = 0; }
+static inline void omap_pm_setup_sr_i2c_pcb_length(u32 mm) { }
+#endif
+
 #endif
diff --git a/arch/arm/mach-omap2/pm24xx.c b/arch/arm/mach-omap2/pm24xx.c
index 13e1f43..c333fa6 100644
--- a/arch/arm/mach-omap2/pm24xx.c
+++ b/arch/arm/mach-omap2/pm24xx.c
@@ -25,7 +25,7 @@
 #include <linux/sysfs.h>
 #include <linux/module.h>
 #include <linux/delay.h>
-#include <linux/clk.h>
+#include <linux/clk-provider.h>
 #include <linux/irq.h>
 #include <linux/time.h>
 #include <linux/gpio.h>
@@ -38,7 +38,7 @@
 #include <asm/mach-types.h>
 #include <asm/system_misc.h>
 
-#include <plat-omap/dma-omap.h>
+#include <linux/omap-dma.h>
 
 #include "soc.h"
 #include "common.h"
@@ -203,7 +203,7 @@
 {
 	if (omap2_fclks_active())
 		return 0;
-	if (osc_ck->usecount > 1)
+	if (__clk_is_enabled(osc_ck))
 		return 0;
 	if (omap_dma_running())
 		return 0;
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index 7703200..7be3622 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -28,6 +28,7 @@
 #include <linux/clk.h>
 #include <linux/delay.h>
 #include <linux/slab.h>
+#include <linux/omap-dma.h>
 #include <linux/platform_data/gpio-omap.h>
 
 #include <trace/events/power.h>
@@ -38,8 +39,6 @@
 
 #include "clockdomain.h"
 #include "powerdomain.h"
-#include <plat-omap/dma-omap.h>
-
 #include "soc.h"
 #include "common.h"
 #include "cm3xxx.h"
diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c
index 7da75ae..aa6fd98 100644
--- a/arch/arm/mach-omap2/pm44xx.c
+++ b/arch/arm/mach-omap2/pm44xx.c
@@ -101,13 +101,6 @@
 	if (!strncmp(pwrdm->name, "cpu", 3))
 		return 0;
 
-	/*
-	 * FIXME: Remove this check when core retention is supported
-	 * Only MPUSS power domain is added in the list.
-	 */
-	if (strcmp(pwrdm->name, "mpu_pwrdm"))
-		return 0;
-
 	pwrst = kmalloc(sizeof(struct power_state), GFP_ATOMIC);
 	if (!pwrst)
 		return -ENOMEM;
diff --git a/arch/arm/mach-omap2/prm-regbits-24xx.h b/arch/arm/mach-omap2/prm-regbits-24xx.h
index 638da6d..91aa510 100644
--- a/arch/arm/mach-omap2/prm-regbits-24xx.h
+++ b/arch/arm/mach-omap2/prm-regbits-24xx.h
@@ -107,12 +107,14 @@
 #define OMAP2420_CLKOUT2_EN_MASK			(1 << 15)
 #define OMAP2420_CLKOUT2_DIV_SHIFT			11
 #define OMAP2420_CLKOUT2_DIV_MASK			(0x7 << 11)
+#define OMAP2420_CLKOUT2_DIV_WIDTH			3
 #define OMAP2420_CLKOUT2_SOURCE_SHIFT			8
 #define OMAP2420_CLKOUT2_SOURCE_MASK			(0x3 << 8)
 #define OMAP24XX_CLKOUT_EN_SHIFT			7
 #define OMAP24XX_CLKOUT_EN_MASK				(1 << 7)
 #define OMAP24XX_CLKOUT_DIV_SHIFT			3
 #define OMAP24XX_CLKOUT_DIV_MASK			(0x7 << 3)
+#define OMAP24XX_CLKOUT_DIV_WIDTH			3
 #define OMAP24XX_CLKOUT_SOURCE_SHIFT			0
 #define OMAP24XX_CLKOUT_SOURCE_MASK			(0x3 << 0)
 
diff --git a/arch/arm/mach-omap2/prm-regbits-34xx.h b/arch/arm/mach-omap2/prm-regbits-34xx.h
index 838b594..b0a2142 100644
--- a/arch/arm/mach-omap2/prm-regbits-34xx.h
+++ b/arch/arm/mach-omap2/prm-regbits-34xx.h
@@ -384,6 +384,7 @@
 /* PRM_CLKSEL */
 #define OMAP3430_SYS_CLKIN_SEL_SHIFT			0
 #define OMAP3430_SYS_CLKIN_SEL_MASK			(0x7 << 0)
+#define OMAP3430_SYS_CLKIN_SEL_WIDTH			3
 
 /* PRM_CLKOUT_CTRL */
 #define OMAP3430_CLKOUT_EN_MASK				(1 << 7)
diff --git a/arch/arm/mach-omap2/prm.h b/arch/arm/mach-omap2/prm.h
index a1a266c..ac25ae6 100644
--- a/arch/arm/mach-omap2/prm.h
+++ b/arch/arm/mach-omap2/prm.h
@@ -114,16 +114,25 @@
 
 /**
  * struct prm_ll_data - fn ptrs to per-SoC PRM function implementations
- * @read_reset_sources: ptr to the Soc PRM-specific get_reset_source impl
+ * @read_reset_sources: ptr to the SoC PRM-specific get_reset_source impl
+ * @was_any_context_lost_old: ptr to the SoC PRM context loss test fn
+ * @clear_context_loss_flags_old: ptr to the SoC PRM context loss flag clear fn
+ *
+ * XXX @was_any_context_lost_old and @clear_context_loss_flags_old are
+ * deprecated.
  */
 struct prm_ll_data {
 	u32 (*read_reset_sources)(void);
+	bool (*was_any_context_lost_old)(u8 part, s16 inst, u16 idx);
+	void (*clear_context_loss_flags_old)(u8 part, s16 inst, u16 idx);
 };
 
 extern int prm_register(struct prm_ll_data *pld);
 extern int prm_unregister(struct prm_ll_data *pld);
 
 extern u32 prm_read_reset_sources(void);
+extern bool prm_was_any_context_lost_old(u8 part, s16 inst, u16 idx);
+extern void prm_clear_context_loss_flags_old(u8 part, s16 inst, u16 idx);
 
 #endif
 
diff --git a/arch/arm/mach-omap2/prm2xxx.c b/arch/arm/mach-omap2/prm2xxx.c
index bf24fc4..faeab186 100644
--- a/arch/arm/mach-omap2/prm2xxx.c
+++ b/arch/arm/mach-omap2/prm2xxx.c
@@ -118,14 +118,13 @@
 	.read_reset_sources = &omap2xxx_prm_read_reset_sources,
 };
 
-static int __init omap2xxx_prm_init(void)
+int __init omap2xxx_prm_init(void)
 {
 	if (!cpu_is_omap24xx())
 		return 0;
 
 	return prm_register(&omap2xxx_prm_ll_data);
 }
-subsys_initcall(omap2xxx_prm_init);
 
 static void __exit omap2xxx_prm_exit(void)
 {
diff --git a/arch/arm/mach-omap2/prm2xxx.h b/arch/arm/mach-omap2/prm2xxx.h
index fe8a14f..3194dd8 100644
--- a/arch/arm/mach-omap2/prm2xxx.h
+++ b/arch/arm/mach-omap2/prm2xxx.h
@@ -126,8 +126,7 @@
 
 extern void omap2xxx_prm_dpll_reset(void);
 
-extern int __init prm2xxx_init(void);
-extern int __exit prm2xxx_exit(void);
+extern int __init omap2xxx_prm_init(void);
 
 #endif
 
diff --git a/arch/arm/mach-omap2/prm2xxx_3xxx.h b/arch/arm/mach-omap2/prm2xxx_3xxx.h
index 78532d6..9624b40 100644
--- a/arch/arm/mach-omap2/prm2xxx_3xxx.h
+++ b/arch/arm/mach-omap2/prm2xxx_3xxx.h
@@ -152,6 +152,7 @@
 /* Named PRCM_CLKSRC_CTRL on the 24XX */
 #define OMAP_SYSCLKDIV_SHIFT				6
 #define OMAP_SYSCLKDIV_MASK				(0x3 << 6)
+#define OMAP_SYSCLKDIV_WIDTH				2
 #define OMAP_AUTOEXTCLKMODE_SHIFT			3
 #define OMAP_AUTOEXTCLKMODE_MASK			(0x3 << 3)
 #define OMAP_SYSCLKSEL_SHIFT				0
diff --git a/arch/arm/mach-omap2/prm3xxx.c b/arch/arm/mach-omap2/prm3xxx.c
index b86116c..db198d0 100644
--- a/arch/arm/mach-omap2/prm3xxx.c
+++ b/arch/arm/mach-omap2/prm3xxx.c
@@ -383,27 +383,30 @@
 	.read_reset_sources = &omap3xxx_prm_read_reset_sources,
 };
 
-static int __init omap3xxx_prm_init(void)
+int __init omap3xxx_prm_init(void)
+{
+	if (!cpu_is_omap34xx())
+		return 0;
+
+	return prm_register(&omap3xxx_prm_ll_data);
+}
+
+static int __init omap3xxx_prm_late_init(void)
 {
 	int ret;
 
 	if (!cpu_is_omap34xx())
 		return 0;
 
-	ret = prm_register(&omap3xxx_prm_ll_data);
-	if (ret)
-		return ret;
-
 	omap3xxx_prm_enable_io_wakeup();
 	ret = omap_prcm_register_chain_handler(&omap3_prcm_irq_setup);
 	if (!ret)
 		irq_set_status_flags(omap_prcm_event_to_irq("io"),
 				     IRQ_NOAUTOEN);
 
-
 	return ret;
 }
-subsys_initcall(omap3xxx_prm_init);
+subsys_initcall(omap3xxx_prm_late_init);
 
 static void __exit omap3xxx_prm_exit(void)
 {
diff --git a/arch/arm/mach-omap2/prm3xxx.h b/arch/arm/mach-omap2/prm3xxx.h
index 10cd41a..277f717 100644
--- a/arch/arm/mach-omap2/prm3xxx.h
+++ b/arch/arm/mach-omap2/prm3xxx.h
@@ -154,6 +154,7 @@
 
 extern void omap3xxx_prm_dpll3_reset(void);
 
+extern int __init omap3xxx_prm_init(void);
 extern u32 omap3xxx_prm_get_reset_sources(void);
 
 #endif /* __ASSEMBLER */
diff --git a/arch/arm/mach-omap2/prm44xx.c b/arch/arm/mach-omap2/prm44xx.c
index 6d3467a..7498bc7 100644
--- a/arch/arm/mach-omap2/prm44xx.c
+++ b/arch/arm/mach-omap2/prm44xx.c
@@ -346,6 +346,37 @@
 	return r;
 }
 
+/**
+ * omap44xx_prm_was_any_context_lost_old - was module hardware context lost?
+ * @part: PRM partition ID (e.g., OMAP4430_PRM_PARTITION)
+ * @inst: PRM instance offset (e.g., OMAP4430_PRM_MPU_INST)
+ * @idx: CONTEXT register offset
+ *
+ * Return 1 if any bits were set in the *_CONTEXT_* register
+ * identified by (@part, @inst, @idx), which means that some context
+ * was lost for that module; otherwise, return 0.
+ */
+static bool omap44xx_prm_was_any_context_lost_old(u8 part, s16 inst, u16 idx)
+{
+	return (omap4_prminst_read_inst_reg(part, inst, idx)) ? 1 : 0;
+}
+
+/**
+ * omap44xx_prm_clear_context_lost_flags_old - clear context loss flags
+ * @part: PRM partition ID (e.g., OMAP4430_PRM_PARTITION)
+ * @inst: PRM instance offset (e.g., OMAP4430_PRM_MPU_INST)
+ * @idx: CONTEXT register offset
+ *
+ * Clear hardware context loss bits for the module identified by
+ * (@part, @inst, @idx).  No return value.  XXX Writes to reserved bits;
+ * is there a way to avoid this?
+ */
+static void omap44xx_prm_clear_context_loss_flags_old(u8 part, s16 inst,
+						      u16 idx)
+{
+	omap4_prminst_write_inst_reg(0xffffffff, part, inst, idx);
+}
+
 /* Powerdomain low-level functions */
 
 static int omap4_pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst)
@@ -613,24 +644,28 @@
  */
 static struct prm_ll_data omap44xx_prm_ll_data = {
 	.read_reset_sources = &omap44xx_prm_read_reset_sources,
+	.was_any_context_lost_old = &omap44xx_prm_was_any_context_lost_old,
+	.clear_context_loss_flags_old = &omap44xx_prm_clear_context_loss_flags_old,
 };
 
-static int __init omap44xx_prm_init(void)
+int __init omap44xx_prm_init(void)
 {
-	int ret;
-
 	if (!cpu_is_omap44xx())
 		return 0;
 
-	ret = prm_register(&omap44xx_prm_ll_data);
-	if (ret)
-		return ret;
+	return prm_register(&omap44xx_prm_ll_data);
+}
+
+static int __init omap44xx_prm_late_init(void)
+{
+	if (!cpu_is_omap44xx())
+		return 0;
 
 	omap44xx_prm_enable_io_wakeup();
 
 	return omap_prcm_register_chain_handler(&omap4_prcm_irq_setup);
 }
-subsys_initcall(omap44xx_prm_init);
+subsys_initcall(omap44xx_prm_late_init);
 
 static void __exit omap44xx_prm_exit(void)
 {
diff --git a/arch/arm/mach-omap2/prm44xx.h b/arch/arm/mach-omap2/prm44xx.h
index c8e1acc..22b0979 100644
--- a/arch/arm/mach-omap2/prm44xx.h
+++ b/arch/arm/mach-omap2/prm44xx.h
@@ -771,6 +771,7 @@
 extern void omap44xx_prm_save_and_clear_irqen(u32 *saved_mask);
 extern void omap44xx_prm_restore_irqen(u32 *saved_mask);
 
+extern int __init omap44xx_prm_init(void);
 extern u32 omap44xx_prm_get_reset_sources(void);
 
 # endif
diff --git a/arch/arm/mach-omap2/prm_common.c b/arch/arm/mach-omap2/prm_common.c
index f596e1e..228b850 100644
--- a/arch/arm/mach-omap2/prm_common.c
+++ b/arch/arm/mach-omap2/prm_common.c
@@ -365,6 +365,51 @@
 }
 
 /**
+ * prm_was_any_context_lost_old - was device context lost? (old API)
+ * @part: PRM partition ID (e.g., OMAP4430_PRM_PARTITION)
+ * @inst: PRM instance offset (e.g., OMAP4430_PRM_MPU_INST)
+ * @idx: CONTEXT register offset
+ *
+ * Return 1 if any bits were set in the *_CONTEXT_* register
+ * identified by (@part, @inst, @idx), which means that some context
+ * was lost for that module; otherwise, return 0.  XXX Deprecated;
+ * callers need to use a less-SoC-dependent way to identify hardware
+ * IP blocks.
+ */
+bool prm_was_any_context_lost_old(u8 part, s16 inst, u16 idx)
+{
+	bool ret = true;
+
+	if (prm_ll_data->was_any_context_lost_old)
+		ret = prm_ll_data->was_any_context_lost_old(part, inst, idx);
+	else
+		WARN_ONCE(1, "prm: %s: no mapping function defined\n",
+			  __func__);
+
+	return ret;
+}
+
+/**
+ * prm_clear_context_lost_flags_old - clear context loss flags (old API)
+ * @part: PRM partition ID (e.g., OMAP4430_PRM_PARTITION)
+ * @inst: PRM instance offset (e.g., OMAP4430_PRM_MPU_INST)
+ * @idx: CONTEXT register offset
+ *
+ * Clear hardware context loss bits for the module identified by
+ * (@part, @inst, @idx).  No return value.  XXX Deprecated; callers
+ * need to use a less-SoC-dependent way to identify hardware IP
+ * blocks.
+ */
+void prm_clear_context_loss_flags_old(u8 part, s16 inst, u16 idx)
+{
+	if (prm_ll_data->clear_context_loss_flags_old)
+		prm_ll_data->clear_context_loss_flags_old(part, inst, idx);
+	else
+		WARN_ONCE(1, "prm: %s: no mapping function defined\n",
+			  __func__);
+}
+
+/**
  * prm_register - register per-SoC low-level data with the PRM
  * @pld: low-level per-SoC OMAP PRM data & function pointers to register
  *
diff --git a/arch/arm/mach-omap2/scrm44xx.h b/arch/arm/mach-omap2/scrm44xx.h
index 701bf2d..e897ac8 100644
--- a/arch/arm/mach-omap2/scrm44xx.h
+++ b/arch/arm/mach-omap2/scrm44xx.h
@@ -127,12 +127,14 @@
 /* AUXCLKREQ0 */
 #define OMAP4_MAPPING_SHIFT			2
 #define OMAP4_MAPPING_MASK			(0x7 << 2)
+#define OMAP4_MAPPING_WIDTH			3
 #define OMAP4_ACCURACY_SHIFT			1
 #define OMAP4_ACCURACY_MASK			(1 << 1)
 
 /* AUXCLK0 */
 #define OMAP4_CLKDIV_SHIFT			16
 #define OMAP4_CLKDIV_MASK			(0xf << 16)
+#define OMAP4_CLKDIV_WIDTH			4
 #define OMAP4_DISABLECLK_SHIFT			9
 #define OMAP4_DISABLECLK_MASK			(1 << 9)
 #define OMAP4_ENABLE_SHIFT			8
diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c
index aa30a3c..93d1025 100644
--- a/arch/arm/mach-omap2/serial.c
+++ b/arch/arm/mach-omap2/serial.c
@@ -26,9 +26,9 @@
 #include <linux/slab.h>
 #include <linux/pm_runtime.h>
 #include <linux/console.h>
+#include <linux/omap-dma.h>
 
 #include <plat/omap-serial.h>
-#include <plat-omap/dma-omap.h>
 
 #include "common.h"
 #include "omap_hwmod.h"
diff --git a/arch/arm/mach-omap2/sr_device.c b/arch/arm/mach-omap2/sr_device.c
index b0e77a4..b9753fe 100644
--- a/arch/arm/mach-omap2/sr_device.c
+++ b/arch/arm/mach-omap2/sr_device.c
@@ -121,6 +121,19 @@
 	sr_data->senn_mod = 0x1;
 	sr_data->senp_mod = 0x1;
 
+	if (cpu_is_omap34xx() || cpu_is_omap44xx()) {
+		sr_data->err_weight = OMAP3430_SR_ERRWEIGHT;
+		sr_data->err_maxlimit = OMAP3430_SR_ERRMAXLIMIT;
+		sr_data->accum_data = OMAP3430_SR_ACCUMDATA;
+		if (!(strcmp(sr_data->name, "smartreflex_mpu"))) {
+			sr_data->senn_avgweight = OMAP3430_SR1_SENNAVGWEIGHT;
+			sr_data->senp_avgweight = OMAP3430_SR1_SENPAVGWEIGHT;
+		} else {
+			sr_data->senn_avgweight = OMAP3430_SR2_SENNAVGWEIGHT;
+			sr_data->senp_avgweight = OMAP3430_SR2_SENPAVGWEIGHT;
+		}
+	}
+
 	sr_data->voltdm = voltdm_lookup(sr_dev_attr->sensor_voltdm_name);
 	if (!sr_data->voltdm) {
 		pr_err("%s: Unable to get voltage domain pointer for VDD %s\n",
diff --git a/arch/arm/mach-omap2/usb-tusb6010.c b/arch/arm/mach-omap2/usb-tusb6010.c
index a8795ff..c5a3c6f 100644
--- a/arch/arm/mach-omap2/usb-tusb6010.c
+++ b/arch/arm/mach-omap2/usb-tusb6010.c
@@ -27,180 +27,88 @@
 static unsigned		refclk_psec;
 
 
-/* t2_ps, when quantized to fclk units, must happen no earlier than
- * the clock after after t1_NS.
- *
- * Return a possibly updated value of t2_ps, converted to nsec.
- */
-static unsigned
-next_clk(unsigned t1_NS, unsigned t2_ps, unsigned fclk_ps)
-{
-	unsigned	t1_ps = t1_NS * 1000;
-	unsigned	t1_f, t2_f;
-
-	if ((t1_ps + fclk_ps) < t2_ps)
-		return t2_ps / 1000;
-
-	t1_f = (t1_ps + fclk_ps - 1) / fclk_ps;
-	t2_f = (t2_ps + fclk_ps - 1) / fclk_ps;
-
-	if (t1_f >= t2_f)
-		t2_f = t1_f + 1;
-
-	return (t2_f * fclk_ps) / 1000;
-}
-
 /* NOTE:  timings are from tusb 6010 datasheet Rev 1.8, 12-Sept 2006 */
 
-static int tusb_set_async_mode(unsigned sysclk_ps, unsigned fclk_ps)
+static int tusb_set_async_mode(unsigned sysclk_ps)
 {
+	struct gpmc_device_timings dev_t;
 	struct gpmc_timings	t;
 	unsigned		t_acsnh_advnh = sysclk_ps + 3000;
-	unsigned		tmp;
 
-	memset(&t, 0, sizeof(t));
+	memset(&dev_t, 0, sizeof(dev_t));
 
-	/* CS_ON = t_acsnh_acsnl */
-	t.cs_on = 8;
-	/* ADV_ON = t_acsnh_advnh - t_advn */
-	t.adv_on = next_clk(t.cs_on, t_acsnh_advnh - 7000, fclk_ps);
+	dev_t.mux = true;
 
-	/*
-	 * READ ... from omap2420 TRM fig 12-13
-	 */
+	dev_t.t_ceasu = 8 * 1000;
+	dev_t.t_avdasu = t_acsnh_advnh - 7000;
+	dev_t.t_ce_avd = 1000;
+	dev_t.t_avdp_r = t_acsnh_advnh;
+	dev_t.t_oeasu = t_acsnh_advnh + 1000;
+	dev_t.t_oe = 300;
+	dev_t.t_cez_r = 7000;
+	dev_t.t_cez_w = dev_t.t_cez_r;
+	dev_t.t_avdp_w = t_acsnh_advnh;
+	dev_t.t_weasu = t_acsnh_advnh + 1000;
+	dev_t.t_wpl = 300;
+	dev_t.cyc_aavdh_we = 1;
 
-	/* ADV_RD_OFF = t_acsnh_advnh */
-	t.adv_rd_off = next_clk(t.adv_on, t_acsnh_advnh, fclk_ps);
-
-	/* OE_ON = t_acsnh_advnh + t_advn_oen (then wait for nRDY) */
-	t.oe_on = next_clk(t.adv_on, t_acsnh_advnh + 1000, fclk_ps);
-
-	/* ACCESS = counters continue only after nRDY */
-	tmp = t.oe_on * 1000 + 300;
-	t.access = next_clk(t.oe_on, tmp, fclk_ps);
-
-	/* OE_OFF = after data gets sampled */
-	tmp = t.access * 1000;
-	t.oe_off = next_clk(t.access, tmp, fclk_ps);
-
-	t.cs_rd_off = t.oe_off;
-
-	tmp = t.cs_rd_off * 1000 + 7000 /* t_acsn_rdy_z */;
-	t.rd_cycle = next_clk(t.cs_rd_off, tmp, fclk_ps);
-
-	/*
-	 * WRITE ... from omap2420 TRM fig 12-15
-	 */
-
-	/* ADV_WR_OFF = t_acsnh_advnh */
-	t.adv_wr_off = t.adv_rd_off;
-
-	/* WE_ON = t_acsnh_advnh + t_advn_wen (then wait for nRDY) */
-	t.we_on = next_clk(t.adv_wr_off, t_acsnh_advnh + 1000, fclk_ps);
-
-	/* WE_OFF = after data gets sampled */
-	tmp = t.we_on * 1000 + 300;
-	t.we_off = next_clk(t.we_on, tmp, fclk_ps);
-
-	t.cs_wr_off = t.we_off;
-
-	tmp = t.cs_wr_off * 1000 + 7000 /* t_acsn_rdy_z */;
-	t.wr_cycle = next_clk(t.cs_wr_off, tmp, fclk_ps);
+	gpmc_calc_timings(&t, &dev_t);
 
 	return gpmc_cs_set_timings(async_cs, &t);
 }
 
-static int tusb_set_sync_mode(unsigned sysclk_ps, unsigned fclk_ps)
+static int tusb_set_sync_mode(unsigned sysclk_ps)
 {
+	struct gpmc_device_timings dev_t;
 	struct gpmc_timings	t;
 	unsigned		t_scsnh_advnh = sysclk_ps + 3000;
-	unsigned		tmp;
 
-	memset(&t, 0, sizeof(t));
-	t.cs_on = 8;
+	memset(&dev_t, 0, sizeof(dev_t));
 
-	/* ADV_ON = t_acsnh_advnh - t_advn */
-	t.adv_on = next_clk(t.cs_on, t_scsnh_advnh - 7000, fclk_ps);
+	dev_t.mux = true;
+	dev_t.sync_read = true;
+	dev_t.sync_write = true;
 
-	/* GPMC_CLK rate = fclk rate / div */
-	t.sync_clk = 11100 /* 11.1 nsec */;
-	tmp = (t.sync_clk + fclk_ps - 1) / fclk_ps;
-	if (tmp > 4)
-		return -ERANGE;
-	if (tmp == 0)
-		tmp = 1;
-	t.page_burst_access = (fclk_ps * tmp) / 1000;
+	dev_t.clk = 11100;
+	dev_t.t_bacc = 1000;
+	dev_t.t_ces = 1000;
+	dev_t.t_ceasu = 8 * 1000;
+	dev_t.t_avdasu = t_scsnh_advnh - 7000;
+	dev_t.t_ce_avd = 1000;
+	dev_t.t_avdp_r = t_scsnh_advnh;
+	dev_t.cyc_aavdh_oe = 3;
+	dev_t.cyc_oe = 5;
+	dev_t.t_ce_rdyz = 7000;
+	dev_t.t_avdp_w = t_scsnh_advnh;
+	dev_t.cyc_aavdh_we = 3;
+	dev_t.cyc_wpl = 6;
+	dev_t.t_ce_rdyz = 7000;
 
-	/*
-	 * READ ... based on omap2420 TRM fig 12-19, 12-20
-	 */
-
-	/* ADV_RD_OFF = t_scsnh_advnh */
-	t.adv_rd_off = next_clk(t.adv_on, t_scsnh_advnh, fclk_ps);
-
-	/* OE_ON = t_scsnh_advnh + t_advn_oen * fclk_ps (then wait for nRDY) */
-	tmp = (t.adv_rd_off * 1000) + (3 * fclk_ps);
-	t.oe_on = next_clk(t.adv_on, tmp, fclk_ps);
-
-	/* ACCESS = number of clock cycles after t_adv_eon */
-	tmp = (t.oe_on * 1000) + (5 * fclk_ps);
-	t.access = next_clk(t.oe_on, tmp, fclk_ps);
-
-	/* OE_OFF = after data gets sampled */
-	tmp = (t.access * 1000) + (1 * fclk_ps);
-	t.oe_off = next_clk(t.access, tmp, fclk_ps);
-
-	t.cs_rd_off = t.oe_off;
-
-	tmp = t.cs_rd_off * 1000 + 7000 /* t_scsn_rdy_z */;
-	t.rd_cycle = next_clk(t.cs_rd_off, tmp, fclk_ps);
-
-	/*
-	 * WRITE ... based on omap2420 TRM fig 12-21
-	 */
-
-	/* ADV_WR_OFF = t_scsnh_advnh */
-	t.adv_wr_off = t.adv_rd_off;
-
-	/* WE_ON = t_scsnh_advnh + t_advn_wen * fclk_ps (then wait for nRDY) */
-	tmp = (t.adv_wr_off * 1000) + (3 * fclk_ps);
-	t.we_on = next_clk(t.adv_wr_off, tmp, fclk_ps);
-
-	/* WE_OFF = number of clock cycles after t_adv_wen */
-	tmp = (t.we_on * 1000) + (6 * fclk_ps);
-	t.we_off = next_clk(t.we_on, tmp, fclk_ps);
-
-	t.cs_wr_off = t.we_off;
-
-	tmp = t.cs_wr_off * 1000 + 7000 /* t_scsn_rdy_z */;
-	t.wr_cycle = next_clk(t.cs_wr_off, tmp, fclk_ps);
+	gpmc_calc_timings(&t, &dev_t);
 
 	return gpmc_cs_set_timings(sync_cs, &t);
 }
 
-extern unsigned long gpmc_get_fclk_period(void);
-
 /* tusb driver calls this when it changes the chip's clocking */
 int tusb6010_platform_retime(unsigned is_refclk)
 {
 	static const char	error[] =
 		KERN_ERR "tusb6010 %s retime error %d\n";
 
-	unsigned	fclk_ps = gpmc_get_fclk_period();
 	unsigned	sysclk_ps;
 	int		status;
 
-	if (!refclk_psec || fclk_ps == 0)
+	if (!refclk_psec)
 		return -ENODEV;
 
 	sysclk_ps = is_refclk ? refclk_psec : TUSB6010_OSCCLK_60;
 
-	status = tusb_set_async_mode(sysclk_ps, fclk_ps);
+	status = tusb_set_async_mode(sysclk_ps);
 	if (status < 0) {
 		printk(error, "async", status);
 		goto done;
 	}
-	status = tusb_set_sync_mode(sysclk_ps, fclk_ps);
+	status = tusb_set_sync_mode(sysclk_ps);
 	if (status < 0)
 		printk(error, "sync", status);
 done:
@@ -284,7 +192,6 @@
 			| GPMC_CONFIG1_READTYPE_SYNC
 			| GPMC_CONFIG1_WRITEMULTIPLE_SUPP
 			| GPMC_CONFIG1_WRITETYPE_SYNC
-			| GPMC_CONFIG1_CLKACTIVATIONTIME(1)
 			| GPMC_CONFIG1_PAGE_LEN(2)
 			| GPMC_CONFIG1_WAIT_READ_MON
 			| GPMC_CONFIG1_WAIT_WRITE_MON
diff --git a/arch/arm/mach-omap2/vc.c b/arch/arm/mach-omap2/vc.c
index 75878c3..49ac797 100644
--- a/arch/arm/mach-omap2/vc.c
+++ b/arch/arm/mach-omap2/vc.c
@@ -11,13 +11,20 @@
 #include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/bug.h>
+#include <linux/io.h>
 
+#include <asm/div64.h>
+
+#include "iomap.h"
 #include "soc.h"
 #include "voltage.h"
 #include "vc.h"
 #include "prm-regbits-34xx.h"
 #include "prm-regbits-44xx.h"
 #include "prm44xx.h"
+#include "pm.h"
+#include "scrm44xx.h"
+#include "control.h"
 
 /**
  * struct omap_vc_channel_cfg - describe the cfg_channel bitfield
@@ -63,6 +70,9 @@
 };
 
 static struct omap_vc_channel_cfg *vc_cfg_bits;
+
+/* Default I2C trace length on pcb, 6.3cm. Used for capacitance calculations. */
+static u32 sr_i2c_pcb_length = 63;
 #define CFG_CHANNEL_MASK 0x1f
 
 /**
@@ -135,6 +145,8 @@
 	vc_cmdval |= (*target_vsel << vc->common->cmd_on_shift);
 	voltdm->write(vc_cmdval, vc->cmdval_reg);
 
+	voltdm->vc_param->on = target_volt;
+
 	omap_vp_update_errorgain(voltdm, target_volt);
 
 	return 0;
@@ -202,46 +214,389 @@
 	return 0;
 }
 
-static void __init omap3_vfsm_init(struct voltagedomain *voltdm)
+/* Convert microsecond value to number of 32kHz clock cycles */
+static inline u32 omap_usec_to_32k(u32 usec)
 {
+	return DIV_ROUND_UP_ULL(32768ULL * (u64)usec, 1000000ULL);
+}
+
+/* Set oscillator setup time for omap3 */
+static void omap3_set_clksetup(u32 usec, struct voltagedomain *voltdm)
+{
+	voltdm->write(omap_usec_to_32k(usec), OMAP3_PRM_CLKSETUP_OFFSET);
+}
+
+/**
+ * omap3_set_i2c_timings - sets i2c sleep timings for a channel
+ * @voltdm: channel to configure
+ * @off_mode: select whether retention or off mode values used
+ *
+ * Calculates and sets up voltage controller to use I2C based
+ * voltage scaling for sleep modes. This can be used for either off mode
+ * or retention. Off mode has additionally an option to use sys_off_mode
+ * pad, which uses a global signal to program the whole power IC to
+ * off-mode.
+ */
+static void omap3_set_i2c_timings(struct voltagedomain *voltdm, bool off_mode)
+{
+	unsigned long voltsetup1;
+	u32 tgt_volt;
+
 	/*
-	 * Voltage Manager FSM parameters init
-	 * XXX This data should be passed in from the board file
+	 * Oscillator is shut down only if we are using sys_off_mode pad,
+	 * thus we set a minimal setup time here
 	 */
-	voltdm->write(OMAP3_CLKSETUP, OMAP3_PRM_CLKSETUP_OFFSET);
-	voltdm->write(OMAP3_VOLTOFFSET, OMAP3_PRM_VOLTOFFSET_OFFSET);
-	voltdm->write(OMAP3_VOLTSETUP2, OMAP3_PRM_VOLTSETUP2_OFFSET);
+	omap3_set_clksetup(1, voltdm);
+
+	if (off_mode)
+		tgt_volt = voltdm->vc_param->off;
+	else
+		tgt_volt = voltdm->vc_param->ret;
+
+	voltsetup1 = (voltdm->vc_param->on - tgt_volt) /
+			voltdm->pmic->slew_rate;
+
+	voltsetup1 = voltsetup1 * voltdm->sys_clk.rate / 8 / 1000000 + 1;
+
+	voltdm->rmw(voltdm->vfsm->voltsetup_mask,
+		voltsetup1 << __ffs(voltdm->vfsm->voltsetup_mask),
+		voltdm->vfsm->voltsetup_reg);
+
+	/*
+	 * pmic is not controlling the voltage scaling during retention,
+	 * thus set voltsetup2 to 0
+	 */
+	voltdm->write(0, OMAP3_PRM_VOLTSETUP2_OFFSET);
+}
+
+/**
+ * omap3_set_off_timings - sets off-mode timings for a channel
+ * @voltdm: channel to configure
+ *
+ * Calculates and sets up off-mode timings for a channel. Off-mode
+ * can use either I2C based voltage scaling, or alternatively
+ * sys_off_mode pad can be used to send a global command to power IC.
+ * This function first checks which mode is being used, and calls
+ * omap3_set_i2c_timings() if the system is using I2C control mode.
+ * sys_off_mode has the additional benefit that voltages can be
+ * scaled to zero volt level with TWL4030 / TWL5030, I2C can only
+ * scale to 600mV.
+ */
+static void omap3_set_off_timings(struct voltagedomain *voltdm)
+{
+	unsigned long clksetup;
+	unsigned long voltsetup2;
+	unsigned long voltsetup2_old;
+	u32 val;
+	u32 tstart, tshut;
+
+	/* check if sys_off_mode is used to control off-mode voltages */
+	val = voltdm->read(OMAP3_PRM_VOLTCTRL_OFFSET);
+	if (!(val & OMAP3430_SEL_OFF_MASK)) {
+		/* No, omap is controlling them over I2C */
+		omap3_set_i2c_timings(voltdm, true);
+		return;
+	}
+
+	omap_pm_get_oscillator(&tstart, &tshut);
+	omap3_set_clksetup(tstart, voltdm);
+
+	clksetup = voltdm->read(OMAP3_PRM_CLKSETUP_OFFSET);
+
+	/* voltsetup 2 in us */
+	voltsetup2 = voltdm->vc_param->on / voltdm->pmic->slew_rate;
+
+	/* convert to 32k clk cycles */
+	voltsetup2 = DIV_ROUND_UP(voltsetup2 * 32768, 1000000);
+
+	voltsetup2_old = voltdm->read(OMAP3_PRM_VOLTSETUP2_OFFSET);
+
+	/*
+	 * Update voltsetup2 if higher than current value (needed because
+	 * we have multiple channels with different ramp times), also
+	 * update voltoffset always to value recommended by TRM
+	 */
+	if (voltsetup2 > voltsetup2_old) {
+		voltdm->write(voltsetup2, OMAP3_PRM_VOLTSETUP2_OFFSET);
+		voltdm->write(clksetup - voltsetup2,
+			OMAP3_PRM_VOLTOFFSET_OFFSET);
+	} else
+		voltdm->write(clksetup - voltsetup2_old,
+			OMAP3_PRM_VOLTOFFSET_OFFSET);
+
+	/*
+	 * omap is not controlling voltage scaling during off-mode,
+	 * thus set voltsetup1 to 0
+	 */
+	voltdm->rmw(voltdm->vfsm->voltsetup_mask, 0,
+		voltdm->vfsm->voltsetup_reg);
+
+	/* voltoffset must be clksetup minus voltsetup2 according to TRM */
+	voltdm->write(clksetup - voltsetup2, OMAP3_PRM_VOLTOFFSET_OFFSET);
 }
 
 static void __init omap3_vc_init_channel(struct voltagedomain *voltdm)
 {
-	static bool is_initialized;
-
-	if (is_initialized)
-		return;
-
-	omap3_vfsm_init(voltdm);
-
-	is_initialized = true;
+	omap3_set_off_timings(voltdm);
 }
 
+/**
+ * omap4_calc_volt_ramp - calculates voltage ramping delays on omap4
+ * @voltdm: channel to calculate values for
+ * @voltage_diff: voltage difference in microvolts
+ *
+ * Calculates voltage ramp prescaler + counter values for a voltage
+ * difference on omap4. Returns a field value suitable for writing to
+ * VOLTSETUP register for a channel in following format:
+ * bits[8:9] prescaler ... bits[0:5] counter. See OMAP4 TRM for reference.
+ */
+static u32 omap4_calc_volt_ramp(struct voltagedomain *voltdm, u32 voltage_diff)
+{
+	u32 prescaler;
+	u32 cycles;
+	u32 time;
+
+	time = voltage_diff / voltdm->pmic->slew_rate;
+
+	cycles = voltdm->sys_clk.rate / 1000 * time / 1000;
+
+	cycles /= 64;
+	prescaler = 0;
+
+	/* shift to next prescaler until no overflow */
+
+	/* scale for div 256 = 64 * 4 */
+	if (cycles > 63) {
+		cycles /= 4;
+		prescaler++;
+	}
+
+	/* scale for div 512 = 256 * 2 */
+	if (cycles > 63) {
+		cycles /= 2;
+		prescaler++;
+	}
+
+	/* scale for div 2048 = 512 * 4 */
+	if (cycles > 63) {
+		cycles /= 4;
+		prescaler++;
+	}
+
+	/* check for overflow => invalid ramp time */
+	if (cycles > 63) {
+		pr_warn("%s: invalid setuptime for vdd_%s\n", __func__,
+			voltdm->name);
+		return 0;
+	}
+
+	cycles++;
+
+	return (prescaler << OMAP4430_RAMP_UP_PRESCAL_SHIFT) |
+		(cycles << OMAP4430_RAMP_UP_COUNT_SHIFT);
+}
+
+/**
+ * omap4_usec_to_val_scrm - convert microsecond value to SCRM module bitfield
+ * @usec: microseconds
+ * @shift: number of bits to shift left
+ * @mask: bitfield mask
+ *
+ * Converts microsecond value to OMAP4 SCRM bitfield. Bitfield is
+ * shifted to requested position, and checked agains the mask value.
+ * If larger, forced to the max value of the field (i.e. the mask itself.)
+ * Returns the SCRM bitfield value.
+ */
+static u32 omap4_usec_to_val_scrm(u32 usec, int shift, u32 mask)
+{
+	u32 val;
+
+	val = omap_usec_to_32k(usec) << shift;
+
+	/* Check for overflow, if yes, force to max value */
+	if (val > mask)
+		val = mask;
+
+	return val;
+}
+
+/**
+ * omap4_set_timings - set voltage ramp timings for a channel
+ * @voltdm: channel to configure
+ * @off_mode: whether off-mode values are used
+ *
+ * Calculates and sets the voltage ramp up / down values for a channel.
+ */
+static void omap4_set_timings(struct voltagedomain *voltdm, bool off_mode)
+{
+	u32 val;
+	u32 ramp;
+	int offset;
+	u32 tstart, tshut;
+
+	if (off_mode) {
+		ramp = omap4_calc_volt_ramp(voltdm,
+			voltdm->vc_param->on - voltdm->vc_param->off);
+		offset = voltdm->vfsm->voltsetup_off_reg;
+	} else {
+		ramp = omap4_calc_volt_ramp(voltdm,
+			voltdm->vc_param->on - voltdm->vc_param->ret);
+		offset = voltdm->vfsm->voltsetup_reg;
+	}
+
+	if (!ramp)
+		return;
+
+	val = voltdm->read(offset);
+
+	val |= ramp << OMAP4430_RAMP_DOWN_COUNT_SHIFT;
+
+	val |= ramp << OMAP4430_RAMP_UP_COUNT_SHIFT;
+
+	voltdm->write(val, offset);
+
+	omap_pm_get_oscillator(&tstart, &tshut);
+
+	val = omap4_usec_to_val_scrm(tstart, OMAP4_SETUPTIME_SHIFT,
+		OMAP4_SETUPTIME_MASK);
+	val |= omap4_usec_to_val_scrm(tshut, OMAP4_DOWNTIME_SHIFT,
+		OMAP4_DOWNTIME_MASK);
+
+	__raw_writel(val, OMAP4_SCRM_CLKSETUPTIME);
+}
 
 /* OMAP4 specific voltage init functions */
 static void __init omap4_vc_init_channel(struct voltagedomain *voltdm)
 {
-	static bool is_initialized;
-	u32 vc_val;
-
-	if (is_initialized)
-		return;
-
-	/* XXX These are magic numbers and do not belong! */
-	vc_val = (0x60 << OMAP4430_SCLL_SHIFT | 0x26 << OMAP4430_SCLH_SHIFT);
-	voltdm->write(vc_val, OMAP4_PRM_VC_CFG_I2C_CLK_OFFSET);
-
-	is_initialized = true;
+	omap4_set_timings(voltdm, true);
+	omap4_set_timings(voltdm, false);
 }
 
+struct i2c_init_data {
+	u8 loadbits;
+	u8 load;
+	u8 hsscll_38_4;
+	u8 hsscll_26;
+	u8 hsscll_19_2;
+	u8 hsscll_16_8;
+	u8 hsscll_12;
+};
+
+static const __initdata struct i2c_init_data omap4_i2c_timing_data[] = {
+	{
+		.load = 50,
+		.loadbits = 0x3,
+		.hsscll_38_4 = 13,
+		.hsscll_26 = 11,
+		.hsscll_19_2 = 9,
+		.hsscll_16_8 = 9,
+		.hsscll_12 = 8,
+	},
+	{
+		.load = 25,
+		.loadbits = 0x2,
+		.hsscll_38_4 = 13,
+		.hsscll_26 = 11,
+		.hsscll_19_2 = 9,
+		.hsscll_16_8 = 9,
+		.hsscll_12 = 8,
+	},
+	{
+		.load = 12,
+		.loadbits = 0x1,
+		.hsscll_38_4 = 11,
+		.hsscll_26 = 10,
+		.hsscll_19_2 = 9,
+		.hsscll_16_8 = 9,
+		.hsscll_12 = 8,
+	},
+	{
+		.load = 0,
+		.loadbits = 0x0,
+		.hsscll_38_4 = 12,
+		.hsscll_26 = 10,
+		.hsscll_19_2 = 9,
+		.hsscll_16_8 = 8,
+		.hsscll_12 = 8,
+	},
+};
+
+/**
+ * omap4_vc_i2c_timing_init - sets up board I2C timing parameters
+ * @voltdm: voltagedomain pointer to get data from
+ *
+ * Use PMIC + board supplied settings for calculating the total I2C
+ * channel capacitance and set the timing parameters based on this.
+ * Pre-calculated values are provided in data tables, as it is not
+ * too straightforward to calculate these runtime.
+ */
+static void __init omap4_vc_i2c_timing_init(struct voltagedomain *voltdm)
+{
+	u32 capacitance;
+	u32 val;
+	u16 hsscll;
+	const struct i2c_init_data *i2c_data;
+
+	if (!voltdm->pmic->i2c_high_speed) {
+		pr_warn("%s: only high speed supported!\n", __func__);
+		return;
+	}
+
+	/* PCB trace capacitance, 0.125pF / mm => mm / 8 */
+	capacitance = DIV_ROUND_UP(sr_i2c_pcb_length, 8);
+
+	/* OMAP pad capacitance */
+	capacitance += 4;
+
+	/* PMIC pad capacitance */
+	capacitance += voltdm->pmic->i2c_pad_load;
+
+	/* Search for capacitance match in the table */
+	i2c_data = omap4_i2c_timing_data;
+
+	while (i2c_data->load > capacitance)
+		i2c_data++;
+
+	/* Select proper values based on sysclk frequency */
+	switch (voltdm->sys_clk.rate) {
+	case 38400000:
+		hsscll = i2c_data->hsscll_38_4;
+		break;
+	case 26000000:
+		hsscll = i2c_data->hsscll_26;
+		break;
+	case 19200000:
+		hsscll = i2c_data->hsscll_19_2;
+		break;
+	case 16800000:
+		hsscll = i2c_data->hsscll_16_8;
+		break;
+	case 12000000:
+		hsscll = i2c_data->hsscll_12;
+		break;
+	default:
+		pr_warn("%s: unsupported sysclk rate: %d!\n", __func__,
+			voltdm->sys_clk.rate);
+		return;
+	}
+
+	/* Loadbits define pull setup for the I2C channels */
+	val = i2c_data->loadbits << 25 | i2c_data->loadbits << 29;
+
+	/* Write to SYSCTRL_PADCONF_WKUP_CTRL_I2C_2 to setup I2C pull */
+	__raw_writel(val, OMAP2_L4_IO_ADDRESS(OMAP4_CTRL_MODULE_PAD_WKUP +
+				OMAP4_CTRL_MODULE_PAD_WKUP_CONTROL_I2C_2));
+
+	/* HSSCLH can always be zero */
+	val = hsscll << OMAP4430_HSSCLL_SHIFT;
+	val |= (0x28 << OMAP4430_SCLL_SHIFT | 0x2c << OMAP4430_SCLH_SHIFT);
+
+	/* Write setup times to I2C config register */
+	voltdm->write(val, OMAP4_PRM_VC_CFG_I2C_CLK_OFFSET);
+}
+
+
+
 /**
  * omap_vc_i2c_init - initialize I2C interface to PMIC
  * @voltdm: voltage domain containing VC data
@@ -281,9 +636,51 @@
 			    mcode << __ffs(vc->common->i2c_mcode_mask),
 			    vc->common->i2c_cfg_reg);
 
+	if (cpu_is_omap44xx())
+		omap4_vc_i2c_timing_init(voltdm);
+
 	initialized = true;
 }
 
+/**
+ * omap_vc_calc_vsel - calculate vsel value for a channel
+ * @voltdm: channel to calculate value for
+ * @uvolt: microvolt value to convert to vsel
+ *
+ * Converts a microvolt value to vsel value for the used PMIC.
+ * This checks whether the microvolt value is out of bounds, and
+ * adjusts the value accordingly. If unsupported value detected,
+ * warning is thrown.
+ */
+static u8 omap_vc_calc_vsel(struct voltagedomain *voltdm, u32 uvolt)
+{
+	if (voltdm->pmic->vddmin > uvolt)
+		uvolt = voltdm->pmic->vddmin;
+	if (voltdm->pmic->vddmax < uvolt) {
+		WARN(1, "%s: voltage not supported by pmic: %u vs max %u\n",
+			__func__, uvolt, voltdm->pmic->vddmax);
+		/* Lets try maximum value anyway */
+		uvolt = voltdm->pmic->vddmax;
+	}
+
+	return voltdm->pmic->uv_to_vsel(uvolt);
+}
+
+#ifdef CONFIG_PM
+/**
+ * omap_pm_setup_sr_i2c_pcb_length - set length of SR I2C traces on PCB
+ * @mm: length of the PCB trace in millimetres
+ *
+ * Sets the PCB trace length for the I2C channel. By default uses 63mm.
+ * This is needed for properly calculating the capacitance value for
+ * the PCB trace, and for setting the SR I2C channel timing parameters.
+ */
+void __init omap_pm_setup_sr_i2c_pcb_length(u32 mm)
+{
+	sr_i2c_pcb_length = mm;
+}
+#endif
+
 void __init omap_vc_init_channel(struct voltagedomain *voltdm)
 {
 	struct omap_vc_channel *vc = voltdm->vc;
@@ -311,7 +708,6 @@
 	vc->i2c_slave_addr = voltdm->pmic->i2c_slave_addr;
 	vc->volt_reg_addr = voltdm->pmic->volt_reg_addr;
 	vc->cmd_reg_addr = voltdm->pmic->cmd_reg_addr;
-	vc->setup_time = voltdm->pmic->volt_setup_time;
 
 	/* Configure the i2c slave address for this VC */
 	voltdm->rmw(vc->smps_sa_mask,
@@ -331,14 +727,18 @@
 		voltdm->rmw(vc->smps_cmdra_mask,
 			    vc->cmd_reg_addr << __ffs(vc->smps_cmdra_mask),
 			    vc->smps_cmdra_reg);
-		vc->cfg_channel |= vc_cfg_bits->rac | vc_cfg_bits->racen;
+		vc->cfg_channel |= vc_cfg_bits->rac;
 	}
 
+	if (vc->cmd_reg_addr == vc->volt_reg_addr)
+		vc->cfg_channel |= vc_cfg_bits->racen;
+
 	/* Set up the on, inactive, retention and off voltage */
-	on_vsel = voltdm->pmic->uv_to_vsel(voltdm->pmic->on_volt);
-	onlp_vsel = voltdm->pmic->uv_to_vsel(voltdm->pmic->onlp_volt);
-	ret_vsel = voltdm->pmic->uv_to_vsel(voltdm->pmic->ret_volt);
-	off_vsel = voltdm->pmic->uv_to_vsel(voltdm->pmic->off_volt);
+	on_vsel = omap_vc_calc_vsel(voltdm, voltdm->vc_param->on);
+	onlp_vsel = omap_vc_calc_vsel(voltdm, voltdm->vc_param->onlp);
+	ret_vsel = omap_vc_calc_vsel(voltdm, voltdm->vc_param->ret);
+	off_vsel = omap_vc_calc_vsel(voltdm, voltdm->vc_param->off);
+
 	val = ((on_vsel << vc->common->cmd_on_shift) |
 	       (onlp_vsel << vc->common->cmd_onlp_shift) |
 	       (ret_vsel << vc->common->cmd_ret_shift) |
@@ -349,11 +749,6 @@
 	/* Channel configuration */
 	omap_vc_config_channel(voltdm);
 
-	/* Configure the setup times */
-	voltdm->rmw(voltdm->vfsm->voltsetup_mask,
-		    vc->setup_time << __ffs(voltdm->vfsm->voltsetup_mask),
-		    voltdm->vfsm->voltsetup_reg);
-
 	omap_vc_i2c_init(voltdm);
 
 	if (cpu_is_omap34xx())
diff --git a/arch/arm/mach-omap2/vc.h b/arch/arm/mach-omap2/vc.h
index 478bf6b4..91c8d75 100644
--- a/arch/arm/mach-omap2/vc.h
+++ b/arch/arm/mach-omap2/vc.h
@@ -86,7 +86,6 @@
 	u16 i2c_slave_addr;
 	u16 volt_reg_addr;
 	u16 cmd_reg_addr;
-	u16 setup_time;
 	u8 cfg_channel;
 	bool i2c_high_speed;
 
@@ -111,6 +110,13 @@
 extern struct omap_vc_channel omap4_vc_iva;
 extern struct omap_vc_channel omap4_vc_core;
 
+extern struct omap_vc_param omap3_mpu_vc_data;
+extern struct omap_vc_param omap3_core_vc_data;
+
+extern struct omap_vc_param omap4_mpu_vc_data;
+extern struct omap_vc_param omap4_iva_vc_data;
+extern struct omap_vc_param omap4_core_vc_data;
+
 void omap_vc_init_channel(struct voltagedomain *voltdm);
 int omap_vc_pre_scale(struct voltagedomain *voltdm,
 		      unsigned long target_volt,
diff --git a/arch/arm/mach-omap2/vc3xxx_data.c b/arch/arm/mach-omap2/vc3xxx_data.c
index 5d8eaf3..75bc4aa 100644
--- a/arch/arm/mach-omap2/vc3xxx_data.c
+++ b/arch/arm/mach-omap2/vc3xxx_data.c
@@ -71,3 +71,25 @@
 	.smps_cmdra_mask = OMAP3430_CMDRA1_MASK,
 	.cfg_channel_sa_shift = OMAP3430_PRM_VC_SMPS_SA_SA1_SHIFT,
 };
+
+/*
+ * Voltage levels for different operating modes: on, sleep, retention and off
+ */
+#define OMAP3_ON_VOLTAGE_UV		1200000
+#define OMAP3_ONLP_VOLTAGE_UV		1000000
+#define OMAP3_RET_VOLTAGE_UV		975000
+#define OMAP3_OFF_VOLTAGE_UV		600000
+
+struct omap_vc_param omap3_mpu_vc_data = {
+	.on		= OMAP3_ON_VOLTAGE_UV,
+	.onlp		= OMAP3_ONLP_VOLTAGE_UV,
+	.ret		= OMAP3_RET_VOLTAGE_UV,
+	.off		= OMAP3_OFF_VOLTAGE_UV,
+};
+
+struct omap_vc_param omap3_core_vc_data = {
+	.on		= OMAP3_ON_VOLTAGE_UV,
+	.onlp		= OMAP3_ONLP_VOLTAGE_UV,
+	.ret		= OMAP3_RET_VOLTAGE_UV,
+	.off		= OMAP3_OFF_VOLTAGE_UV,
+};
diff --git a/arch/arm/mach-omap2/vc44xx_data.c b/arch/arm/mach-omap2/vc44xx_data.c
index d70b930..085e5d6 100644
--- a/arch/arm/mach-omap2/vc44xx_data.c
+++ b/arch/arm/mach-omap2/vc44xx_data.c
@@ -87,3 +87,31 @@
 	.cfg_channel_sa_shift = OMAP4430_SA_VDD_CORE_L_SHIFT,
 };
 
+/*
+ * Voltage levels for different operating modes: on, sleep, retention and off
+ */
+#define OMAP4_ON_VOLTAGE_UV			1375000
+#define OMAP4_ONLP_VOLTAGE_UV			1375000
+#define OMAP4_RET_VOLTAGE_UV			837500
+#define OMAP4_OFF_VOLTAGE_UV			0
+
+struct omap_vc_param omap4_mpu_vc_data = {
+	.on			= OMAP4_ON_VOLTAGE_UV,
+	.onlp			= OMAP4_ONLP_VOLTAGE_UV,
+	.ret			= OMAP4_RET_VOLTAGE_UV,
+	.off			= OMAP4_OFF_VOLTAGE_UV,
+};
+
+struct omap_vc_param omap4_iva_vc_data = {
+	.on			= OMAP4_ON_VOLTAGE_UV,
+	.onlp			= OMAP4_ONLP_VOLTAGE_UV,
+	.ret			= OMAP4_RET_VOLTAGE_UV,
+	.off			= OMAP4_OFF_VOLTAGE_UV,
+};
+
+struct omap_vc_param omap4_core_vc_data = {
+	.on			= OMAP4_ON_VOLTAGE_UV,
+	.onlp			= OMAP4_ONLP_VOLTAGE_UV,
+	.ret			= OMAP4_RET_VOLTAGE_UV,
+	.off			= OMAP4_OFF_VOLTAGE_UV,
+};
diff --git a/arch/arm/mach-omap2/voltage.h b/arch/arm/mach-omap2/voltage.h
index 7283b7e..a0ce4f1 100644
--- a/arch/arm/mach-omap2/voltage.h
+++ b/arch/arm/mach-omap2/voltage.h
@@ -40,12 +40,14 @@
  * data
  * @voltsetup_mask: SETUP_TIME* bitmask in the PRM_VOLTSETUP* register
  * @voltsetup_reg: register offset of PRM_VOLTSETUP from PRM base
+ * @voltsetup_off_reg: register offset of PRM_VOLTSETUP_OFF from PRM base
  *
  * XXX What about VOLTOFFSET/VOLTCTRL?
  */
 struct omap_vfsm_instance {
 	u32 voltsetup_mask;
 	u8 voltsetup_reg;
+	u8 voltsetup_off_reg;
 };
 
 /**
@@ -74,6 +76,8 @@
 	const struct omap_vfsm_instance *vfsm;
 	struct omap_vp_instance *vp;
 	struct omap_voltdm_pmic *pmic;
+	struct omap_vp_param *vp_param;
+	struct omap_vc_param *vc_param;
 
 	/* VC/VP register access functions: SoC specific */
 	u32 (*read) (u8 offset);
@@ -92,6 +96,24 @@
 	struct omap_volt_data *volt_data;
 };
 
+/* Min and max voltages from OMAP perspective */
+#define OMAP3430_VP1_VLIMITTO_VDDMIN	850000
+#define OMAP3430_VP1_VLIMITTO_VDDMAX	1425000
+#define OMAP3430_VP2_VLIMITTO_VDDMIN	900000
+#define OMAP3430_VP2_VLIMITTO_VDDMAX	1150000
+
+#define OMAP3630_VP1_VLIMITTO_VDDMIN	900000
+#define OMAP3630_VP1_VLIMITTO_VDDMAX	1350000
+#define OMAP3630_VP2_VLIMITTO_VDDMIN	900000
+#define OMAP3630_VP2_VLIMITTO_VDDMAX	1200000
+
+#define OMAP4_VP_MPU_VLIMITTO_VDDMIN	830000
+#define OMAP4_VP_MPU_VLIMITTO_VDDMAX	1410000
+#define OMAP4_VP_IVA_VLIMITTO_VDDMIN	830000
+#define OMAP4_VP_IVA_VLIMITTO_VDDMAX	1260000
+#define OMAP4_VP_CORE_VLIMITTO_VDDMIN	830000
+#define OMAP4_VP_CORE_VLIMITTO_VDDMAX	1200000
+
 /**
  * struct omap_voltdm_pmic - PMIC specific data required by voltage driver.
  * @slew_rate:	PMIC slew rate (in uv/us)
@@ -107,26 +129,34 @@
 struct omap_voltdm_pmic {
 	int slew_rate;
 	int step_size;
-	u32 on_volt;
-	u32 onlp_volt;
-	u32 ret_volt;
-	u32 off_volt;
-	u16 volt_setup_time;
 	u16 i2c_slave_addr;
 	u16 volt_reg_addr;
 	u16 cmd_reg_addr;
 	u8 vp_erroroffset;
 	u8 vp_vstepmin;
 	u8 vp_vstepmax;
-	u8 vp_vddmin;
-	u8 vp_vddmax;
+	u32 vddmin;
+	u32 vddmax;
 	u8 vp_timeout_us;
 	bool i2c_high_speed;
+	u32 i2c_pad_load;
 	u8 i2c_mcode;
 	unsigned long (*vsel_to_uv) (const u8 vsel);
 	u8 (*uv_to_vsel) (unsigned long uV);
 };
 
+struct omap_vp_param {
+	u32 vddmax;
+	u32 vddmin;
+};
+
+struct omap_vc_param {
+	u32 on;
+	u32 onlp;
+	u32 ret;
+	u32 off;
+};
+
 void omap_voltage_get_volttable(struct voltagedomain *voltdm,
 		struct omap_volt_data **volt_data);
 struct omap_volt_data *omap_voltage_get_voltdata(struct voltagedomain *voltdm,
diff --git a/arch/arm/mach-omap2/voltagedomains3xxx_data.c b/arch/arm/mach-omap2/voltagedomains3xxx_data.c
index 63afbfe..261bb7c 100644
--- a/arch/arm/mach-omap2/voltagedomains3xxx_data.c
+++ b/arch/arm/mach-omap2/voltagedomains3xxx_data.c
@@ -117,6 +117,11 @@
 	}
 #endif
 
+	omap3_voltdm_mpu.vp_param = &omap3_mpu_vp_data;
+	omap3_voltdm_core.vp_param = &omap3_core_vp_data;
+	omap3_voltdm_mpu.vc_param = &omap3_mpu_vc_data;
+	omap3_voltdm_core.vc_param = &omap3_core_vc_data;
+
 	if (soc_is_am35xx())
 		voltdms = voltagedomains_am35xx;
 	else
diff --git a/arch/arm/mach-omap2/voltagedomains44xx_data.c b/arch/arm/mach-omap2/voltagedomains44xx_data.c
index c3115f6..48b22a0 100644
--- a/arch/arm/mach-omap2/voltagedomains44xx_data.c
+++ b/arch/arm/mach-omap2/voltagedomains44xx_data.c
@@ -22,7 +22,7 @@
 #include <linux/init.h>
 
 #include "common.h"
-
+#include "soc.h"
 #include "prm-regbits-44xx.h"
 #include "prm44xx.h"
 #include "prcm44xx.h"
@@ -34,14 +34,17 @@
 
 static const struct omap_vfsm_instance omap4_vdd_mpu_vfsm = {
 	.voltsetup_reg = OMAP4_PRM_VOLTSETUP_MPU_RET_SLEEP_OFFSET,
+	.voltsetup_off_reg = OMAP4_PRM_VOLTSETUP_MPU_OFF_OFFSET,
 };
 
 static const struct omap_vfsm_instance omap4_vdd_iva_vfsm = {
 	.voltsetup_reg = OMAP4_PRM_VOLTSETUP_IVA_RET_SLEEP_OFFSET,
+	.voltsetup_off_reg = OMAP4_PRM_VOLTSETUP_IVA_OFF_OFFSET,
 };
 
 static const struct omap_vfsm_instance omap4_vdd_core_vfsm = {
 	.voltsetup_reg = OMAP4_PRM_VOLTSETUP_CORE_RET_SLEEP_OFFSET,
+	.voltsetup_off_reg = OMAP4_PRM_VOLTSETUP_CORE_OFF_OFFSET,
 };
 
 static struct voltagedomain omap4_voltdm_mpu = {
@@ -101,11 +104,25 @@
 	 * 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;
+	if (cpu_is_omap443x()) {
+		omap4_voltdm_mpu.volt_data = omap443x_vdd_mpu_volt_data;
+		omap4_voltdm_iva.volt_data = omap443x_vdd_iva_volt_data;
+		omap4_voltdm_core.volt_data = omap443x_vdd_core_volt_data;
+	} else if (cpu_is_omap446x()) {
+		omap4_voltdm_mpu.volt_data = omap446x_vdd_mpu_volt_data;
+		omap4_voltdm_iva.volt_data = omap446x_vdd_iva_volt_data;
+		omap4_voltdm_core.volt_data = omap446x_vdd_core_volt_data;
+	}
 #endif
 
+	omap4_voltdm_mpu.vp_param = &omap4_mpu_vp_data;
+	omap4_voltdm_iva.vp_param = &omap4_iva_vp_data;
+	omap4_voltdm_core.vp_param = &omap4_core_vp_data;
+
+	omap4_voltdm_mpu.vc_param = &omap4_mpu_vc_data;
+	omap4_voltdm_iva.vc_param = &omap4_iva_vc_data;
+	omap4_voltdm_core.vc_param = &omap4_core_vc_data;
+
 	for (i = 0; voltdm = voltagedomains_omap4[i], voltdm; i++)
 		voltdm->sys_clk.name = sys_clk_name;
 
diff --git a/arch/arm/mach-omap2/vp.c b/arch/arm/mach-omap2/vp.c
index 85241b8..a3c3065 100644
--- a/arch/arm/mach-omap2/vp.c
+++ b/arch/arm/mach-omap2/vp.c
@@ -58,8 +58,10 @@
 	sys_clk_rate = voltdm->sys_clk.rate / 1000;
 
 	timeout = (sys_clk_rate * voltdm->pmic->vp_timeout_us) / 1000;
-	vddmin = voltdm->pmic->vp_vddmin;
-	vddmax = voltdm->pmic->vp_vddmax;
+	vddmin = max(voltdm->vp_param->vddmin, voltdm->pmic->vddmin);
+	vddmax = min(voltdm->vp_param->vddmax, voltdm->pmic->vddmax);
+	vddmin = voltdm->pmic->uv_to_vsel(vddmin);
+	vddmax = voltdm->pmic->uv_to_vsel(vddmax);
 
 	waittime = DIV_ROUND_UP(voltdm->pmic->step_size * sys_clk_rate,
 				1000 * voltdm->pmic->slew_rate);
@@ -138,7 +140,7 @@
 		udelay(1);
 	}
 	if (timeout >= VP_TRANXDONE_TIMEOUT) {
-		pr_warn("%s: vdd_%s TRANXDONE timeout exceeded. Voltage change aborted",
+		pr_warn("%s: vdd_%s TRANXDONE timeout exceeded. Voltage change aborted\n",
 			__func__, voltdm->name);
 		return -ETIMEDOUT;
 	}
@@ -197,7 +199,7 @@
 	u32 vpconfig, volt;
 
 	if (!voltdm || IS_ERR(voltdm)) {
-		pr_warning("%s: VDD specified does not exist!\n", __func__);
+		pr_warn("%s: VDD specified does not exist!\n", __func__);
 		return;
 	}
 
@@ -214,8 +216,8 @@
 
 	volt = voltdm_get_voltage(voltdm);
 	if (!volt) {
-		pr_warning("%s: unable to find current voltage for %s\n",
-			   __func__, voltdm->name);
+		pr_warn("%s: unable to find current voltage for %s\n",
+			__func__, voltdm->name);
 		return;
 	}
 
@@ -242,7 +244,7 @@
 	int timeout;
 
 	if (!voltdm || IS_ERR(voltdm)) {
-		pr_warning("%s: VDD specified does not exist!\n", __func__);
+		pr_warn("%s: VDD specified does not exist!\n", __func__);
 		return;
 	}
 
@@ -272,8 +274,7 @@
 			  VP_IDLE_TIMEOUT, timeout);
 
 	if (timeout >= VP_IDLE_TIMEOUT)
-		pr_warning("%s: vdd_%s idle timedout\n",
-			__func__, voltdm->name);
+		pr_warn("%s: vdd_%s idle timedout\n", __func__, voltdm->name);
 
 	vp->enabled = false;
 
diff --git a/arch/arm/mach-omap2/vp.h b/arch/arm/mach-omap2/vp.h
index 7c155d2..0fdf7080 100644
--- a/arch/arm/mach-omap2/vp.h
+++ b/arch/arm/mach-omap2/vp.h
@@ -117,6 +117,13 @@
 extern struct omap_vp_instance omap4_vp_iva;
 extern struct omap_vp_instance omap4_vp_core;
 
+extern struct omap_vp_param omap3_mpu_vp_data;
+extern struct omap_vp_param omap3_core_vp_data;
+
+extern struct omap_vp_param omap4_mpu_vp_data;
+extern struct omap_vp_param omap4_iva_vp_data;
+extern struct omap_vp_param omap4_core_vp_data;
+
 void omap_vp_init(struct voltagedomain *voltdm);
 void omap_vp_enable(struct voltagedomain *voltdm);
 void omap_vp_disable(struct voltagedomain *voltdm);
diff --git a/arch/arm/mach-omap2/vp3xxx_data.c b/arch/arm/mach-omap2/vp3xxx_data.c
index bd89f80..1914e02 100644
--- a/arch/arm/mach-omap2/vp3xxx_data.c
+++ b/arch/arm/mach-omap2/vp3xxx_data.c
@@ -77,3 +77,13 @@
 	.vstatus = OMAP3_PRM_VP2_STATUS_OFFSET,
 	.voltage = OMAP3_PRM_VP2_VOLTAGE_OFFSET,
 };
+
+struct omap_vp_param omap3_mpu_vp_data = {
+	.vddmin			= OMAP3430_VP1_VLIMITTO_VDDMIN,
+	.vddmax			= OMAP3430_VP1_VLIMITTO_VDDMAX,
+};
+
+struct omap_vp_param omap3_core_vp_data = {
+	.vddmin			= OMAP3430_VP2_VLIMITTO_VDDMIN,
+	.vddmax			= OMAP3430_VP2_VLIMITTO_VDDMAX,
+};
diff --git a/arch/arm/mach-omap2/vp44xx_data.c b/arch/arm/mach-omap2/vp44xx_data.c
index 8c031d1..e62f6b0 100644
--- a/arch/arm/mach-omap2/vp44xx_data.c
+++ b/arch/arm/mach-omap2/vp44xx_data.c
@@ -87,3 +87,18 @@
 	.vstatus = OMAP4_PRM_VP_CORE_STATUS_OFFSET,
 	.voltage = OMAP4_PRM_VP_CORE_VOLTAGE_OFFSET,
 };
+
+struct omap_vp_param omap4_mpu_vp_data = {
+	.vddmin			= OMAP4_VP_MPU_VLIMITTO_VDDMIN,
+	.vddmax			= OMAP4_VP_MPU_VLIMITTO_VDDMAX,
+};
+
+struct omap_vp_param omap4_iva_vp_data = {
+	.vddmin			= OMAP4_VP_IVA_VLIMITTO_VDDMIN,
+	.vddmax			= OMAP4_VP_IVA_VLIMITTO_VDDMAX,
+};
+
+struct omap_vp_param omap4_core_vp_data = {
+	.vddmin			= OMAP4_VP_CORE_VLIMITTO_VDDMIN,
+	.vddmax			= OMAP4_VP_CORE_VLIMITTO_VDDMAX,
+};
diff --git a/arch/arm/mach-s3c24xx/include/mach/bast-map.h b/arch/arm/mach-s3c24xx/include/mach/bast-map.h
index 6e7dc9d..eecea2a 100644
--- a/arch/arm/mach-s3c24xx/include/mach/bast-map.h
+++ b/arch/arm/mach-s3c24xx/include/mach/bast-map.h
@@ -74,7 +74,7 @@
 
 
 /* 0xE0000000 contains the IO space that is split by speed and
- * wether the access is for 8 or 16bit IO... this ensures that
+ * whether the access is for 8 or 16bit IO... this ensures that
  * the correct access is made
  *
  * 0x10000000 of space, partitioned as so:
diff --git a/arch/arm/mach-s3c24xx/include/mach/dma.h b/arch/arm/mach-s3c24xx/include/mach/dma.h
index ee99fd5..6b72d5a 100644
--- a/arch/arm/mach-s3c24xx/include/mach/dma.h
+++ b/arch/arm/mach-s3c24xx/include/mach/dma.h
@@ -88,7 +88,7 @@
  *
  * This represents the state of the DMA engine, wrt to the loaded / running
  * transfers. Since we don't have any way of knowing exactly the state of
- * the DMA transfers, we need to know the state to make decisions on wether
+ * the DMA transfers, we need to know the state to make decisions on whether
  * we can
  *
  * S3C2410_DMA_NONE
diff --git a/arch/arm/mach-s3c24xx/include/mach/vr1000-map.h b/arch/arm/mach-s3c24xx/include/mach/vr1000-map.h
index 99612fc..28376e5 100644
--- a/arch/arm/mach-s3c24xx/include/mach/vr1000-map.h
+++ b/arch/arm/mach-s3c24xx/include/mach/vr1000-map.h
@@ -51,7 +51,7 @@
 #define VR1000_VA_PC104_IRQMASK VR1000_IOADDR(0x00600000)
 
 /* 0xE0000000 contains the IO space that is split by speed and
- * wether the access is for 8 or 16bit IO... this ensures that
+ * whether the access is for 8 or 16bit IO... this ensures that
  * the correct access is made
  *
  * 0x10000000 of space, partitioned as so:
diff --git a/arch/arm/mach-s3c24xx/mach-gta02.c b/arch/arm/mach-s3c24xx/mach-gta02.c
index 4a96346..973b87c 100644
--- a/arch/arm/mach-s3c24xx/mach-gta02.c
+++ b/arch/arm/mach-s3c24xx/mach-gta02.c
@@ -521,7 +521,6 @@
 	&gta02_nor_flash,
 	&s3c24xx_pwm_device,
 	&s3c_device_iis,
-	&samsung_asoc_dma,
 	&s3c_device_i2c0,
 	&gta02_dfbmcs320_device,
 	&gta02_buttons_device,
diff --git a/arch/arm/mach-s3c24xx/mach-h1940.c b/arch/arm/mach-s3c24xx/mach-h1940.c
index 63aaf07..b23dd1b 100644
--- a/arch/arm/mach-s3c24xx/mach-h1940.c
+++ b/arch/arm/mach-s3c24xx/mach-h1940.c
@@ -632,7 +632,6 @@
 	&s3c_device_wdt,
 	&s3c_device_i2c0,
 	&s3c_device_iis,
-	&samsung_asoc_dma,
 	&s3c_device_usbgadget,
 	&h1940_device_leds,
 	&h1940_device_bluetooth,
diff --git a/arch/arm/mach-s3c24xx/mach-mini2440.c b/arch/arm/mach-s3c24xx/mach-mini2440.c
index 393c0f1..a31d5b8 100644
--- a/arch/arm/mach-s3c24xx/mach-mini2440.c
+++ b/arch/arm/mach-s3c24xx/mach-mini2440.c
@@ -519,7 +519,6 @@
 	&s3c_device_iis,
 	&uda1340_codec,
 	&mini2440_audio,
-	&samsung_asoc_dma,
 };
 
 static void __init mini2440_map_io(void)
diff --git a/arch/arm/mach-s3c24xx/mach-rx1950.c b/arch/arm/mach-s3c24xx/mach-rx1950.c
index 379fde5..0606f2f 100644
--- a/arch/arm/mach-s3c24xx/mach-rx1950.c
+++ b/arch/arm/mach-s3c24xx/mach-rx1950.c
@@ -712,7 +712,6 @@
 	&s3c_device_wdt,
 	&s3c_device_i2c0,
 	&s3c_device_iis,
-	&samsung_asoc_dma,
 	&s3c_device_usbgadget,
 	&s3c_device_rtc,
 	&s3c_device_nand,
diff --git a/arch/arm/mach-s3c24xx/pm.c b/arch/arm/mach-s3c24xx/pm.c
index 60627e6..724755f 100644
--- a/arch/arm/mach-s3c24xx/pm.c
+++ b/arch/arm/mach-s3c24xx/pm.c
@@ -121,7 +121,7 @@
 	int pin;
 
 	/* for each of the external interrupts (EINT0..EINT15) we
-	 * need to check wether it is an external interrupt source,
+	 * need to check whether it is an external interrupt source,
 	 * and then configure it as an input if it is not
 	*/
 
diff --git a/arch/arm/mach-s3c64xx/mach-crag6410.c b/arch/arm/mach-s3c64xx/mach-crag6410.c
index 701f421..cdde2491 100644
--- a/arch/arm/mach-s3c64xx/mach-crag6410.c
+++ b/arch/arm/mach-s3c64xx/mach-crag6410.c
@@ -379,7 +379,6 @@
 	&s3c_device_timer[0],
 	&s3c64xx_device_iis0,
 	&s3c64xx_device_iis1,
-	&samsung_asoc_dma,
 	&samsung_device_keypad,
 	&crag6410_gpio_keydev,
 	&crag6410_dm9k_device,
diff --git a/arch/arm/mach-s3c64xx/mach-smdk6410.c b/arch/arm/mach-s3c64xx/mach-smdk6410.c
index da1a771..574a9ee 100644
--- a/arch/arm/mach-s3c64xx/mach-smdk6410.c
+++ b/arch/arm/mach-s3c64xx/mach-smdk6410.c
@@ -275,7 +275,6 @@
 	&s3c_device_fb,
 	&s3c_device_ohci,
 	&s3c_device_usb_hsotg,
-	&samsung_asoc_dma,
 	&s3c64xx_device_iisv4,
 	&samsung_device_keypad,
 
diff --git a/arch/arm/mach-s5p64x0/mach-smdk6440.c b/arch/arm/mach-s5p64x0/mach-smdk6440.c
index 96ea1fe..1af8235 100644
--- a/arch/arm/mach-s5p64x0/mach-smdk6440.c
+++ b/arch/arm/mach-s5p64x0/mach-smdk6440.c
@@ -165,7 +165,6 @@
 	&s3c_device_i2c1,
 	&s3c_device_ts,
 	&s3c_device_wdt,
-	&samsung_asoc_dma,
 	&s5p6440_device_iis,
 	&s3c_device_fb,
 	&smdk6440_lcd_lte480wv,
diff --git a/arch/arm/mach-s5p64x0/mach-smdk6450.c b/arch/arm/mach-s5p64x0/mach-smdk6450.c
index 12748b6..62526cc 100644
--- a/arch/arm/mach-s5p64x0/mach-smdk6450.c
+++ b/arch/arm/mach-s5p64x0/mach-smdk6450.c
@@ -183,7 +183,6 @@
 	&s3c_device_i2c1,
 	&s3c_device_ts,
 	&s3c_device_wdt,
-	&samsung_asoc_dma,
 	&s5p6450_device_iis0,
 	&s3c_device_fb,
 	&smdk6450_lcd_lte480wv,
diff --git a/arch/arm/mach-s5pc100/mach-smdkc100.c b/arch/arm/mach-s5pc100/mach-smdkc100.c
index dba7384..9abe95e 100644
--- a/arch/arm/mach-s5pc100/mach-smdkc100.c
+++ b/arch/arm/mach-s5pc100/mach-smdkc100.c
@@ -197,7 +197,6 @@
 	&s3c_device_ts,
 	&s3c_device_wdt,
 	&smdkc100_lcd_powerdev,
-	&samsung_asoc_dma,
 	&s5pc100_device_iis0,
 	&samsung_device_keypad,
 	&s5pc100_device_ac97,
diff --git a/arch/arm/mach-s5pv210/mach-smdkc110.c b/arch/arm/mach-s5pv210/mach-smdkc110.c
index d9c99fc..f1f3bd3 100644
--- a/arch/arm/mach-s5pv210/mach-smdkc110.c
+++ b/arch/arm/mach-s5pv210/mach-smdkc110.c
@@ -85,7 +85,6 @@
 };
 
 static struct platform_device *smdkc110_devices[] __initdata = {
-	&samsung_asoc_dma,
 	&s5pv210_device_iis0,
 	&s5pv210_device_ac97,
 	&s5pv210_device_spdif,
diff --git a/arch/arm/mach-s5pv210/mach-smdkv210.c b/arch/arm/mach-s5pv210/mach-smdkv210.c
index 4cdb5bb..6bc8404 100644
--- a/arch/arm/mach-s5pv210/mach-smdkv210.c
+++ b/arch/arm/mach-s5pv210/mach-smdkv210.c
@@ -234,7 +234,6 @@
 	&s5pv210_device_ac97,
 	&s5pv210_device_iis0,
 	&s5pv210_device_spdif,
-	&samsung_asoc_dma,
 	&samsung_asoc_idma,
 	&samsung_device_keypad,
 	&smdkv210_dm9000,
diff --git a/arch/arm/mach-shmobile/Kconfig b/arch/arm/mach-shmobile/Kconfig
index 4eddca1..9255546 100644
--- a/arch/arm/mach-shmobile/Kconfig
+++ b/arch/arm/mach-shmobile/Kconfig
@@ -29,6 +29,8 @@
 	select ARM_GIC
 	select CPU_V7
 	select SH_CLK_CPG
+	select USB_ARCH_HAS_EHCI
+	select USB_ARCH_HAS_OHCI
 
 config ARCH_EMEV2
 	bool "Emma Mobile EV2"
diff --git a/arch/arm/mach-shmobile/board-ap4evb.c b/arch/arm/mach-shmobile/board-ap4evb.c
index cefdd03..4065785 100644
--- a/arch/arm/mach-shmobile/board-ap4evb.c
+++ b/arch/arm/mach-shmobile/board-ap4evb.c
@@ -658,133 +658,16 @@
 
 /* FSI */
 #define IRQ_FSI		evt2irq(0x1840)
-static int __fsi_set_rate(struct clk *clk, long rate, int enable)
-{
-	int ret = 0;
-
-	if (rate <= 0)
-		return ret;
-
-	if (enable) {
-		ret = clk_set_rate(clk, rate);
-		if (0 == ret)
-			ret = clk_enable(clk);
-	} else {
-		clk_disable(clk);
-	}
-
-	return ret;
-}
-
-static int __fsi_set_round_rate(struct clk *clk, long rate, int enable)
-{
-	return __fsi_set_rate(clk, clk_round_rate(clk, rate), enable);
-}
-
-static int fsi_ak4642_set_rate(struct device *dev, int rate, int enable)
-{
-	struct clk *fsia_ick;
-	struct clk *fsiack;
-	int ret = -EIO;
-
-	fsia_ick = clk_get(dev, "icka");
-	if (IS_ERR(fsia_ick))
-		return PTR_ERR(fsia_ick);
-
-	/*
-	 * FSIACK is connected to AK4642,
-	 * and use external clock pin from it.
-	 * it is parent of fsia_ick now.
-	 */
-	fsiack = clk_get_parent(fsia_ick);
-	if (!fsiack)
-		goto fsia_ick_out;
-
-	/*
-	 * we get 1/1 divided clock by setting same rate to fsiack and fsia_ick
-	 *
-	 ** FIXME **
-	 * Because the freq_table of external clk (fsiack) are all 0,
-	 * the return value of clk_round_rate became 0.
-	 * So, it use __fsi_set_rate here.
-	 */
-	ret = __fsi_set_rate(fsiack, rate, enable);
-	if (ret < 0)
-		goto fsiack_out;
-
-	ret = __fsi_set_round_rate(fsia_ick, rate, enable);
-	if ((ret < 0) && enable)
-		__fsi_set_round_rate(fsiack, rate, 0); /* disable FSI ACK */
-
-fsiack_out:
-	clk_put(fsiack);
-
-fsia_ick_out:
-	clk_put(fsia_ick);
-
-	return 0;
-}
-
-static int fsi_hdmi_set_rate(struct device *dev, int rate, int enable)
-{
-	struct clk *fsib_clk;
-	struct clk *fdiv_clk = clk_get(NULL, "fsidivb");
-	long fsib_rate = 0;
-	long fdiv_rate = 0;
-	int ackmd_bpfmd;
-	int ret;
-
-	switch (rate) {
-	case 44100:
-		fsib_rate	= rate * 256;
-		ackmd_bpfmd	= SH_FSI_ACKMD_256 | SH_FSI_BPFMD_64;
-		break;
-	case 48000:
-		fsib_rate	= 85428000; /* around 48kHz x 256 x 7 */
-		fdiv_rate	= rate * 256;
-		ackmd_bpfmd	= SH_FSI_ACKMD_256 | SH_FSI_BPFMD_64;
-		break;
-	default:
-		pr_err("unsupported rate in FSI2 port B\n");
-		return -EINVAL;
-	}
-
-	/* FSI B setting */
-	fsib_clk = clk_get(dev, "ickb");
-	if (IS_ERR(fsib_clk))
-		return -EIO;
-
-	ret = __fsi_set_round_rate(fsib_clk, fsib_rate, enable);
-	if (ret < 0)
-		goto fsi_set_rate_end;
-
-	/* FSI DIV setting */
-	ret = __fsi_set_round_rate(fdiv_clk, fdiv_rate, enable);
-	if (ret < 0) {
-		/* disable FSI B */
-		if (enable)
-			__fsi_set_round_rate(fsib_clk, fsib_rate, 0);
-		goto fsi_set_rate_end;
-	}
-
-	ret = ackmd_bpfmd;
-
-fsi_set_rate_end:
-	clk_put(fsib_clk);
-	return ret;
-}
-
 static struct sh_fsi_platform_info fsi_info = {
 	.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_CLK_CPG |
 				  SH_FSI_FMT_SPDIF,
-		.set_rate	= fsi_hdmi_set_rate,
 	},
 };
 
@@ -1144,25 +1027,6 @@
 		clk_put(hdmi_ick);
 }
 
-static void __init fsi_init_pm_clock(void)
-{
-	struct clk *fsia_ick;
-	int ret;
-
-	fsia_ick = clk_get(&fsi_device.dev, "icka");
-	if (IS_ERR(fsia_ick)) {
-		ret = PTR_ERR(fsia_ick);
-		pr_err("Cannot get FSI ICK: %d\n", ret);
-		return;
-	}
-
-	ret = clk_set_parent(fsia_ick, &sh7372_fsiack_clk);
-	if (ret < 0)
-		pr_err("Cannot set FSI-A parent: %d\n", ret);
-
-	clk_put(fsia_ick);
-}
-
 /* TouchScreen */
 #ifdef CONFIG_AP4EVB_QHD
 # define GPIO_TSC_IRQ	GPIO_FN_IRQ28_123
@@ -1476,7 +1340,6 @@
 				       ARRAY_SIZE(domain_devices));
 
 	hdmi_init_pm_clock();
-	fsi_init_pm_clock();
 	sh7372_pm_init();
 	pm_clk_add(&fsi_device.dev, "spu2");
 	pm_clk_add(&lcdc1_device.dev, "hdmi");
diff --git a/arch/arm/mach-shmobile/board-armadillo800eva.c b/arch/arm/mach-shmobile/board-armadillo800eva.c
index 499e6e3..5353adf 100644
--- a/arch/arm/mach-shmobile/board-armadillo800eva.c
+++ b/arch/arm/mach-shmobile/board-armadillo800eva.c
@@ -768,32 +768,6 @@
 };
 
 /* FSI */
-static int fsi_hdmi_set_rate(struct device *dev, int rate, int enable)
-{
-	struct clk *fsib;
-	int ret;
-
-	/* it support 48KHz only */
-	if (48000 != rate)
-		return -EINVAL;
-
-	fsib = clk_get(dev, "ickb");
-	if (IS_ERR(fsib))
-		return -EINVAL;
-
-	if (enable) {
-		ret = SH_FSI_ACKMD_256 | SH_FSI_BPFMD_64;
-		clk_enable(fsib);
-	} else {
-		ret = 0;
-		clk_disable(fsib);
-	}
-
-	clk_put(fsib);
-
-	return ret;
-}
-
 static struct sh_fsi_platform_info fsi_info = {
 	/* FSI-WM8978 */
 	.port_a = {
@@ -802,8 +776,8 @@
 	/* FSI-HDMI */
 	.port_b = {
 		.flags		= SH_FSI_FMT_SPDIF |
-				  SH_FSI_ENABLE_STREAM_MODE,
-		.set_rate	= fsi_hdmi_set_rate,
+				  SH_FSI_ENABLE_STREAM_MODE |
+				  SH_FSI_CLK_CPG,
 		.tx_id		= SHDMA_SLAVE_FSIB_TX,
 	}
 };
@@ -938,13 +912,11 @@
 	struct clk *xtal1	= clk_get(NULL, "extal1");
 	struct clk *usb24s	= clk_get(NULL, "usb24s");
 	struct clk *fsibck	= clk_get(NULL, "fsibck");
-	struct clk *fsib	= clk_get(&fsi_device.dev, "ickb");
 
 	if (IS_ERR(system)	||
 	    IS_ERR(xtal1)	||
 	    IS_ERR(usb24s)	||
-	    IS_ERR(fsibck)	||
-	    IS_ERR(fsib)) {
+	    IS_ERR(fsibck)) {
 		pr_err("armadillo800eva board clock init failed\n");
 		goto clock_error;
 	}
@@ -956,9 +928,7 @@
 	clk_set_parent(usb24s, system);
 
 	/* FSIBCK is 12.288MHz, and it is parent of FSI-B */
-	clk_set_parent(fsib, fsibck);
 	clk_set_rate(fsibck, 12288000);
-	clk_set_rate(fsib,   12288000);
 
 clock_error:
 	if (!IS_ERR(system))
@@ -969,8 +939,6 @@
 		clk_put(usb24s);
 	if (!IS_ERR(fsibck))
 		clk_put(fsibck);
-	if (!IS_ERR(fsib))
-		clk_put(fsib);
 }
 
 /*
diff --git a/arch/arm/mach-shmobile/board-mackerel.c b/arch/arm/mach-shmobile/board-mackerel.c
index f274252..3f56e70 100644
--- a/arch/arm/mach-shmobile/board-mackerel.c
+++ b/arch/arm/mach-shmobile/board-mackerel.c
@@ -816,6 +816,8 @@
 	.id	= 1,
 	.dev = {
 		.platform_data		= &usbhs1_private.info,
+		.dma_mask		= &usbhs1_device.dev.coherent_dma_mask,
+		.coherent_dma_mask	= DMA_BIT_MASK(32),
 	},
 	.num_resources	= ARRAY_SIZE(usbhs1_resources),
 	.resource	= usbhs1_resources,
@@ -860,76 +862,6 @@
 
 /* FSI */
 #define IRQ_FSI evt2irq(0x1840)
-static int __fsi_set_round_rate(struct clk *clk, long rate, int enable)
-{
-	int ret;
-
-	if (rate <= 0)
-		return 0;
-
-	if (!enable) {
-		clk_disable(clk);
-		return 0;
-	}
-
-	ret = clk_set_rate(clk, clk_round_rate(clk, rate));
-	if (ret < 0)
-		return ret;
-
-	return clk_enable(clk);
-}
-
-static int fsi_b_set_rate(struct device *dev, int rate, int enable)
-{
-	struct clk *fsib_clk;
-	struct clk *fdiv_clk = clk_get(NULL, "fsidivb");
-	long fsib_rate = 0;
-	long fdiv_rate = 0;
-	int ackmd_bpfmd;
-	int ret;
-
-	/* clock start */
-	switch (rate) {
-	case 44100:
-		fsib_rate	= rate * 256;
-		ackmd_bpfmd	= SH_FSI_ACKMD_256 | SH_FSI_BPFMD_64;
-		break;
-	case 48000:
-		fsib_rate	= 85428000; /* around 48kHz x 256 x 7 */
-		fdiv_rate	= rate * 256;
-		ackmd_bpfmd	= SH_FSI_ACKMD_256 | SH_FSI_BPFMD_64;
-		break;
-	default:
-		pr_err("unsupported rate in FSI2 port B\n");
-		return -EINVAL;
-	}
-
-	/* FSI B setting */
-	fsib_clk = clk_get(dev, "ickb");
-	if (IS_ERR(fsib_clk))
-		return -EIO;
-
-	/* fsib */
-	ret = __fsi_set_round_rate(fsib_clk, fsib_rate, enable);
-	if (ret < 0)
-		goto fsi_set_rate_end;
-
-	/* FSI DIV */
-	ret = __fsi_set_round_rate(fdiv_clk, fdiv_rate, enable);
-	if (ret < 0) {
-		/* disable FSI B */
-		if (enable)
-			__fsi_set_round_rate(fsib_clk, fsib_rate, 0);
-		goto fsi_set_rate_end;
-	}
-
-	ret = ackmd_bpfmd;
-
-fsi_set_rate_end:
-	clk_put(fsib_clk);
-	return ret;
-}
-
 static struct sh_fsi_platform_info fsi_info = {
 	.port_a = {
 		.flags = SH_FSI_BRS_INV,
@@ -940,8 +872,8 @@
 		.flags = SH_FSI_BRS_INV	|
 			SH_FSI_BRM_INV	|
 			SH_FSI_LRS_INV	|
+			SH_FSI_CLK_CPG	|
 			SH_FSI_FMT_SPDIF,
-		.set_rate = fsi_b_set_rate,
 	}
 };
 
@@ -1018,7 +950,11 @@
 		.start	= 0xe6a30000,
 		.end	= 0xe6a3009b,
 		.flags	= IORESOURCE_MEM,
-	}
+	},
+	[1] = {
+		.start	= evt2irq(0x0d80), /* flstei: status error irq */
+		.flags	= IORESOURCE_IRQ,
+	},
 };
 
 static struct sh_flctl_platform_data nand_flash_data = {
diff --git a/arch/arm/mach-shmobile/board-marzen.c b/arch/arm/mach-shmobile/board-marzen.c
index 69f7f46..449f928 100644
--- a/arch/arm/mach-shmobile/board-marzen.c
+++ b/arch/arm/mach-shmobile/board-marzen.c
@@ -34,6 +34,10 @@
 #include <linux/spi/sh_hspi.h>
 #include <linux/mmc/sh_mobile_sdhi.h>
 #include <linux/mfd/tmio.h>
+#include <linux/usb/otg.h>
+#include <linux/usb/ehci_pdriver.h>
+#include <linux/usb/ohci_pdriver.h>
+#include <linux/pm_runtime.h>
 #include <mach/hardware.h>
 #include <mach/r8a7779.h>
 #include <mach/common.h>
@@ -144,13 +148,185 @@
 	.num_resources	= ARRAY_SIZE(hspi_resources),
 };
 
+/* USB PHY */
+static struct resource usb_phy_resources[] = {
+	[0] = {
+		.start		= 0xffe70000,
+		.end		= 0xffe70900 - 1,
+		.flags		= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start		= 0xfff70000,
+		.end		= 0xfff70900 - 1,
+		.flags		= IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device usb_phy_device = {
+	.name		= "rcar_usb_phy",
+	.resource	= usb_phy_resources,
+	.num_resources	= ARRAY_SIZE(usb_phy_resources),
+};
+
 static struct platform_device *marzen_devices[] __initdata = {
 	&eth_device,
 	&sdhi0_device,
 	&thermal_device,
 	&hspi_device,
+	&usb_phy_device,
 };
 
+/* USB */
+static struct usb_phy *phy;
+static int usb_power_on(struct platform_device *pdev)
+{
+	if (!phy)
+		return -EIO;
+
+	pm_runtime_enable(&pdev->dev);
+	pm_runtime_get_sync(&pdev->dev);
+
+	usb_phy_init(phy);
+
+	return 0;
+}
+
+static void usb_power_off(struct platform_device *pdev)
+{
+	if (!phy)
+		return;
+
+	usb_phy_shutdown(phy);
+
+	pm_runtime_put_sync(&pdev->dev);
+	pm_runtime_disable(&pdev->dev);
+}
+
+static struct usb_ehci_pdata ehcix_pdata = {
+	.power_on	= usb_power_on,
+	.power_off	= usb_power_off,
+	.power_suspend	= usb_power_off,
+};
+
+static struct resource ehci0_resources[] = {
+	[0] = {
+		.start	= 0xffe70000,
+		.end	= 0xffe70400 - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= gic_spi(44),
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device ehci0_device = {
+	.name	= "ehci-platform",
+	.id	= 0,
+	.dev	= {
+		.dma_mask		= &ehci0_device.dev.coherent_dma_mask,
+		.coherent_dma_mask	= 0xffffffff,
+		.platform_data		= &ehcix_pdata,
+	},
+	.num_resources	= ARRAY_SIZE(ehci0_resources),
+	.resource	= ehci0_resources,
+};
+
+static struct resource ehci1_resources[] = {
+	[0] = {
+		.start	= 0xfff70000,
+		.end	= 0xfff70400 - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= gic_spi(45),
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device ehci1_device = {
+	.name	= "ehci-platform",
+	.id	= 1,
+	.dev	= {
+		.dma_mask		= &ehci1_device.dev.coherent_dma_mask,
+		.coherent_dma_mask	= 0xffffffff,
+		.platform_data		= &ehcix_pdata,
+	},
+	.num_resources	= ARRAY_SIZE(ehci1_resources),
+	.resource	= ehci1_resources,
+};
+
+static struct usb_ohci_pdata ohcix_pdata = {
+	.power_on	= usb_power_on,
+	.power_off	= usb_power_off,
+	.power_suspend	= usb_power_off,
+};
+
+static struct resource ohci0_resources[] = {
+	[0] = {
+		.start	= 0xffe70400,
+		.end	= 0xffe70800 - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= gic_spi(44),
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device ohci0_device = {
+	.name	= "ohci-platform",
+	.id	= 0,
+	.dev	= {
+		.dma_mask		= &ohci0_device.dev.coherent_dma_mask,
+		.coherent_dma_mask	= 0xffffffff,
+		.platform_data		= &ohcix_pdata,
+	},
+	.num_resources	= ARRAY_SIZE(ohci0_resources),
+	.resource	= ohci0_resources,
+};
+
+static struct resource ohci1_resources[] = {
+	[0] = {
+		.start	= 0xfff70400,
+		.end	= 0xfff70800 - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= gic_spi(45),
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device ohci1_device = {
+	.name	= "ohci-platform",
+	.id	= 1,
+	.dev	= {
+		.dma_mask		= &ohci1_device.dev.coherent_dma_mask,
+		.coherent_dma_mask	= 0xffffffff,
+		.platform_data		= &ohcix_pdata,
+	},
+	.num_resources	= ARRAY_SIZE(ohci1_resources),
+	.resource	= ohci1_resources,
+};
+
+static struct platform_device *marzen_late_devices[] __initdata = {
+	&ehci0_device,
+	&ehci1_device,
+	&ohci0_device,
+	&ohci1_device,
+};
+
+void __init marzen_init_late(void)
+{
+	/* get usb phy */
+	phy = usb_get_phy(USB_PHY_TYPE_USB2);
+
+	shmobile_init_late();
+	platform_add_devices(marzen_late_devices,
+			     ARRAY_SIZE(marzen_late_devices));
+}
+
 static void __init marzen_init(void)
 {
 	regulator_register_always_on(0, "fixed-3.3V", fixed3v3_power_consumers,
@@ -188,6 +364,14 @@
 	gpio_request(GPIO_FN_HSPI_TX0,	NULL);
 	gpio_request(GPIO_FN_HSPI_RX0,	NULL);
 
+	/* USB (CN21) */
+	gpio_request(GPIO_FN_USB_OVC0, NULL);
+	gpio_request(GPIO_FN_USB_OVC1, NULL);
+	gpio_request(GPIO_FN_USB_OVC2, NULL);
+
+	/* USB (CN22) */
+	gpio_request(GPIO_FN_USB_PENC2, NULL);
+
 	r8a7779_add_standard_devices();
 	platform_add_devices(marzen_devices, ARRAY_SIZE(marzen_devices));
 }
@@ -200,6 +384,6 @@
 	.init_irq	= r8a7779_init_irq,
 	.handle_irq	= gic_handle_irq,
 	.init_machine	= marzen_init,
-	.init_late	= shmobile_init_late,
+	.init_late	= marzen_init_late,
 	.timer		= &shmobile_timer,
 MACHINE_END
diff --git a/arch/arm/mach-tegra/Kconfig b/arch/arm/mach-tegra/Kconfig
index 9ff6f6e..b442f15 100644
--- a/arch/arm/mach-tegra/Kconfig
+++ b/arch/arm/mach-tegra/Kconfig
@@ -55,58 +55,7 @@
 	help
 	  Adds AHB configuration functionality for NVIDIA Tegra SoCs,
 	  which controls AHB bus master arbitration and some
-	  perfomance parameters(priority, prefech size).
-
-choice
-        prompt "Default low-level debug console UART"
-        default TEGRA_DEBUG_UART_NONE
-
-config TEGRA_DEBUG_UART_NONE
-        bool "None"
-
-config TEGRA_DEBUG_UARTA
-        bool "UART-A"
-
-config TEGRA_DEBUG_UARTB
-        bool "UART-B"
-
-config TEGRA_DEBUG_UARTC
-        bool "UART-C"
-
-config TEGRA_DEBUG_UARTD
-        bool "UART-D"
-
-config TEGRA_DEBUG_UARTE
-        bool "UART-E"
-
-endchoice
-
-choice
-	prompt "Automatic low-level debug console UART"
-	default TEGRA_DEBUG_UART_AUTO_NONE
-
-config TEGRA_DEBUG_UART_AUTO_NONE
-	bool "None"
-
-config TEGRA_DEBUG_UART_AUTO_ODMDATA
-	bool "Via ODMDATA"
-	help
-	  Automatically determines which UART to use for low-level debug based
-	  on the ODMDATA value. This value is part of the BCT, and is written
-	  to the boot memory device using nvflash, or other flashing tool.
-	  When bits 19:18 are 3, then bits 17:15 indicate which UART to use;
-	  0/1/2/3/4 are UART A/B/C/D/E.
-
-config TEGRA_DEBUG_UART_AUTO_SCRATCH
-	bool "Via UART scratch register"
-	help
-	  Automatically determines which UART to use for low-level debug based
-	  on the UART scratch register value. Some bootloaders put ASCII 'D'
-	  in this register when they initialize their own console UART output.
-	  Using this option allows the kernel to automatically pick the same
-	  UART.
-
-endchoice
+	  performance parameters(priority, prefech size).
 
 config TEGRA_EMC_SCALING_ENABLE
 	bool "Enable scaling the memory frequency"
diff --git a/arch/arm/mach-tegra/common.c b/arch/arm/mach-tegra/common.c
index 11a74db..0816562 100644
--- a/arch/arm/mach-tegra/common.c
+++ b/arch/arm/mach-tegra/common.c
@@ -45,14 +45,15 @@
  * 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] = {
+u32 tegra_uart_config[4] = {
 	/* Debug UART initialization required */
 	1,
 	/* Debug UART physical address */
-	(u32)(IO_APB_PHYS + TEGRA_DEBUG_UART_OFFSET),
+	0,
 	/* Debug UART virtual address */
-	(u32)(IO_APB_VIRT + TEGRA_DEBUG_UART_OFFSET),
+	0,
+	/* Scratch space for debug macro */
+	0,
 };
 
 #ifdef CONFIG_OF
diff --git a/arch/arm/mach-tegra/include/mach/debug-macro.S b/arch/arm/mach-tegra/include/mach/debug-macro.S
deleted file mode 100644
index 44ca7b1..0000000
--- a/arch/arm/mach-tegra/include/mach/debug-macro.S
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * arch/arm/mach-tegra/include/mach/debug-macro.S
- *
- * 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
- * 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/serial_reg.h>
-
-#include "../../iomap.h"
-#include "../../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	senduart, rd, rx
-		tst	\rx, #0x0000ff00
-		strneb	\rd, [\rx, #UART_TX << UART_SHIFT]
-1001:
-		.endm
-
-		.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/irqs.h b/arch/arm/mach-tegra/include/mach/irqs.h
deleted file mode 100644
index aad1a2c..0000000
--- a/arch/arm/mach-tegra/include/mach/irqs.h
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- * arch/arm/mach-tegra/include/mach/irqs.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_IRQS_H
-#define __MACH_TEGRA_IRQS_H
-
-#define INT_GIC_BASE			0
-
-#define IRQ_LOCALTIMER                  29
-
-/* Primary Interrupt Controller */
-#define INT_PRI_BASE			(INT_GIC_BASE + 32)
-#define INT_TMR1			(INT_PRI_BASE + 0)
-#define INT_TMR2			(INT_PRI_BASE + 1)
-#define INT_RTC				(INT_PRI_BASE + 2)
-#define INT_I2S2			(INT_PRI_BASE + 3)
-#define INT_SHR_SEM_INBOX_IBF		(INT_PRI_BASE + 4)
-#define INT_SHR_SEM_INBOX_IBE		(INT_PRI_BASE + 5)
-#define INT_SHR_SEM_OUTBOX_IBF		(INT_PRI_BASE + 6)
-#define INT_SHR_SEM_OUTBOX_IBE		(INT_PRI_BASE + 7)
-#define INT_VDE_UCQ_ERROR		(INT_PRI_BASE + 8)
-#define INT_VDE_SYNC_TOKEN		(INT_PRI_BASE + 9)
-#define INT_VDE_BSE_V			(INT_PRI_BASE + 10)
-#define INT_VDE_BSE_A			(INT_PRI_BASE + 11)
-#define INT_VDE_SXE			(INT_PRI_BASE + 12)
-#define INT_I2S1			(INT_PRI_BASE + 13)
-#define INT_SDMMC1			(INT_PRI_BASE + 14)
-#define INT_SDMMC2			(INT_PRI_BASE + 15)
-#define INT_XIO				(INT_PRI_BASE + 16)
-#define INT_VDE				(INT_PRI_BASE + 17)
-#define INT_AVP_UCQ			(INT_PRI_BASE + 18)
-#define INT_SDMMC3			(INT_PRI_BASE + 19)
-#define INT_USB				(INT_PRI_BASE + 20)
-#define INT_USB2			(INT_PRI_BASE + 21)
-#define INT_PRI_RES_22			(INT_PRI_BASE + 22)
-#define INT_EIDE			(INT_PRI_BASE + 23)
-#define INT_NANDFLASH			(INT_PRI_BASE + 24)
-#define INT_VCP				(INT_PRI_BASE + 25)
-#define INT_APB_DMA			(INT_PRI_BASE + 26)
-#define INT_AHB_DMA			(INT_PRI_BASE + 27)
-#define INT_GNT_0			(INT_PRI_BASE + 28)
-#define INT_GNT_1			(INT_PRI_BASE + 29)
-#define INT_OWR				(INT_PRI_BASE + 30)
-#define INT_SDMMC4			(INT_PRI_BASE + 31)
-
-/* Secondary Interrupt Controller */
-#define INT_SEC_BASE			(INT_PRI_BASE + 32)
-#define INT_GPIO1			(INT_SEC_BASE + 0)
-#define INT_GPIO2			(INT_SEC_BASE + 1)
-#define INT_GPIO3			(INT_SEC_BASE + 2)
-#define INT_GPIO4			(INT_SEC_BASE + 3)
-#define INT_UARTA			(INT_SEC_BASE + 4)
-#define INT_UARTB			(INT_SEC_BASE + 5)
-#define INT_I2C				(INT_SEC_BASE + 6)
-#define INT_SPI				(INT_SEC_BASE + 7)
-#define INT_TWC				(INT_SEC_BASE + 8)
-#define INT_TMR3			(INT_SEC_BASE + 9)
-#define INT_TMR4			(INT_SEC_BASE + 10)
-#define INT_FLOW_RSM0			(INT_SEC_BASE + 11)
-#define INT_FLOW_RSM1			(INT_SEC_BASE + 12)
-#define INT_SPDIF			(INT_SEC_BASE + 13)
-#define INT_UARTC			(INT_SEC_BASE + 14)
-#define INT_MIPI			(INT_SEC_BASE + 15)
-#define INT_EVENTA			(INT_SEC_BASE + 16)
-#define INT_EVENTB			(INT_SEC_BASE + 17)
-#define INT_EVENTC			(INT_SEC_BASE + 18)
-#define INT_EVENTD			(INT_SEC_BASE + 19)
-#define INT_VFIR			(INT_SEC_BASE + 20)
-#define INT_DVC				(INT_SEC_BASE + 21)
-#define INT_SYS_STATS_MON		(INT_SEC_BASE + 22)
-#define INT_GPIO5			(INT_SEC_BASE + 23)
-#define INT_CPU0_PMU_INTR		(INT_SEC_BASE + 24)
-#define INT_CPU1_PMU_INTR		(INT_SEC_BASE + 25)
-#define INT_SEC_RES_26			(INT_SEC_BASE + 26)
-#define INT_S_LINK1			(INT_SEC_BASE + 27)
-#define INT_APB_DMA_COP			(INT_SEC_BASE + 28)
-#define INT_AHB_DMA_COP			(INT_SEC_BASE + 29)
-#define INT_DMA_TX			(INT_SEC_BASE + 30)
-#define INT_DMA_RX			(INT_SEC_BASE + 31)
-
-/* Tertiary Interrupt Controller */
-#define INT_TRI_BASE			(INT_SEC_BASE + 32)
-#define INT_HOST1X_COP_SYNCPT		(INT_TRI_BASE + 0)
-#define INT_HOST1X_MPCORE_SYNCPT	(INT_TRI_BASE + 1)
-#define INT_HOST1X_COP_GENERAL		(INT_TRI_BASE + 2)
-#define INT_HOST1X_MPCORE_GENERAL	(INT_TRI_BASE + 3)
-#define INT_MPE_GENERAL			(INT_TRI_BASE + 4)
-#define INT_VI_GENERAL			(INT_TRI_BASE + 5)
-#define INT_EPP_GENERAL			(INT_TRI_BASE + 6)
-#define INT_ISP_GENERAL			(INT_TRI_BASE + 7)
-#define INT_2D_GENERAL			(INT_TRI_BASE + 8)
-#define INT_DISPLAY_GENERAL		(INT_TRI_BASE + 9)
-#define INT_DISPLAY_B_GENERAL		(INT_TRI_BASE + 10)
-#define INT_HDMI			(INT_TRI_BASE + 11)
-#define INT_TVO_GENERAL			(INT_TRI_BASE + 12)
-#define INT_MC_GENERAL			(INT_TRI_BASE + 13)
-#define INT_EMC_GENERAL			(INT_TRI_BASE + 14)
-#define INT_TRI_RES_15			(INT_TRI_BASE + 15)
-#define INT_TRI_RES_16			(INT_TRI_BASE + 16)
-#define INT_AC97			(INT_TRI_BASE + 17)
-#define INT_SPI_2			(INT_TRI_BASE + 18)
-#define INT_SPI_3			(INT_TRI_BASE + 19)
-#define INT_I2C2			(INT_TRI_BASE + 20)
-#define INT_KBC				(INT_TRI_BASE + 21)
-#define INT_EXTERNAL_PMU		(INT_TRI_BASE + 22)
-#define INT_GPIO6			(INT_TRI_BASE + 23)
-#define INT_TVDAC			(INT_TRI_BASE + 24)
-#define INT_GPIO7			(INT_TRI_BASE + 25)
-#define INT_UARTD			(INT_TRI_BASE + 26)
-#define INT_UARTE			(INT_TRI_BASE + 27)
-#define INT_I2C3			(INT_TRI_BASE + 28)
-#define INT_SPI_4			(INT_TRI_BASE + 29)
-#define INT_TRI_RES_30			(INT_TRI_BASE + 30)
-#define INT_SW_RESERVED			(INT_TRI_BASE + 31)
-
-/* Quaternary Interrupt Controller */
-#define INT_QUAD_BASE			(INT_TRI_BASE + 32)
-#define INT_SNOR			(INT_QUAD_BASE + 0)
-#define INT_USB3			(INT_QUAD_BASE + 1)
-#define INT_PCIE_INTR			(INT_QUAD_BASE + 2)
-#define INT_PCIE_MSI			(INT_QUAD_BASE + 3)
-#define INT_QUAD_RES_4			(INT_QUAD_BASE + 4)
-#define INT_QUAD_RES_5			(INT_QUAD_BASE + 5)
-#define INT_QUAD_RES_6			(INT_QUAD_BASE + 6)
-#define INT_QUAD_RES_7			(INT_QUAD_BASE + 7)
-#define INT_APB_DMA_CH0			(INT_QUAD_BASE + 8)
-#define INT_APB_DMA_CH1			(INT_QUAD_BASE + 9)
-#define INT_APB_DMA_CH2			(INT_QUAD_BASE + 10)
-#define INT_APB_DMA_CH3			(INT_QUAD_BASE + 11)
-#define INT_APB_DMA_CH4			(INT_QUAD_BASE + 12)
-#define INT_APB_DMA_CH5			(INT_QUAD_BASE + 13)
-#define INT_APB_DMA_CH6			(INT_QUAD_BASE + 14)
-#define INT_APB_DMA_CH7			(INT_QUAD_BASE + 15)
-#define INT_APB_DMA_CH8			(INT_QUAD_BASE + 16)
-#define INT_APB_DMA_CH9			(INT_QUAD_BASE + 17)
-#define INT_APB_DMA_CH10		(INT_QUAD_BASE + 18)
-#define INT_APB_DMA_CH11		(INT_QUAD_BASE + 19)
-#define INT_APB_DMA_CH12		(INT_QUAD_BASE + 20)
-#define INT_APB_DMA_CH13		(INT_QUAD_BASE + 21)
-#define INT_APB_DMA_CH14		(INT_QUAD_BASE + 22)
-#define INT_APB_DMA_CH15		(INT_QUAD_BASE + 23)
-#define INT_QUAD_RES_24			(INT_QUAD_BASE + 24)
-#define INT_QUAD_RES_25			(INT_QUAD_BASE + 25)
-#define INT_QUAD_RES_26			(INT_QUAD_BASE + 26)
-#define INT_QUAD_RES_27			(INT_QUAD_BASE + 27)
-#define INT_QUAD_RES_28			(INT_QUAD_BASE + 28)
-#define INT_QUAD_RES_29			(INT_QUAD_BASE + 29)
-#define INT_QUAD_RES_30			(INT_QUAD_BASE + 30)
-#define INT_QUAD_RES_31			(INT_QUAD_BASE + 31)
-
-/* Tegra30 has 5 banks of 32 IRQs */
-#define INT_MAIN_NR			(32 * 5)
-#define INT_GPIO_BASE			(INT_PRI_BASE + INT_MAIN_NR)
-
-/* Tegra30 has 8 banks of 32 GPIOs */
-#define INT_GPIO_NR			(32 * 8)
-
-#define TEGRA_NR_IRQS			(INT_GPIO_BASE + INT_GPIO_NR)
-
-#define INT_BOARD_BASE			TEGRA_NR_IRQS
-#define NR_BOARD_IRQS			32
-
-#define NR_IRQS				(INT_BOARD_BASE + NR_BOARD_IRQS)
-
-#endif
diff --git a/arch/arm/mach-tegra/include/mach/uncompress.h b/arch/arm/mach-tegra/include/mach/uncompress.h
index 2772575..485003f 100644
--- a/arch/arm/mach-tegra/include/mach/uncompress.h
+++ b/arch/arm/mach-tegra/include/mach/uncompress.h
@@ -29,7 +29,6 @@
 #include <linux/serial_reg.h>
 
 #include "../../iomap.h"
-#include "../../irammap.h"
 
 #define BIT(x) (1 << (x))
 #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
@@ -52,17 +51,6 @@
 {
 }
 
-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;
-}
-
 static const struct {
 	u32 base;
 	u32 reset_reg;
@@ -139,51 +127,19 @@
 }
 #endif
 
-#ifdef CONFIG_TEGRA_DEBUG_UART_AUTO_SCRATCH
-int auto_scratch(void)
-{
-	int i;
-
-	/*
-	 * 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 (!uart_clocked(i))
-			continue;
-
-		uart = (volatile u8 *)uarts[i].base;
-		if (uart[UART_SCR << DEBUG_UART_SHIFT] != 'D')
-			continue;
-
-		return i;
-	}
-
-	return -1;
-}
-#endif
-
 /*
  * 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)
 {
-	int uart_id, auto_uart_id;
+	int uart_id;
 	volatile u32 *apb_misc = (volatile u32 *)TEGRA_APB_MISC_BASE;
 	u32 chip, div;
 
-#if defined(CONFIG_TEGRA_DEBUG_UARTA)
+#if defined(CONFIG_TEGRA_DEBUG_UART_AUTO_ODMDATA)
+	uart_id = auto_odmdata();
+#elif defined(CONFIG_TEGRA_DEBUG_UARTA)
 	uart_id = 0;
 #elif defined(CONFIG_TEGRA_DEBUG_UARTB)
 	uart_id = 1;
@@ -193,27 +149,14 @@
 	uart_id = 3;
 #elif defined(CONFIG_TEGRA_DEBUG_UARTE)
 	uart_id = 4;
-#else
-	uart_id = -1;
 #endif
 
-#if defined(CONFIG_TEGRA_DEBUG_UART_AUTO_ODMDATA)
-	auto_uart_id = auto_odmdata();
-#elif defined(CONFIG_TEGRA_DEBUG_UART_AUTO_SCRATCH)
-	auto_uart_id = auto_scratch();
-#else
-	auto_uart_id = -1;
-#endif
-	if (auto_uart_id != -1)
-		uart_id = auto_uart_id;
-
 	if (uart_id < 0 || uart_id >= ARRAY_SIZE(uarts) ||
 	    !uart_clocked(uart_id))
 		uart = NULL;
 	else
 		uart = (volatile u8 *)uarts[uart_id].base;
 
-	save_uart_address();
 	if (uart == NULL)
 		return;
 
diff --git a/arch/arm/mach-tegra/io.c b/arch/arm/mach-tegra/io.c
index 7d09f30..bb9c9c2 100644
--- a/arch/arm/mach-tegra/io.c
+++ b/arch/arm/mach-tegra/io.c
@@ -59,5 +59,6 @@
 
 void __init tegra_map_common_io(void)
 {
+	debug_ll_io_init();
 	iotable_init(tegra_io_desc, ARRAY_SIZE(tegra_io_desc));
 }
diff --git a/arch/arm/mach-tegra/iomap.h b/arch/arm/mach-tegra/iomap.h
index 5315103..db8be51 100644
--- a/arch/arm/mach-tegra/iomap.h
+++ b/arch/arm/mach-tegra/iomap.h
@@ -261,20 +261,6 @@
 #define TEGRA_SDMMC4_BASE		0xC8000600
 #define TEGRA_SDMMC4_SIZE		SZ_512
 
-#if defined(CONFIG_TEGRA_DEBUG_UART_NONE)
-# define TEGRA_DEBUG_UART_BASE 0
-#elif defined(CONFIG_TEGRA_DEBUG_UARTA)
-# define TEGRA_DEBUG_UART_BASE TEGRA_UARTA_BASE
-#elif defined(CONFIG_TEGRA_DEBUG_UARTB)
-# define TEGRA_DEBUG_UART_BASE TEGRA_UARTB_BASE
-#elif defined(CONFIG_TEGRA_DEBUG_UARTC)
-# define TEGRA_DEBUG_UART_BASE TEGRA_UARTC_BASE
-#elif defined(CONFIG_TEGRA_DEBUG_UARTD)
-# define TEGRA_DEBUG_UART_BASE TEGRA_UARTD_BASE
-#elif defined(CONFIG_TEGRA_DEBUG_UARTE)
-# define TEGRA_DEBUG_UART_BASE TEGRA_UARTE_BASE
-#endif
-
 /* On TEGRA, many peripherals are very closely packed in
  * two 256MB io windows (that actually only use about 64KB
  * at the start of each).
diff --git a/arch/arm/mach-tegra/irammap.h b/arch/arm/mach-tegra/irammap.h
index 0cbe632..501952a 100644
--- a/arch/arm/mach-tegra/irammap.h
+++ b/arch/arm/mach-tegra/irammap.h
@@ -23,13 +23,4 @@
 #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/pcie.c b/arch/arm/mach-tegra/pcie.c
index f18fc3a..53d0858 100644
--- a/arch/arm/mach-tegra/pcie.c
+++ b/arch/arm/mach-tegra/pcie.c
@@ -43,6 +43,9 @@
 #include "board.h"
 #include "iomap.h"
 
+/* Hack - need to parse this from DT */
+#define INT_PCIE_INTR 130
+
 /* register definitions */
 #define AFI_OFFSET	0x3800
 #define PADS_OFFSET	0x3000
diff --git a/arch/arm/mach-tegra/timer.c b/arch/arm/mach-tegra/timer.c
index 6ff5035..e4863f3 100644
--- a/arch/arm/mach-tegra/timer.c
+++ b/arch/arm/mach-tegra/timer.c
@@ -26,16 +26,14 @@
 #include <linux/clocksource.h>
 #include <linux/clk.h>
 #include <linux/io.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
 
 #include <asm/mach/time.h>
 #include <asm/smp_twd.h>
 #include <asm/sched_clock.h>
 
-#include <mach/irqs.h>
-
 #include "board.h"
-#include "clock.h"
-#include "iomap.h"
 
 #define RTC_SECONDS            0x08
 #define RTC_SHADOW_SECONDS     0x0c
@@ -53,8 +51,8 @@
 #define TIMER_PTV 0x0
 #define TIMER_PCR 0x4
 
-static void __iomem *timer_reg_base = IO_ADDRESS(TEGRA_TMR1_BASE);
-static void __iomem *rtc_base = IO_ADDRESS(TEGRA_RTC_BASE);
+static void __iomem *timer_reg_base;
+static void __iomem *rtc_base;
 
 static struct timespec persistent_ts;
 static u64 persistent_ms, last_persistent_ms;
@@ -158,40 +156,66 @@
 	.flags		= IRQF_DISABLED | IRQF_TIMER | IRQF_TRIGGER_HIGH,
 	.handler	= tegra_timer_interrupt,
 	.dev_id		= &tegra_clockevent,
-	.irq		= INT_TMR3,
 };
 
-#ifdef CONFIG_HAVE_ARM_TWD
-static DEFINE_TWD_LOCAL_TIMER(twd_local_timer,
-			      TEGRA_ARM_PERIF_BASE + 0x600,
-			      IRQ_LOCALTIMER);
+static const struct of_device_id timer_match[] __initconst = {
+	{ .compatible = "nvidia,tegra20-timer" },
+	{}
+};
 
-static void __init tegra_twd_init(void)
-{
-	int err = twd_local_timer_register(&twd_local_timer);
-	if (err)
-		pr_err("twd_local_timer_register failed %d\n", err);
-}
-#else
-#define tegra_twd_init()	do {} while(0)
-#endif
+static const struct of_device_id rtc_match[] __initconst = {
+	{ .compatible = "nvidia,tegra20-rtc" },
+	{}
+};
 
 static void __init tegra_init_timer(void)
 {
+	struct device_node *np;
 	struct clk *clk;
 	unsigned long rate;
 	int ret;
 
+	np = of_find_matching_node(NULL, timer_match);
+	if (!np) {
+		pr_err("Failed to find timer DT node\n");
+		BUG();
+	}
+
+	timer_reg_base = of_iomap(np, 0);
+	if (!timer_reg_base) {
+		pr_err("Can't map timer registers");
+		BUG();
+	}
+
+	tegra_timer_irq.irq = irq_of_parse_and_map(np, 2);
+	if (tegra_timer_irq.irq <= 0) {
+		pr_err("Failed to map timer IRQ\n");
+		BUG();
+	}
+
 	clk = clk_get_sys("timer", NULL);
 	if (IS_ERR(clk)) {
-		pr_warn("Unable to get timer clock."
-			" Assuming 12Mhz input clock.\n");
+		pr_warn("Unable to get timer clock. Assuming 12Mhz input clock.\n");
 		rate = 12000000;
 	} else {
 		clk_prepare_enable(clk);
 		rate = clk_get_rate(clk);
 	}
 
+	of_node_put(np);
+
+	np = of_find_matching_node(NULL, rtc_match);
+	if (!np) {
+		pr_err("Failed to find RTC DT node\n");
+		BUG();
+	}
+
+	rtc_base = of_iomap(np, 0);
+	if (!rtc_base) {
+		pr_err("Can't map RTC registers");
+		BUG();
+	}
+
 	/*
 	 * rtc registers are used by read_persistent_clock, keep the rtc clock
 	 * enabled
@@ -202,6 +226,8 @@
 	else
 		clk_prepare_enable(clk);
 
+	of_node_put(np);
+
 	switch (rate) {
 	case 12000000:
 		timer_writel(0x000b, TIMERUS_USEC_CFG);
@@ -223,13 +249,13 @@
 
 	if (clocksource_mmio_init(timer_reg_base + TIMERUS_CNTR_1US,
 		"timer_us", 1000000, 300, 32, clocksource_mmio_readl_up)) {
-		printk(KERN_ERR "Failed to register clocksource\n");
+		pr_err("Failed to register clocksource\n");
 		BUG();
 	}
 
 	ret = setup_irq(tegra_timer_irq.irq, &tegra_timer_irq);
 	if (ret) {
-		printk(KERN_ERR "Failed to register timer IRQ: %d\n", ret);
+		pr_err("Failed to register timer IRQ: %d\n", ret);
 		BUG();
 	}
 
@@ -241,7 +267,9 @@
 	tegra_clockevent.cpumask = cpu_all_mask;
 	tegra_clockevent.irq = tegra_timer_irq.irq;
 	clockevents_register_device(&tegra_clockevent);
-	tegra_twd_init();
+#ifdef CONFIG_HAVE_ARM_TWD
+	twd_local_timer_of_register();
+#endif
 	register_persistent_clock(NULL, tegra_read_persistent_clock);
 }
 
diff --git a/arch/arm/mach-ux500/Kconfig b/arch/arm/mach-ux500/Kconfig
index e8c3f0d..5dea906 100644
--- a/arch/arm/mach-ux500/Kconfig
+++ b/arch/arm/mach-ux500/Kconfig
@@ -7,8 +7,8 @@
 	select ARM_ERRATA_764369 if SMP
 	select ARM_GIC
 	select CACHE_L2X0
+	select CLKSRC_NOMADIK_MTU
 	select COMMON_CLK
-	select HAS_MTU
 	select PINCTRL
 	select PINCTRL_NOMADIK
 	select PL310_ERRATA_753970 if CACHE_PL310
diff --git a/arch/arm/mach-ux500/board-mop500-audio.c b/arch/arm/mach-ux500/board-mop500-audio.c
index 33631c9..7209db7 100644
--- a/arch/arm/mach-ux500/board-mop500-audio.c
+++ b/arch/arm/mach-ux500/board-mop500-audio.c
@@ -8,8 +8,7 @@
 #include <linux/init.h>
 #include <linux/gpio.h>
 #include <linux/platform_data/pinctrl-nomadik.h>
-
-#include <plat/ste_dma40.h>
+#include <linux/platform_data/dma-ste-dma40.h>
 
 #include <mach/devices.h>
 #include <mach/hardware.h>
@@ -149,15 +148,6 @@
 	},
 };
 
-/* Platform device for Ux500-PCM */
-static struct platform_device ux500_pcm = {
-		.name = "ux500-pcm",
-		.id = 0,
-		.dev = {
-			.platform_data = NULL,
-		},
-};
-
 struct msp_i2s_platform_data msp2_platform_data = {
 	.id = MSP_I2S_2,
 	.msp_i2s_dma_rx = &msp2_dma_rx,
@@ -185,10 +175,3 @@
 	db8500_add_msp_i2s(parent, 3, U8500_MSP3_BASE, IRQ_DB8500_MSP1,
 			   &msp3_platform_data);
 }
-
-/* Due for removal once the MSP driver has been fully DT:ed. */
-void mop500_of_audio_init(struct device *parent)
-{
-	pr_info("%s: Register platform-device 'ux500-pcm'\n", __func__);
-	platform_device_register(&ux500_pcm);
-}
diff --git a/arch/arm/mach-ux500/board-mop500-pins.c b/arch/arm/mach-ux500/board-mop500-pins.c
index c34d4ef..0a3f30d 100644
--- a/arch/arm/mach-ux500/board-mop500-pins.c
+++ b/arch/arm/mach-ux500/board-mop500-pins.c
@@ -33,8 +33,6 @@
 BIAS(in_nopull_slpm_nowkup, PIN_INPUT_NOPULL|PIN_SLPM_WAKEUP_DISABLE);
 BIAS(in_pu, PIN_INPUT_PULLUP);
 BIAS(in_pd, PIN_INPUT_PULLDOWN);
-BIAS(in_pd_slpm_in_pu, PIN_INPUT_PULLDOWN|PIN_SLPM_INPUT_PULLUP);
-BIAS(in_pu_slpm_out_lo, PIN_INPUT_PULLUP|PIN_SLPM_OUTPUT_LOW);
 BIAS(out_hi, PIN_OUTPUT_HIGH);
 BIAS(out_lo, PIN_OUTPUT_LOW);
 BIAS(out_lo_slpm_nowkup, PIN_OUTPUT_LOW|PIN_SLPM_WAKEUP_DISABLE);
@@ -46,14 +44,34 @@
 BIAS(gpio_out_hi, PIN_OUTPUT_HIGH|PIN_GPIOMODE_ENABLED);
 BIAS(gpio_out_lo, PIN_OUTPUT_LOW|PIN_GPIOMODE_ENABLED);
 /* Sleep modes */
-BIAS(slpm_in_wkup_pdis, PIN_SLEEPMODE_ENABLED|PIN_SLPM_DIR_INPUT|PIN_SLPM_WAKEUP_ENABLE|PIN_SLPM_PDIS_DISABLED);
-BIAS(slpm_in_nopull_wkup, PIN_SLEEPMODE_ENABLED|PIN_SLPM_DIR_INPUT|PIN_SLPM_PULL_NONE|PIN_SLPM_WAKEUP_ENABLE);
-BIAS(slpm_wkup_pdis, PIN_SLEEPMODE_ENABLED|PIN_SLPM_WAKEUP_ENABLE|PIN_SLPM_PDIS_DISABLED);
-BIAS(slpm_out_hi_wkup_pdis, PIN_SLEEPMODE_ENABLED|PIN_SLPM_OUTPUT_HIGH|PIN_SLPM_WAKEUP_ENABLE|PIN_SLPM_PDIS_DISABLED);
-BIAS(slpm_out_wkup_pdis, PIN_SLEEPMODE_ENABLED|PIN_SLPM_WAKEUP_ENABLE|PIN_SLPM_PDIS_DISABLED);
-BIAS(slpm_out_lo_wkup, PIN_SLEEPMODE_ENABLED|PIN_SLPM_OUTPUT_LOW|PIN_SLPM_WAKEUP_ENABLE);
-BIAS(slpm_out_lo_wkup_pdis, PIN_SLEEPMODE_ENABLED|PIN_SLPM_OUTPUT_LOW|PIN_SLPM_WAKEUP_ENABLE|PIN_SLPM_PDIS_DISABLED);
-BIAS(slpm_in_nopull_wkup_pdis, PIN_SLEEPMODE_ENABLED|PIN_SLPM_INPUT_NOPULL|PIN_SLPM_WAKEUP_ENABLE|PIN_SLPM_PDIS_DISABLED);
+BIAS(slpm_in_nopull_wkup, PIN_SLEEPMODE_ENABLED|
+	PIN_SLPM_DIR_INPUT|PIN_SLPM_PULL_NONE|PIN_SLPM_WAKEUP_ENABLE);
+BIAS(slpm_in_wkup_pdis, PIN_SLEEPMODE_ENABLED|
+	PIN_SLPM_DIR_INPUT|PIN_SLPM_WAKEUP_ENABLE|PIN_SLPM_PDIS_DISABLED);
+BIAS(slpm_wkup_pdis, PIN_SLEEPMODE_ENABLED|
+	PIN_SLPM_WAKEUP_ENABLE|PIN_SLPM_PDIS_DISABLED);
+BIAS(slpm_out_lo_pdis, PIN_SLEEPMODE_ENABLED|
+	PIN_SLPM_OUTPUT_LOW|PIN_SLPM_WAKEUP_DISABLE|PIN_SLPM_PDIS_DISABLED);
+BIAS(slpm_out_lo_wkup, PIN_SLEEPMODE_ENABLED|
+	PIN_SLPM_OUTPUT_LOW|PIN_SLPM_WAKEUP_ENABLE);
+BIAS(slpm_out_lo_wkup_pdis, PIN_SLEEPMODE_ENABLED|
+	PIN_SLPM_OUTPUT_LOW|PIN_SLPM_WAKEUP_ENABLE|PIN_SLPM_PDIS_DISABLED);
+BIAS(slpm_out_hi_wkup_pdis, PIN_SLEEPMODE_ENABLED|PIN_SLPM_OUTPUT_HIGH|
+	PIN_SLPM_WAKEUP_ENABLE|PIN_SLPM_PDIS_DISABLED);
+BIAS(slpm_in_nopull_wkup_pdis, PIN_SLEEPMODE_ENABLED|
+	PIN_SLPM_INPUT_NOPULL|PIN_SLPM_WAKEUP_ENABLE|PIN_SLPM_PDIS_DISABLED);
+BIAS(slpm_in_pu_wkup_pdis_en, PIN_SLEEPMODE_ENABLED|PIN_SLPM_INPUT_PULLUP|
+	PIN_SLPM_WAKEUP_ENABLE|PIN_SLPM_PDIS_ENABLED);
+BIAS(slpm_out_wkup_pdis, PIN_SLEEPMODE_ENABLED|
+	PIN_SLPM_DIR_OUTPUT|PIN_SLPM_WAKEUP_ENABLE|PIN_SLPM_PDIS_DISABLED);
+BIAS(out_lo_wkup_pdis, PIN_SLPM_OUTPUT_LOW|
+	PIN_SLPM_WAKEUP_ENABLE|PIN_SLPM_PDIS_DISABLED);
+BIAS(in_wkup_pdis_en, PIN_SLPM_DIR_INPUT|PIN_SLPM_WAKEUP_ENABLE|
+	PIN_SLPM_PDIS_ENABLED);
+BIAS(in_wkup_pdis, PIN_SLPM_DIR_INPUT|PIN_SLPM_WAKEUP_ENABLE|
+	PIN_SLPM_PDIS_DISABLED);
+BIAS(out_wkup_pdis, PIN_SLPM_DIR_OUTPUT|PIN_SLPM_WAKEUP_ENABLE|
+	PIN_SLPM_PDIS_DISABLED);
 
 /* We use these to define hog settings that are always done on boot */
 #define DB8500_MUX_HOG(group,func) \
@@ -69,13 +87,16 @@
 	PIN_MAP_MUX_GROUP_DEFAULT(dev, "pinctrl-db8500", group, func)
 #define DB8500_PIN(pin,conf,dev) \
 	PIN_MAP_CONFIGS_PIN_DEFAULT(dev, "pinctrl-db8500", pin, conf)
+#define DB8500_PIN_IDLE(pin, conf, dev) \
+	PIN_MAP_CONFIGS_PIN(dev, PINCTRL_STATE_IDLE, "pinctrl-db8500",	\
+			    pin, conf)
 #define DB8500_PIN_SLEEP(pin, conf, dev) \
 	PIN_MAP_CONFIGS_PIN(dev, PINCTRL_STATE_SLEEP, "pinctrl-db8500",	\
 			    pin, conf)
-
-#define DB8500_PIN_SLEEP(pin,conf,dev) \
-	PIN_MAP_CONFIGS_PIN(dev, PINCTRL_STATE_SLEEP, "pinctrl-db8500",	\
-			    pin, conf)
+#define DB8500_MUX_STATE(group, func, dev, state) \
+	PIN_MAP_MUX_GROUP(dev, state, "pinctrl-db8500", group, func)
+#define DB8500_PIN_STATE(pin, conf, dev, state) \
+	PIN_MAP_CONFIGS_PIN(dev, state, "pinctrl-db8500", pin, conf)
 
 /* Pin control settings */
 static struct pinctrl_map __initdata mop500_family_pinmap[] = {
@@ -112,7 +133,7 @@
 	 * UART0, we do not mux in u0 here.
 	 * uart-0 pins gpio configuration should be kept intact to prevent
 	 * a glitch in tx line when the tty dev is opened. Later these pins
-	 * are configured to uart mop500_pins_uart0
+	 * are configured by uart driver
 	 */
 	DB8500_PIN_HOG("GPIO0_AJ5", in_pu), /* CTS */
 	DB8500_PIN_HOG("GPIO1_AJ3", out_hi), /* RTS */
@@ -123,12 +144,13 @@
 	 * TODO: is this used on U8500 variants and Snowball really?
 	 * The setting on GPIO31 conflicts with magnetometer use on hrefv60
 	 */
-	DB8500_MUX_HOG("u2rxtx_c_1", "u2"),
-	DB8500_MUX_HOG("u2ctsrts_c_1", "u2"),
-	DB8500_PIN_HOG("GPIO29_W2", in_pu), /* RXD */
-	DB8500_PIN_HOG("GPIO30_W3", out_hi), /* TXD */
-	DB8500_PIN_HOG("GPIO31_V3", in_pu), /* CTS */
-	DB8500_PIN_HOG("GPIO32_V2", out_hi), /* RTS */
+	/* default state for UART2 */
+	DB8500_MUX("u2rxtx_c_1", "u2", "uart2"),
+	DB8500_PIN("GPIO29_W2", in_pu, "uart2"), /* RXD */
+	DB8500_PIN("GPIO30_W3", out_hi, "uart2"), /* TXD */
+	/* Sleep state for UART2 */
+	DB8500_PIN_SLEEP("GPIO29_W2", in_wkup_pdis, "uart2"),
+	DB8500_PIN_SLEEP("GPIO30_W3", out_wkup_pdis, "uart2"),
 	/*
 	 * The following pin sets were known as "runtime pins" before being
 	 * converted to the pinctrl model. Here we model them as "default"
@@ -140,11 +162,18 @@
 	DB8500_PIN("GPIO1_AJ3", out_hi, "uart0"), /* RTS */
 	DB8500_PIN("GPIO2_AH4", in_pu, "uart0"), /* RXD */
 	DB8500_PIN("GPIO3_AH3", out_hi, "uart0"), /* TXD */
-	/* UART0 sleep state */
+	/* Sleep state for UART0 */
 	DB8500_PIN_SLEEP("GPIO0_AJ5", slpm_in_wkup_pdis, "uart0"),
 	DB8500_PIN_SLEEP("GPIO1_AJ3", slpm_out_hi_wkup_pdis, "uart0"),
 	DB8500_PIN_SLEEP("GPIO2_AH4", slpm_in_wkup_pdis, "uart0"),
 	DB8500_PIN_SLEEP("GPIO3_AH3", slpm_out_wkup_pdis, "uart0"),
+	/* Mux in UART1 after initialization */
+	DB8500_MUX("u1rxtx_a_1", "u1", "uart1"),
+	DB8500_PIN("GPIO4_AH6", in_pu, "uart1"), /* RXD */
+	DB8500_PIN("GPIO5_AG6", out_hi, "uart1"), /* TXD */
+	/* Sleep state for UART1 */
+	DB8500_PIN_SLEEP("GPIO4_AH6", slpm_in_wkup_pdis, "uart1"),
+	DB8500_PIN_SLEEP("GPIO5_AG6", slpm_out_wkup_pdis, "uart1"),
 	/* MSP1 for ALSA codec */
 	DB8500_MUX("msp1txrx_a_1", "msp1", "ux500-msp-i2s.1"),
 	DB8500_MUX("msp1_a_1", "msp1", "ux500-msp-i2s.1"),
@@ -161,7 +190,10 @@
 	DB8500_MUX("lcd_d8_d11_a_1", "lcd", "mcde-tvout"),
 	DB8500_MUX("lcdaclk_b_1", "lcda", "mcde-tvout"),
 	/* Mux in LCD VSI1 and pull it up for MCDE HDMI output */
-	DB8500_MUX("lcdvsi1_a_1", "lcd", "av8100-hdmi"),
+	DB8500_MUX("lcdvsi1_a_1", "lcd", "0-0070"),
+	DB8500_PIN("GPIO69_E2", in_pu, "0-0070"),
+	/* LCD VSI1 sleep state */
+	DB8500_PIN_SLEEP("GPIO69_E2", slpm_in_wkup_pdis, "0-0070"),
 	/* Mux in i2c0 block, default state */
 	DB8500_MUX("i2c0_a_1", "i2c0", "nmk-i2c.0"),
 	/* i2c0 sleep state */
@@ -194,6 +226,18 @@
 	DB8500_PIN("GPIO26_Y2", in_pu, "sdi0"), /* DAT1 */
 	DB8500_PIN("GPIO27_AA2", in_pu, "sdi0"), /* DAT2 */
 	DB8500_PIN("GPIO28_AA1", in_pu, "sdi0"), /* DAT3 */
+	/* SDI0 sleep state */
+	DB8500_PIN_SLEEP("GPIO18_AC2", slpm_out_hi_wkup_pdis, "sdi0"),
+	DB8500_PIN_SLEEP("GPIO19_AC1", slpm_out_hi_wkup_pdis, "sdi0"),
+	DB8500_PIN_SLEEP("GPIO20_AB4", slpm_out_hi_wkup_pdis, "sdi0"),
+	DB8500_PIN_SLEEP("GPIO22_AA3", slpm_in_wkup_pdis, "sdi0"),
+	DB8500_PIN_SLEEP("GPIO23_AA4", slpm_out_lo_wkup_pdis, "sdi0"),
+	DB8500_PIN_SLEEP("GPIO24_AB2", slpm_in_wkup_pdis, "sdi0"),
+	DB8500_PIN_SLEEP("GPIO25_Y4", slpm_in_wkup_pdis, "sdi0"),
+	DB8500_PIN_SLEEP("GPIO26_Y2", slpm_in_wkup_pdis, "sdi0"),
+	DB8500_PIN_SLEEP("GPIO27_AA2", slpm_in_wkup_pdis, "sdi0"),
+	DB8500_PIN_SLEEP("GPIO28_AA1", slpm_in_wkup_pdis, "sdi0"),
+
 	/* Mux in SDI1 (here called MC1) used for SDIO for CW1200 WLAN */
 	DB8500_MUX("mc1_a_1", "mc1", "sdi1"),
 	DB8500_PIN("GPIO208_AH16", out_lo, "sdi1"), /* CLK */
@@ -203,6 +247,15 @@
 	DB8500_PIN("GPIO212_AF13", in_pu, "sdi1"), /* DAT1 */
 	DB8500_PIN("GPIO213_AG13", in_pu, "sdi1"), /* DAT2 */
 	DB8500_PIN("GPIO214_AH15", in_pu, "sdi1"), /* DAT3 */
+	/* SDI1 sleep state */
+	DB8500_PIN_SLEEP("GPIO208_AH16", slpm_out_lo_wkup_pdis, "sdi1"), /* CLK */
+	DB8500_PIN_SLEEP("GPIO209_AG15", slpm_in_wkup_pdis, "sdi1"), /* FBCLK */
+	DB8500_PIN_SLEEP("GPIO210_AJ15", slpm_in_wkup_pdis, "sdi1"), /* CMD */
+	DB8500_PIN_SLEEP("GPIO211_AG14", slpm_in_wkup_pdis, "sdi1"), /* DAT0 */
+	DB8500_PIN_SLEEP("GPIO212_AF13", slpm_in_wkup_pdis, "sdi1"), /* DAT1 */
+	DB8500_PIN_SLEEP("GPIO213_AG13", slpm_in_wkup_pdis, "sdi1"), /* DAT2 */
+	DB8500_PIN_SLEEP("GPIO214_AH15", slpm_in_wkup_pdis, "sdi1"), /* DAT3 */
+
 	/* Mux in SDI2 (here called MC2) used for for PoP eMMC */
 	DB8500_MUX("mc2_a_1", "mc2", "sdi2"),
 	DB8500_PIN("GPIO128_A5", out_lo, "sdi2"), /* CLK */
@@ -216,6 +269,19 @@
 	DB8500_PIN("GPIO136_C7", in_pu, "sdi2"), /* DAT5 */
 	DB8500_PIN("GPIO137_A7", in_pu, "sdi2"), /* DAT6 */
 	DB8500_PIN("GPIO138_C5", in_pu, "sdi2"), /* DAT7 */
+	/* SDI2 sleep state */
+	DB8500_PIN_SLEEP("GPIO128_A5", out_lo_wkup_pdis, "sdi2"), /* CLK */
+	DB8500_PIN_SLEEP("GPIO129_B4", in_wkup_pdis_en, "sdi2"), /* CMD */
+	DB8500_PIN_SLEEP("GPIO130_C8", in_wkup_pdis_en, "sdi2"), /* FBCLK */
+	DB8500_PIN_SLEEP("GPIO131_A12", in_wkup_pdis, "sdi2"), /* DAT0 */
+	DB8500_PIN_SLEEP("GPIO132_C10", in_wkup_pdis, "sdi2"), /* DAT1 */
+	DB8500_PIN_SLEEP("GPIO133_B10", in_wkup_pdis, "sdi2"), /* DAT2 */
+	DB8500_PIN_SLEEP("GPIO134_B9", in_wkup_pdis, "sdi2"), /* DAT3 */
+	DB8500_PIN_SLEEP("GPIO135_A9", in_wkup_pdis, "sdi2"), /* DAT4 */
+	DB8500_PIN_SLEEP("GPIO136_C7", in_wkup_pdis, "sdi2"), /* DAT5 */
+	DB8500_PIN_SLEEP("GPIO137_A7", in_wkup_pdis, "sdi2"), /* DAT6 */
+	DB8500_PIN_SLEEP("GPIO138_C5", in_wkup_pdis, "sdi2"), /* DAT7 */
+
 	/* Mux in SDI4 (here called MC4) used for for PCB-mounted eMMC */
 	DB8500_MUX("mc4_a_1", "mc4", "sdi4"),
 	DB8500_PIN("GPIO197_AH24", in_pu, "sdi4"), /* DAT3 */
@@ -229,6 +295,19 @@
 	DB8500_PIN("GPIO205_AG23", in_pu, "sdi4"), /* DAT6 */
 	DB8500_PIN("GPIO206_AG24", in_pu, "sdi4"), /* DAT5 */
 	DB8500_PIN("GPIO207_AJ23", in_pu, "sdi4"), /* DAT4 */
+	/*SDI4 sleep state */
+	DB8500_PIN_SLEEP("GPIO197_AH24", slpm_in_wkup_pdis, "sdi4"), /* DAT3 */
+	DB8500_PIN_SLEEP("GPIO198_AG25", slpm_in_wkup_pdis, "sdi4"), /* DAT2 */
+	DB8500_PIN_SLEEP("GPIO199_AH23", slpm_in_wkup_pdis, "sdi4"), /* DAT1 */
+	DB8500_PIN_SLEEP("GPIO200_AH26", slpm_in_wkup_pdis, "sdi4"), /* DAT0 */
+	DB8500_PIN_SLEEP("GPIO201_AF24", slpm_in_wkup_pdis, "sdi4"), /* CMD */
+	DB8500_PIN_SLEEP("GPIO202_AF25", slpm_in_wkup_pdis, "sdi4"), /* FBCLK */
+	DB8500_PIN_SLEEP("GPIO203_AE23", slpm_out_lo_wkup_pdis, "sdi4"), /* CLK */
+	DB8500_PIN_SLEEP("GPIO204_AF23", slpm_in_wkup_pdis, "sdi4"), /* DAT7 */
+	DB8500_PIN_SLEEP("GPIO205_AG23", slpm_in_wkup_pdis, "sdi4"), /* DAT6 */
+	DB8500_PIN_SLEEP("GPIO206_AG24", slpm_in_wkup_pdis, "sdi4"), /* DAT5 */
+	DB8500_PIN_SLEEP("GPIO207_AJ23", slpm_in_wkup_pdis, "sdi4"), /* DAT4 */
+
 	/* Mux in USB pins, drive STP high */
 	DB8500_MUX("usb_a_1", "usb", "musb-ux500.0"),
 	DB8500_PIN("GPIO257_AE29", out_hi, "musb-ux500.0"), /* STP */
@@ -238,10 +317,232 @@
 	DB8500_PIN("GPIO218_AH11", in_pd, "spi2"), /* RXD */
 	DB8500_PIN("GPIO215_AH13", out_lo, "spi2"), /* TXD */
 	DB8500_PIN("GPIO217_AH12", out_lo, "spi2"), /* CLK */
-	/* SPI2 sleep state */
+	/* SPI2 idle state */
 	DB8500_PIN_SLEEP("GPIO218_AH11", slpm_in_wkup_pdis, "spi2"), /* RXD */
 	DB8500_PIN_SLEEP("GPIO215_AH13", slpm_out_lo_wkup_pdis, "spi2"), /* TXD */
 	DB8500_PIN_SLEEP("GPIO217_AH12", slpm_wkup_pdis, "spi2"), /* CLK */
+	/* SPI2 sleep state */
+	DB8500_PIN_SLEEP("GPIO216_AG12", slpm_in_wkup_pdis, "spi2"), /* FRM */
+	DB8500_PIN_SLEEP("GPIO218_AH11", slpm_in_wkup_pdis, "spi2"), /* RXD */
+	DB8500_PIN_SLEEP("GPIO215_AH13", slpm_out_lo_wkup_pdis, "spi2"), /* TXD */
+	DB8500_PIN_SLEEP("GPIO217_AH12", slpm_wkup_pdis, "spi2"), /* CLK */
+
+	/* ske default state */
+	DB8500_MUX("kp_a_2", "kp", "nmk-ske-keypad"),
+	DB8500_PIN("GPIO153_B17", in_pd, "nmk-ske-keypad"), /* I7 */
+	DB8500_PIN("GPIO154_C16", in_pd, "nmk-ske-keypad"), /* I6 */
+	DB8500_PIN("GPIO155_C19", in_pd, "nmk-ske-keypad"), /* I5 */
+	DB8500_PIN("GPIO156_C17", in_pd, "nmk-ske-keypad"), /* I4 */
+	DB8500_PIN("GPIO161_D21", in_pd, "nmk-ske-keypad"), /* I3 */
+	DB8500_PIN("GPIO162_D20", in_pd, "nmk-ske-keypad"), /* I2 */
+	DB8500_PIN("GPIO163_C20", in_pd, "nmk-ske-keypad"), /* I1 */
+	DB8500_PIN("GPIO164_B21", in_pd, "nmk-ske-keypad"), /* I0 */
+	DB8500_PIN("GPIO157_A18", out_lo, "nmk-ske-keypad"), /* O7 */
+	DB8500_PIN("GPIO158_C18", out_lo, "nmk-ske-keypad"), /* O6 */
+	DB8500_PIN("GPIO159_B19", out_lo, "nmk-ske-keypad"), /* O5 */
+	DB8500_PIN("GPIO160_B20", out_lo, "nmk-ske-keypad"), /* O4 */
+	DB8500_PIN("GPIO165_C21", out_lo, "nmk-ske-keypad"), /* O3 */
+	DB8500_PIN("GPIO166_A22", out_lo, "nmk-ske-keypad"), /* O2 */
+	DB8500_PIN("GPIO167_B24", out_lo, "nmk-ske-keypad"), /* O1 */
+	DB8500_PIN("GPIO168_C22", out_lo, "nmk-ske-keypad"), /* O0 */
+	/* ske sleep state */
+	DB8500_PIN_SLEEP("GPIO153_B17", slpm_in_pu_wkup_pdis_en, "nmk-ske-keypad"), /* I7 */
+	DB8500_PIN_SLEEP("GPIO154_C16", slpm_in_pu_wkup_pdis_en, "nmk-ske-keypad"), /* I6 */
+	DB8500_PIN_SLEEP("GPIO155_C19", slpm_in_pu_wkup_pdis_en, "nmk-ske-keypad"), /* I5 */
+	DB8500_PIN_SLEEP("GPIO156_C17", slpm_in_pu_wkup_pdis_en, "nmk-ske-keypad"), /* I4 */
+	DB8500_PIN_SLEEP("GPIO161_D21", slpm_in_pu_wkup_pdis_en, "nmk-ske-keypad"), /* I3 */
+	DB8500_PIN_SLEEP("GPIO162_D20", slpm_in_pu_wkup_pdis_en, "nmk-ske-keypad"), /* I2 */
+	DB8500_PIN_SLEEP("GPIO163_C20", slpm_in_pu_wkup_pdis_en, "nmk-ske-keypad"), /* I1 */
+	DB8500_PIN_SLEEP("GPIO164_B21", slpm_in_pu_wkup_pdis_en, "nmk-ske-keypad"), /* I0 */
+	DB8500_PIN_SLEEP("GPIO157_A18", slpm_out_lo_pdis, "nmk-ske-keypad"), /* O7 */
+	DB8500_PIN_SLEEP("GPIO158_C18", slpm_out_lo_pdis, "nmk-ske-keypad"), /* O6 */
+	DB8500_PIN_SLEEP("GPIO159_B19", slpm_out_lo_pdis, "nmk-ske-keypad"), /* O5 */
+	DB8500_PIN_SLEEP("GPIO160_B20", slpm_out_lo_pdis, "nmk-ske-keypad"), /* O4 */
+	DB8500_PIN_SLEEP("GPIO165_C21", slpm_out_lo_pdis, "nmk-ske-keypad"), /* O3 */
+	DB8500_PIN_SLEEP("GPIO166_A22", slpm_out_lo_pdis, "nmk-ske-keypad"), /* O2 */
+	DB8500_PIN_SLEEP("GPIO167_B24", slpm_out_lo_pdis, "nmk-ske-keypad"), /* O1 */
+	DB8500_PIN_SLEEP("GPIO168_C22", slpm_out_lo_pdis, "nmk-ske-keypad"), /* O0 */
+
+	/* STM APE pins states */
+	DB8500_MUX_STATE("stmape_c_1", "stmape",
+		"stm", "ape_mipi34"),
+	DB8500_PIN_STATE("GPIO70_G5", in_nopull,
+		"stm", "ape_mipi34"), /* clk */
+	DB8500_PIN_STATE("GPIO71_G4", in_nopull,
+		"stm", "ape_mipi34"), /* dat3 */
+	DB8500_PIN_STATE("GPIO72_H4", in_nopull,
+		"stm", "ape_mipi34"), /* dat2 */
+	DB8500_PIN_STATE("GPIO73_H3", in_nopull,
+		"stm", "ape_mipi34"), /* dat1 */
+	DB8500_PIN_STATE("GPIO74_J3", in_nopull,
+		"stm", "ape_mipi34"), /* dat0 */
+
+	DB8500_PIN_STATE("GPIO70_G5", slpm_out_lo_pdis,
+		"stm", "ape_mipi34_sleep"), /* clk */
+	DB8500_PIN_STATE("GPIO71_G4", slpm_out_lo_pdis,
+		"stm", "ape_mipi34_sleep"), /* dat3 */
+	DB8500_PIN_STATE("GPIO72_H4", slpm_out_lo_pdis,
+		"stm", "ape_mipi34_sleep"), /* dat2 */
+	DB8500_PIN_STATE("GPIO73_H3", slpm_out_lo_pdis,
+		"stm", "ape_mipi34_sleep"), /* dat1 */
+	DB8500_PIN_STATE("GPIO74_J3", slpm_out_lo_pdis,
+		"stm", "ape_mipi34_sleep"), /* dat0 */
+
+	DB8500_MUX_STATE("stmape_oc1_1", "stmape",
+		"stm", "ape_microsd"),
+	DB8500_PIN_STATE("GPIO23_AA4", in_nopull,
+		"stm", "ape_microsd"), /* clk */
+	DB8500_PIN_STATE("GPIO25_Y4", in_nopull,
+		"stm", "ape_microsd"), /* dat0 */
+	DB8500_PIN_STATE("GPIO26_Y2", in_nopull,
+		"stm", "ape_microsd"), /* dat1 */
+	DB8500_PIN_STATE("GPIO27_AA2", in_nopull,
+		"stm", "ape_microsd"), /* dat2 */
+	DB8500_PIN_STATE("GPIO28_AA1", in_nopull,
+		"stm", "ape_microsd"), /* dat3 */
+
+	DB8500_PIN_STATE("GPIO23_AA4", slpm_out_lo_wkup_pdis,
+		"stm", "ape_microsd_sleep"), /* clk */
+	DB8500_PIN_STATE("GPIO25_Y4", slpm_in_wkup_pdis,
+		"stm", "ape_microsd_sleep"), /* dat0 */
+	DB8500_PIN_STATE("GPIO26_Y2", slpm_in_wkup_pdis,
+		"stm", "ape_microsd_sleep"), /* dat1 */
+	DB8500_PIN_STATE("GPIO27_AA2", slpm_in_wkup_pdis,
+		"stm", "ape_microsd_sleep"), /* dat2 */
+	DB8500_PIN_STATE("GPIO28_AA1", slpm_in_wkup_pdis,
+		"stm", "ape_microsd_sleep"), /* dat3 */
+
+	/*  STM Modem pins states */
+	DB8500_MUX_STATE("stmmod_oc3_2", "stmmod",
+		"stm", "mod_mipi34"),
+	DB8500_MUX_STATE("uartmodrx_oc3_1", "uartmod",
+		"stm", "mod_mipi34"),
+	DB8500_MUX_STATE("uartmodtx_oc3_1", "uartmod",
+		"stm", "mod_mipi34"),
+	DB8500_PIN_STATE("GPIO70_G5", in_nopull,
+		"stm", "mod_mipi34"), /* clk */
+	DB8500_PIN_STATE("GPIO71_G4", in_nopull,
+		"stm", "mod_mipi34"), /* dat3 */
+	DB8500_PIN_STATE("GPIO72_H4", in_nopull,
+		"stm", "mod_mipi34"), /* dat2 */
+	DB8500_PIN_STATE("GPIO73_H3", in_nopull,
+		"stm", "mod_mipi34"), /* dat1 */
+	DB8500_PIN_STATE("GPIO74_J3", in_nopull,
+		"stm", "mod_mipi34"), /* dat0 */
+	DB8500_PIN_STATE("GPIO75_H2", in_pu,
+		"stm", "mod_mipi34"), /* uartmod rx */
+	DB8500_PIN_STATE("GPIO76_J2", out_lo,
+		"stm", "mod_mipi34"), /* uartmod tx */
+
+	DB8500_PIN_STATE("GPIO70_G5", slpm_out_lo_pdis,
+		"stm", "mod_mipi34_sleep"), /* clk */
+	DB8500_PIN_STATE("GPIO71_G4", slpm_out_lo_pdis,
+		"stm", "mod_mipi34_sleep"), /* dat3 */
+	DB8500_PIN_STATE("GPIO72_H4", slpm_out_lo_pdis,
+		"stm", "mod_mipi34_sleep"), /* dat2 */
+	DB8500_PIN_STATE("GPIO73_H3", slpm_out_lo_pdis,
+		"stm", "mod_mipi34_sleep"), /* dat1 */
+	DB8500_PIN_STATE("GPIO74_J3", slpm_out_lo_pdis,
+		"stm", "mod_mipi34_sleep"), /* dat0 */
+	DB8500_PIN_STATE("GPIO75_H2", slpm_in_wkup_pdis,
+		"stm", "mod_mipi34_sleep"), /* uartmod rx */
+	DB8500_PIN_STATE("GPIO76_J2", slpm_out_lo_wkup_pdis,
+		"stm", "mod_mipi34_sleep"), /* uartmod tx */
+
+	DB8500_MUX_STATE("stmmod_b_1", "stmmod",
+		"stm", "mod_microsd"),
+	DB8500_MUX_STATE("uartmodrx_oc3_1", "uartmod",
+		"stm", "mod_microsd"),
+	DB8500_MUX_STATE("uartmodtx_oc3_1", "uartmod",
+		"stm", "mod_microsd"),
+	DB8500_PIN_STATE("GPIO23_AA4", in_nopull,
+		"stm", "mod_microsd"), /* clk */
+	DB8500_PIN_STATE("GPIO25_Y4", in_nopull,
+		"stm", "mod_microsd"), /* dat0 */
+	DB8500_PIN_STATE("GPIO26_Y2", in_nopull,
+		"stm", "mod_microsd"), /* dat1 */
+	DB8500_PIN_STATE("GPIO27_AA2", in_nopull,
+		"stm", "mod_microsd"), /* dat2 */
+	DB8500_PIN_STATE("GPIO28_AA1", in_nopull,
+		"stm", "mod_microsd"), /* dat3 */
+	DB8500_PIN_STATE("GPIO75_H2", in_pu,
+		"stm", "mod_microsd"), /* uartmod rx */
+	DB8500_PIN_STATE("GPIO76_J2", out_lo,
+		"stm", "mod_microsd"), /* uartmod tx */
+
+	DB8500_PIN_STATE("GPIO23_AA4", slpm_out_lo_wkup_pdis,
+		"stm", "mod_microsd_sleep"), /* clk */
+	DB8500_PIN_STATE("GPIO25_Y4", slpm_in_wkup_pdis,
+		"stm", "mod_microsd_sleep"), /* dat0 */
+	DB8500_PIN_STATE("GPIO26_Y2", slpm_in_wkup_pdis,
+		"stm", "mod_microsd_sleep"), /* dat1 */
+	DB8500_PIN_STATE("GPIO27_AA2", slpm_in_wkup_pdis,
+		"stm", "mod_microsd_sleep"), /* dat2 */
+	DB8500_PIN_STATE("GPIO28_AA1", slpm_in_wkup_pdis,
+		"stm", "mod_microsd_sleep"), /* dat3 */
+	DB8500_PIN_STATE("GPIO75_H2", slpm_in_wkup_pdis,
+		"stm", "mod_microsd_sleep"), /* uartmod rx */
+	DB8500_PIN_STATE("GPIO76_J2", slpm_out_lo_wkup_pdis,
+		"stm", "mod_microsd_sleep"), /* uartmod tx */
+
+	/*  STM dual Modem/APE pins state */
+	DB8500_MUX_STATE("stmmod_oc3_2", "stmmod",
+		"stm", "mod_mipi34_ape_mipi60"),
+	DB8500_MUX_STATE("stmape_c_2", "stmape",
+		"stm", "mod_mipi34_ape_mipi60"),
+	DB8500_MUX_STATE("uartmodrx_oc3_1", "uartmod",
+		"stm", "mod_mipi34_ape_mipi60"),
+	DB8500_MUX_STATE("uartmodtx_oc3_1", "uartmod",
+		"stm", "mod_mipi34_ape_mipi60"),
+	DB8500_PIN_STATE("GPIO70_G5", in_nopull,
+		"stm", "mod_mipi34_ape_mipi60"), /* clk */
+	DB8500_PIN_STATE("GPIO71_G4", in_nopull,
+		"stm", "mod_mipi34_ape_mipi60"), /* dat3 */
+	DB8500_PIN_STATE("GPIO72_H4", in_nopull,
+		"stm", "mod_mipi34_ape_mipi60"), /* dat2 */
+	DB8500_PIN_STATE("GPIO73_H3", in_nopull,
+		"stm", "mod_mipi34_ape_mipi60"), /* dat1 */
+	DB8500_PIN_STATE("GPIO74_J3", in_nopull,
+		"stm", "mod_mipi34_ape_mipi60"), /* dat0 */
+	DB8500_PIN_STATE("GPIO75_H2", in_pu,
+		"stm", "mod_mipi34_ape_mipi60"), /* uartmod rx */
+	DB8500_PIN_STATE("GPIO76_J2", out_lo,
+		"stm", "mod_mipi34_ape_mipi60"), /* uartmod tx */
+	DB8500_PIN_STATE("GPIO155_C19", in_nopull,
+		"stm", "mod_mipi34_ape_mipi60"), /* clk */
+	DB8500_PIN_STATE("GPIO156_C17", in_nopull,
+		"stm", "mod_mipi34_ape_mipi60"), /* dat3 */
+	DB8500_PIN_STATE("GPIO157_A18", in_nopull,
+		"stm", "mod_mipi34_ape_mipi60"), /* dat2 */
+	DB8500_PIN_STATE("GPIO158_C18", in_nopull,
+		"stm", "mod_mipi34_ape_mipi60"), /* dat1 */
+	DB8500_PIN_STATE("GPIO159_B19", in_nopull,
+		"stm", "mod_mipi34_ape_mipi60"), /* dat0 */
+
+	DB8500_PIN_STATE("GPIO70_G5", slpm_out_lo_pdis,
+		"stm", "mod_mipi34_ape_mipi60_sleep"), /* clk */
+	DB8500_PIN_STATE("GPIO71_G4", slpm_out_lo_pdis,
+		"stm", "mod_mipi34_ape_mipi60_sleep"), /* dat3 */
+	DB8500_PIN_STATE("GPIO72_H4", slpm_out_lo_pdis,
+		"stm", "mod_mipi34_ape_mipi60_sleep"), /* dat2 */
+	DB8500_PIN_STATE("GPIO73_H3", slpm_out_lo_pdis,
+		"stm", "mod_mipi34_ape_mipi60_sleep"), /* dat1 */
+	DB8500_PIN_STATE("GPIO74_J3", slpm_out_lo_pdis,
+		"stm", "mod_mipi34_ape_mipi60_sleep"), /* dat0 */
+	DB8500_PIN_STATE("GPIO75_H2", slpm_in_wkup_pdis,
+		"stm", "mod_mipi34_ape_mipi60_sleep"), /* uartmod rx */
+	DB8500_PIN_STATE("GPIO76_J2", slpm_out_lo_wkup_pdis,
+		"stm", "mod_mipi34_ape_mipi60_sleep"), /* uartmod tx */
+	DB8500_PIN_STATE("GPIO155_C19", slpm_in_wkup_pdis,
+		"stm", "mod_mipi34_ape_mipi60_sleep"), /* clk */
+	DB8500_PIN_STATE("GPIO156_C17", slpm_in_wkup_pdis,
+		"stm", "mod_mipi34_ape_mipi60_sleep"), /* dat3 */
+	DB8500_PIN_STATE("GPIO157_A18", slpm_in_wkup_pdis,
+		"stm", "mod_mipi34_ape_mipi60_sleep"), /* dat2 */
+	DB8500_PIN_STATE("GPIO158_C18", slpm_in_wkup_pdis,
+		"stm", "mod_mipi34_ape_mipi60_sleep"), /* dat1 */
+	DB8500_PIN_STATE("GPIO159_B19", slpm_in_wkup_pdis,
+		"stm", "mod_mipi34_ape_mipi60_sleep"), /* dat0 */
 };
 
 /*
@@ -267,32 +568,48 @@
 	DB8500_PIN_HOG("GPIO217_AH12", gpio_in_pu),
 	/* Mux in UART1 and set the pull-ups */
 	DB8500_MUX_HOG("u1rxtx_a_1", "u1"),
-	DB8500_MUX_HOG("u1ctsrts_a_1", "u1"),
 	DB8500_PIN_HOG("GPIO4_AH6", in_pu), /* RXD */
 	DB8500_PIN_HOG("GPIO5_AG6", out_hi), /* TXD */
-	DB8500_PIN_HOG("GPIO6_AF6", in_pu), /* CTS */
-	DB8500_PIN_HOG("GPIO7_AG5", out_hi), /* RTS */
 	/*
 	 * Runtime stuff: make it possible to mux in the SKE keypad
 	 * and bias the pins
 	 */
-	DB8500_MUX("kp_a_2", "kp", "ske"),
-	DB8500_PIN("GPIO153_B17", in_pd_slpm_in_pu, "ske"), /* I7 */
-	DB8500_PIN("GPIO154_C16", in_pd_slpm_in_pu, "ske"), /* I6 */
-	DB8500_PIN("GPIO155_C19", in_pd_slpm_in_pu, "ske"), /* I5 */
-	DB8500_PIN("GPIO156_C17", in_pd_slpm_in_pu, "ske"), /* I4 */
-	DB8500_PIN("GPIO161_D21", in_pd_slpm_in_pu, "ske"), /* I3 */
-	DB8500_PIN("GPIO162_D20", in_pd_slpm_in_pu, "ske"), /* I2 */
-	DB8500_PIN("GPIO163_C20", in_pd_slpm_in_pu, "ske"), /* I1 */
-	DB8500_PIN("GPIO164_B21", in_pd_slpm_in_pu, "ske"), /* I0 */
-	DB8500_PIN("GPIO157_A18", in_pu_slpm_out_lo, "ske"), /* O7 */
-	DB8500_PIN("GPIO158_C18", in_pu_slpm_out_lo, "ske"), /* O6 */
-	DB8500_PIN("GPIO159_B19", in_pu_slpm_out_lo, "ske"), /* O5 */
-	DB8500_PIN("GPIO160_B20", in_pu_slpm_out_lo, "ske"), /* O4 */
-	DB8500_PIN("GPIO165_C21", in_pu_slpm_out_lo, "ske"), /* O3 */
-	DB8500_PIN("GPIO166_A22", in_pu_slpm_out_lo, "ske"), /* O2 */
-	DB8500_PIN("GPIO167_B24", in_pu_slpm_out_lo, "ske"), /* O1 */
-	DB8500_PIN("GPIO168_C22", in_pu_slpm_out_lo, "ske"), /* O0 */
+	/* ske default state */
+	DB8500_MUX("kp_a_2", "kp", "nmk-ske-keypad"),
+	DB8500_PIN("GPIO153_B17", in_pu, "nmk-ske-keypad"), /* I7 */
+	DB8500_PIN("GPIO154_C16", in_pu, "nmk-ske-keypad"), /* I6 */
+	DB8500_PIN("GPIO155_C19", in_pu, "nmk-ske-keypad"), /* I5 */
+	DB8500_PIN("GPIO156_C17", in_pu, "nmk-ske-keypad"), /* I4 */
+	DB8500_PIN("GPIO161_D21", in_pu, "nmk-ske-keypad"), /* I3 */
+	DB8500_PIN("GPIO162_D20", in_pu, "nmk-ske-keypad"), /* I2 */
+	DB8500_PIN("GPIO163_C20", in_pu, "nmk-ske-keypad"), /* I1 */
+	DB8500_PIN("GPIO164_B21", in_pu, "nmk-ske-keypad"), /* I0 */
+	DB8500_PIN("GPIO157_A18", out_lo, "nmk-ske-keypad"), /* O7 */
+	DB8500_PIN("GPIO158_C18", out_lo, "nmk-ske-keypad"), /* O6 */
+	DB8500_PIN("GPIO159_B19", out_lo, "nmk-ske-keypad"), /* O5 */
+	DB8500_PIN("GPIO160_B20", out_lo, "nmk-ske-keypad"), /* O4 */
+	DB8500_PIN("GPIO165_C21", out_lo, "nmk-ske-keypad"), /* O3 */
+	DB8500_PIN("GPIO166_A22", out_lo, "nmk-ske-keypad"), /* O2 */
+	DB8500_PIN("GPIO167_B24", out_lo, "nmk-ske-keypad"), /* O1 */
+	DB8500_PIN("GPIO168_C22", out_lo, "nmk-ske-keypad"), /* O0 */
+	/* ske sleep state */
+	DB8500_PIN_SLEEP("GPIO153_B17", slpm_in_pu_wkup_pdis_en, "nmk-ske-keypad"), /* I7 */
+	DB8500_PIN_SLEEP("GPIO154_C16", slpm_in_pu_wkup_pdis_en, "nmk-ske-keypad"), /* I6 */
+	DB8500_PIN_SLEEP("GPIO155_C19", slpm_in_pu_wkup_pdis_en, "nmk-ske-keypad"), /* I5 */
+	DB8500_PIN_SLEEP("GPIO156_C17", slpm_in_pu_wkup_pdis_en, "nmk-ske-keypad"), /* I4 */
+	DB8500_PIN_SLEEP("GPIO161_D21", slpm_in_pu_wkup_pdis_en, "nmk-ske-keypad"), /* I3 */
+	DB8500_PIN_SLEEP("GPIO162_D20", slpm_in_pu_wkup_pdis_en, "nmk-ske-keypad"), /* I2 */
+	DB8500_PIN_SLEEP("GPIO163_C20", slpm_in_pu_wkup_pdis_en, "nmk-ske-keypad"), /* I1 */
+	DB8500_PIN_SLEEP("GPIO164_B21", slpm_in_pu_wkup_pdis_en, "nmk-ske-keypad"), /* I0 */
+	DB8500_PIN_SLEEP("GPIO157_A18", slpm_out_lo_pdis, "nmk-ske-keypad"), /* O7 */
+	DB8500_PIN_SLEEP("GPIO158_C18", slpm_out_lo_pdis, "nmk-ske-keypad"), /* O6 */
+	DB8500_PIN_SLEEP("GPIO159_B19", slpm_out_lo_pdis, "nmk-ske-keypad"), /* O5 */
+	DB8500_PIN_SLEEP("GPIO160_B20", slpm_out_lo_pdis, "nmk-ske-keypad"), /* O4 */
+	DB8500_PIN_SLEEP("GPIO165_C21", slpm_out_lo_pdis, "nmk-ske-keypad"), /* O3 */
+	DB8500_PIN_SLEEP("GPIO166_A22", slpm_out_lo_pdis, "nmk-ske-keypad"), /* O2 */
+	DB8500_PIN_SLEEP("GPIO167_B24", slpm_out_lo_pdis, "nmk-ske-keypad"), /* O1 */
+	DB8500_PIN_SLEEP("GPIO168_C22", slpm_out_lo_pdis, "nmk-ske-keypad"), /* O0 */
+
 	/* Mux in and drive the SDI0 DAT31DIR line high at runtime */
 	DB8500_MUX("mc0dat31dir_a_1", "mc0", "sdi0"),
 	DB8500_PIN("GPIO21_AB3", out_hi, "sdi0"),
@@ -395,28 +712,6 @@
 	DB8500_PIN("GPIO217_AH12", gpio_in_pu_slpm_gpio_nopull, "gpio-keys.0"),
 	DB8500_PIN("GPIO145_C13", gpio_in_pd_slpm_gpio_nopull, "gpio-keys.0"),
 	DB8500_PIN("GPIO139_C9", gpio_in_pu_slpm_gpio_nopull, "gpio-keys.0"),
-	/*
-	 * Make it possible to mux in the SKE keypad and bias the pins
-	 * FIXME: what's the point with this on HREFv60? KP/SKE is already
-	 * muxed in at another place! Enabling this will bork.
-	 */
-	DB8500_MUX("kp_a_2", "kp", "ske"),
-	DB8500_PIN("GPIO153_B17", in_pd_slpm_in_pu, "ske"), /* I7 */
-	DB8500_PIN("GPIO154_C16", in_pd_slpm_in_pu, "ske"), /* I6 */
-	DB8500_PIN("GPIO155_C19", in_pd_slpm_in_pu, "ske"), /* I5 */
-	DB8500_PIN("GPIO156_C17", in_pd_slpm_in_pu, "ske"), /* I4 */
-	DB8500_PIN("GPIO161_D21", in_pd_slpm_in_pu, "ske"), /* I3 */
-	DB8500_PIN("GPIO162_D20", in_pd_slpm_in_pu, "ske"), /* I2 */
-	DB8500_PIN("GPIO163_C20", in_pd_slpm_in_pu, "ske"), /* I1 */
-	DB8500_PIN("GPIO164_B21", in_pd_slpm_in_pu, "ske"), /* I0 */
-	DB8500_PIN("GPIO157_A18", in_pu_slpm_out_lo, "ske"), /* O7 */
-	DB8500_PIN("GPIO158_C18", in_pu_slpm_out_lo, "ske"), /* O6 */
-	DB8500_PIN("GPIO159_B19", in_pu_slpm_out_lo, "ske"), /* O5 */
-	DB8500_PIN("GPIO160_B20", in_pu_slpm_out_lo, "ske"), /* O4 */
-	DB8500_PIN("GPIO165_C21", in_pu_slpm_out_lo, "ske"), /* O3 */
-	DB8500_PIN("GPIO166_A22", in_pu_slpm_out_lo, "ske"), /* O2 */
-	DB8500_PIN("GPIO167_B24", in_pu_slpm_out_lo, "ske"), /* O1 */
-	DB8500_PIN("GPIO168_C22", in_pu_slpm_out_lo, "ske"), /* O0 */
 };
 
 static struct pinctrl_map __initdata u9500_pinmap[] = {
diff --git a/arch/arm/mach-ux500/board-mop500-sdi.c b/arch/arm/mach-ux500/board-mop500-sdi.c
index 9c8e4a9..051b62c 100644
--- a/arch/arm/mach-ux500/board-mop500-sdi.c
+++ b/arch/arm/mach-ux500/board-mop500-sdi.c
@@ -11,9 +11,9 @@
 #include <linux/amba/mmci.h>
 #include <linux/mmc/host.h>
 #include <linux/platform_device.h>
+#include <linux/platform_data/dma-ste-dma40.h>
 
 #include <asm/mach-types.h>
-#include <plat/ste_dma40.h>
 #include <mach/devices.h>
 #include <mach/hardware.h>
 
diff --git a/arch/arm/mach-ux500/board-mop500-stuib.c b/arch/arm/mach-ux500/board-mop500-stuib.c
index 8c97977..564f57d 100644
--- a/arch/arm/mach-ux500/board-mop500-stuib.c
+++ b/arch/arm/mach-ux500/board-mop500-stuib.c
@@ -162,18 +162,6 @@
 	.y_flip = true,
 };
 
-static struct bu21013_platform_device tsc_plat2_device = {
-	.cs_en = bu21013_gpio_board_init,
-	.cs_dis = bu21013_gpio_board_exit,
-	.irq_read_val = bu21013_read_pin_val,
-	.irq = NOMADIK_GPIO_TO_IRQ(TOUCH_GPIO_PIN),
-	.touch_x_max = TOUCH_XMAX,
-	.touch_y_max = TOUCH_YMAX,
-	.ext_clk = false,
-	.x_flip = false,
-	.y_flip = true,
-};
-
 static struct i2c_board_info __initdata u8500_i2c3_devices_stuib[] = {
 	{
 		I2C_BOARD_INFO("bu21013_tp", 0x5C),
@@ -181,21 +169,17 @@
 	},
 	{
 		I2C_BOARD_INFO("bu21013_tp", 0x5D),
-		.platform_data = &tsc_plat2_device,
+		.platform_data = &tsc_plat_device,
 	},
 
 };
 
 void __init mop500_stuib_init(void)
 {
-	if (machine_is_hrefv60()) {
+	if (machine_is_hrefv60())
 		tsc_plat_device.cs_pin = HREFV60_TOUCH_RST_GPIO;
-		tsc_plat2_device.cs_pin = HREFV60_TOUCH_RST_GPIO;
-	} else {
+	else
 		tsc_plat_device.cs_pin = GPIO_BU21013_CS;
-		tsc_plat2_device.cs_pin = GPIO_BU21013_CS;
-
-	}
 
 	mop500_uib_i2c_add(0, mop500_i2c0_devices_stuib,
 			ARRAY_SIZE(mop500_i2c0_devices_stuib));
diff --git a/arch/arm/mach-ux500/board-mop500.c b/arch/arm/mach-ux500/board-mop500.c
index e6ad1614..d453522 100644
--- a/arch/arm/mach-ux500/board-mop500.c
+++ b/arch/arm/mach-ux500/board-mop500.c
@@ -33,18 +33,15 @@
 #include <linux/smsc911x.h>
 #include <linux/gpio_keys.h>
 #include <linux/delay.h>
-#include <linux/of.h>
-#include <linux/of_platform.h>
 #include <linux/leds.h>
 #include <linux/pinctrl/consumer.h>
 #include <linux/platform_data/pinctrl-nomadik.h>
+#include <linux/platform_data/dma-ste-dma40.h>
 
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/hardware/gic.h>
 
-#include <plat/ste_dma40.h>
-
 #include <mach/hardware.h>
 #include <mach/setup.h>
 #include <mach/devices.h>
@@ -525,7 +522,7 @@
 };
 #endif
 
-static struct pl022_ssp_controller ssp0_plat = {
+struct pl022_ssp_controller ssp0_plat = {
 	.bus_id = 0,
 #ifdef CONFIG_STE_DMA40
 	.enable_dma = 1,
@@ -602,7 +599,7 @@
 };
 #endif
 
-static struct amba_pl011_data uart0_plat = {
+struct amba_pl011_data uart0_plat = {
 #ifdef CONFIG_STE_DMA40
 	.dma_filter = stedma40_filter,
 	.dma_rx_param = &uart0_dma_cfg_rx,
@@ -610,7 +607,7 @@
 #endif
 };
 
-static struct amba_pl011_data uart1_plat = {
+struct amba_pl011_data uart1_plat = {
 #ifdef CONFIG_STE_DMA40
 	.dma_filter = stedma40_filter,
 	.dma_rx_param = &uart1_dma_cfg_rx,
@@ -618,7 +615,7 @@
 #endif
 };
 
-static struct amba_pl011_data uart2_plat = {
+struct amba_pl011_data uart2_plat = {
 #ifdef CONFIG_STE_DMA40
 	.dma_filter = stedma40_filter,
 	.dma_rx_param = &uart2_dma_cfg_rx,
@@ -681,8 +678,6 @@
 
 	/* This board has full regulator constraints */
 	regulator_has_full_constraints();
-
-	mop500_uib_init();
 }
 
 static void __init snowball_init_machine(void)
@@ -747,8 +742,6 @@
 
 	/* This board has full regulator constraints */
 	regulator_has_full_constraints();
-
-	mop500_uib_init();
 }
 
 MACHINE_START(U8500, "ST-Ericsson MOP500 platform")
@@ -794,135 +787,5 @@
 	.timer		= &ux500_timer,
 	.handle_irq	= gic_handle_irq,
 	.init_machine	= snowball_init_machine,
-	.init_late	= ux500_init_late,
+	.init_late	= NULL,
 MACHINE_END
-
-#ifdef CONFIG_MACH_UX500_DT
-
-struct of_dev_auxdata u8500_auxdata_lookup[] __initdata = {
-	/* Requires call-back bindings. */
-	OF_DEV_AUXDATA("arm,cortex-a9-pmu", 0, "arm-pmu", &db8500_pmu_platdata),
-	/* Requires DMA and call-back bindings. */
-	OF_DEV_AUXDATA("arm,pl011", 0x80120000, "uart0", &uart0_plat),
-	OF_DEV_AUXDATA("arm,pl011", 0x80121000, "uart1", &uart1_plat),
-	OF_DEV_AUXDATA("arm,pl011", 0x80007000, "uart2", &uart2_plat),
-	/* Requires DMA bindings. */
-	OF_DEV_AUXDATA("arm,pl022", 0x80002000, "ssp0",  &ssp0_plat),
-	OF_DEV_AUXDATA("arm,pl18x", 0x80126000, "sdi0",  &mop500_sdi0_data),
-	OF_DEV_AUXDATA("arm,pl18x", 0x80118000, "sdi1",  &mop500_sdi1_data),
-	OF_DEV_AUXDATA("arm,pl18x", 0x80005000, "sdi2",  &mop500_sdi2_data),
-	OF_DEV_AUXDATA("arm,pl18x", 0x80114000, "sdi4",  &mop500_sdi4_data),
-	/* Requires clock name bindings. */
-	OF_DEV_AUXDATA("st,nomadik-gpio", 0x8012e000, "gpio.0", NULL),
-	OF_DEV_AUXDATA("st,nomadik-gpio", 0x8012e080, "gpio.1", NULL),
-	OF_DEV_AUXDATA("st,nomadik-gpio", 0x8000e000, "gpio.2", NULL),
-	OF_DEV_AUXDATA("st,nomadik-gpio", 0x8000e080, "gpio.3", NULL),
-	OF_DEV_AUXDATA("st,nomadik-gpio", 0x8000e100, "gpio.4", NULL),
-	OF_DEV_AUXDATA("st,nomadik-gpio", 0x8000e180, "gpio.5", NULL),
-	OF_DEV_AUXDATA("st,nomadik-gpio", 0x8011e000, "gpio.6", NULL),
-	OF_DEV_AUXDATA("st,nomadik-gpio", 0x8011e080, "gpio.7", NULL),
-	OF_DEV_AUXDATA("st,nomadik-gpio", 0xa03fe000, "gpio.8", NULL),
-	OF_DEV_AUXDATA("st,nomadik-i2c", 0x80004000, "nmk-i2c.0", NULL),
-	OF_DEV_AUXDATA("st,nomadik-i2c", 0x80122000, "nmk-i2c.1", NULL),
-	OF_DEV_AUXDATA("st,nomadik-i2c", 0x80128000, "nmk-i2c.2", NULL),
-	OF_DEV_AUXDATA("st,nomadik-i2c", 0x80110000, "nmk-i2c.3", NULL),
-	OF_DEV_AUXDATA("st,nomadik-i2c", 0x8012a000, "nmk-i2c.4", NULL),
-	/* Requires device name bindings. */
-	OF_DEV_AUXDATA("stericsson,nmk_pinctrl", 0, "pinctrl-db8500", NULL),
-	/* Requires clock name and DMA bindings. */
-	OF_DEV_AUXDATA("stericsson,ux500-msp-i2s", 0x80123000,
-		"ux500-msp-i2s.0", &msp0_platform_data),
-	OF_DEV_AUXDATA("stericsson,ux500-msp-i2s", 0x80124000,
-		"ux500-msp-i2s.1", &msp1_platform_data),
-	OF_DEV_AUXDATA("stericsson,ux500-msp-i2s", 0x80117000,
-		"ux500-msp-i2s.2", &msp2_platform_data),
-	OF_DEV_AUXDATA("stericsson,ux500-msp-i2s", 0x80125000,
-		"ux500-msp-i2s.3", &msp3_platform_data),
-	{},
-};
-
-static const struct of_device_id u8500_local_bus_nodes[] = {
-	/* only create devices below soc node */
-	{ .compatible = "stericsson,db8500", },
-	{ .compatible = "stericsson,db8500-prcmu", },
-	{ .compatible = "simple-bus"},
-	{ },
-};
-
-static void __init u8500_init_machine(void)
-{
-	struct device *parent = NULL;
-	int i2c0_devs;
-	int i;
-
-	/* Pinmaps must be in place before devices register */
-	if (of_machine_is_compatible("st-ericsson,mop500"))
-		mop500_pinmaps_init();
-	else if (of_machine_is_compatible("calaosystems,snowball-a9500"))
-		snowball_pinmaps_init();
-	else if (of_machine_is_compatible("st-ericsson,hrefv60+"))
-		hrefv60_pinmaps_init();
-
-	parent = u8500_of_init_devices();
-
-	for (i = 0; i < ARRAY_SIZE(mop500_platform_devs); i++)
-		mop500_platform_devs[i]->dev.parent = parent;
-
-	/* automatically probe child nodes of db8500 device */
-	of_platform_populate(NULL, u8500_local_bus_nodes, u8500_auxdata_lookup, parent);
-
-	if (of_machine_is_compatible("st-ericsson,mop500")) {
-		mop500_gpio_keys[0].gpio = GPIO_PROX_SENSOR;
-
-		platform_add_devices(mop500_platform_devs,
-				ARRAY_SIZE(mop500_platform_devs));
-
-		mop500_sdi_init(parent);
-		mop500_audio_init(parent);
-		i2c0_devs = ARRAY_SIZE(mop500_i2c0_devices);
-		i2c_register_board_info(0, mop500_i2c0_devices, i2c0_devs);
-		i2c_register_board_info(2, mop500_i2c2_devices,
-					ARRAY_SIZE(mop500_i2c2_devices));
-
-		mop500_uib_init();
-
-	} else if (of_machine_is_compatible("calaosystems,snowball-a9500")) {
-		mop500_of_audio_init(parent);
-	} else if (of_machine_is_compatible("st-ericsson,hrefv60+")) {
-		/*
-		 * The HREFv60 board removed a GPIO expander and routed
-		 * all these GPIO pins to the internal GPIO controller
-		 * instead.
-		 */
-		mop500_gpio_keys[0].gpio = HREFV60_PROX_SENSE_GPIO;
-		platform_add_devices(mop500_platform_devs,
-				ARRAY_SIZE(mop500_platform_devs));
-
-		mop500_uib_init();
-	}
-
-	/* This board has full regulator constraints */
-	regulator_has_full_constraints();
-}
-
-static const char * u8500_dt_board_compat[] = {
-	"calaosystems,snowball-a9500",
-	"st-ericsson,hrefv60+",
-	"st-ericsson,u8500",
-	"st-ericsson,mop500",
-	NULL,
-};
-
-
-DT_MACHINE_START(U8500_DT, "ST-Ericsson U8500 platform (Device Tree Support)")
-	.smp		= smp_ops(ux500_smp_ops),
-	.map_io		= u8500_map_io,
-	.init_irq	= ux500_init_irq,
-	/* we re-use nomadik timer here */
-	.timer		= &ux500_timer,
-	.handle_irq	= gic_handle_irq,
-	.init_machine	= u8500_init_machine,
-	.init_late	= ux500_init_late,
-	.dt_compat      = u8500_dt_board_compat,
-MACHINE_END
-#endif
diff --git a/arch/arm/mach-ux500/board-mop500.h b/arch/arm/mach-ux500/board-mop500.h
index aca39a6..eaa605f 100644
--- a/arch/arm/mach-ux500/board-mop500.h
+++ b/arch/arm/mach-ux500/board-mop500.h
@@ -89,6 +89,10 @@
 extern struct msp_i2s_platform_data msp2_platform_data;
 extern struct msp_i2s_platform_data msp3_platform_data;
 extern struct arm_pmu_platdata db8500_pmu_platdata;
+extern struct amba_pl011_data uart0_plat;
+extern struct amba_pl011_data uart1_plat;
+extern struct amba_pl011_data uart2_plat;
+extern struct pl022_ssp_controller ssp0_plat;
 
 extern void mop500_sdi_init(struct device *parent);
 extern void snowball_sdi_init(struct device *parent);
@@ -100,14 +104,8 @@
 void __init snowball_pinmaps_init(void);
 void __init hrefv60_pinmaps_init(void);
 void mop500_audio_init(struct device *parent);
-/* Due for removal once the MSP driver has been fully DT:ed. */
-void mop500_of_audio_init(struct device *parent);
 
 int __init mop500_uib_init(void);
 void mop500_uib_i2c_add(int busnum, struct i2c_board_info *info,
 		unsigned n);
-
-/* TODO: Once all pieces are DT:ed, remove completely. */
-struct device * __init u8500_of_init_devices(void);
-
 #endif
diff --git a/arch/arm/mach-ux500/cpu-db8500.c b/arch/arm/mach-ux500/cpu-db8500.c
index 5c5ad70..db0bb75 100644
--- a/arch/arm/mach-ux500/cpu-db8500.c
+++ b/arch/arm/mach-ux500/cpu-db8500.c
@@ -17,19 +17,27 @@
 #include <linux/platform_device.h>
 #include <linux/io.h>
 #include <linux/mfd/abx500/ab8500.h>
-#include <linux/platform_data/usb-musb-ux500.h>
+#include <linux/mfd/dbx500-prcmu.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/regulator/machine.h>
 #include <linux/platform_data/pinctrl-nomadik.h>
 #include <linux/random.h>
 
 #include <asm/pmu.h>
 #include <asm/mach/map.h>
+#include <asm/mach/arch.h>
+#include <asm/hardware/gic.h>
+
 #include <mach/hardware.h>
 #include <mach/setup.h>
 #include <mach/devices.h>
 #include <mach/db8500-regs.h>
+#include <mach/irqs.h>
 
 #include "devices-db8500.h"
 #include "ste-dma40-db8500.h"
+#include "board-mop500.h"
 
 /* minimum static i/o mapping required to boot U8500 platforms */
 static struct map_desc u8500_uart_io_desc[] __initdata = {
@@ -227,12 +235,12 @@
 	return parent;
 }
 
-/* TODO: Once all pieces are DT:ed, remove completely. */
-struct device * __init u8500_of_init_devices(void)
-{
-	struct device *parent;
+#ifdef CONFIG_MACH_UX500_DT
 
-	parent = db8500_soc_device_init();
+/* TODO: Once all pieces are DT:ed, remove completely. */
+static struct device * __init u8500_of_init_devices(void)
+{
+	struct device *parent = db8500_soc_device_init();
 
 	db8500_add_usb(parent, usb_db8500_rx_dma_cfg, usb_db8500_tx_dma_cfg);
 
@@ -248,3 +256,95 @@
 
 	return parent;
 }
+
+static struct of_dev_auxdata u8500_auxdata_lookup[] __initdata = {
+	/* Requires call-back bindings. */
+	OF_DEV_AUXDATA("arm,cortex-a9-pmu", 0, "arm-pmu", &db8500_pmu_platdata),
+	/* Requires DMA bindings. */
+	OF_DEV_AUXDATA("arm,pl011", 0x80120000, "uart0", &uart0_plat),
+	OF_DEV_AUXDATA("arm,pl011", 0x80121000, "uart1", &uart1_plat),
+	OF_DEV_AUXDATA("arm,pl011", 0x80007000, "uart2", &uart2_plat),
+	OF_DEV_AUXDATA("arm,pl022", 0x80002000, "ssp0",  &ssp0_plat),
+	OF_DEV_AUXDATA("arm,pl18x", 0x80126000, "sdi0",  &mop500_sdi0_data),
+	OF_DEV_AUXDATA("arm,pl18x", 0x80118000, "sdi1",  &mop500_sdi1_data),
+	OF_DEV_AUXDATA("arm,pl18x", 0x80005000, "sdi2",  &mop500_sdi2_data),
+	OF_DEV_AUXDATA("arm,pl18x", 0x80114000, "sdi4",  &mop500_sdi4_data),
+	/* Requires clock name bindings. */
+	OF_DEV_AUXDATA("st,nomadik-gpio", 0x8012e000, "gpio.0", NULL),
+	OF_DEV_AUXDATA("st,nomadik-gpio", 0x8012e080, "gpio.1", NULL),
+	OF_DEV_AUXDATA("st,nomadik-gpio", 0x8000e000, "gpio.2", NULL),
+	OF_DEV_AUXDATA("st,nomadik-gpio", 0x8000e080, "gpio.3", NULL),
+	OF_DEV_AUXDATA("st,nomadik-gpio", 0x8000e100, "gpio.4", NULL),
+	OF_DEV_AUXDATA("st,nomadik-gpio", 0x8000e180, "gpio.5", NULL),
+	OF_DEV_AUXDATA("st,nomadik-gpio", 0x8011e000, "gpio.6", NULL),
+	OF_DEV_AUXDATA("st,nomadik-gpio", 0x8011e080, "gpio.7", NULL),
+	OF_DEV_AUXDATA("st,nomadik-gpio", 0xa03fe000, "gpio.8", NULL),
+	OF_DEV_AUXDATA("st,nomadik-i2c", 0x80004000, "nmk-i2c.0", NULL),
+	OF_DEV_AUXDATA("st,nomadik-i2c", 0x80122000, "nmk-i2c.1", NULL),
+	OF_DEV_AUXDATA("st,nomadik-i2c", 0x80128000, "nmk-i2c.2", NULL),
+	OF_DEV_AUXDATA("st,nomadik-i2c", 0x80110000, "nmk-i2c.3", NULL),
+	OF_DEV_AUXDATA("st,nomadik-i2c", 0x8012a000, "nmk-i2c.4", NULL),
+	/* Requires device name bindings. */
+	OF_DEV_AUXDATA("stericsson,nmk_pinctrl", 0, "pinctrl-db8500", NULL),
+	/* Requires clock name and DMA bindings. */
+	OF_DEV_AUXDATA("stericsson,ux500-msp-i2s", 0x80123000,
+		"ux500-msp-i2s.0", &msp0_platform_data),
+	OF_DEV_AUXDATA("stericsson,ux500-msp-i2s", 0x80124000,
+		"ux500-msp-i2s.1", &msp1_platform_data),
+	OF_DEV_AUXDATA("stericsson,ux500-msp-i2s", 0x80117000,
+		"ux500-msp-i2s.2", &msp2_platform_data),
+	OF_DEV_AUXDATA("stericsson,ux500-msp-i2s", 0x80125000,
+		"ux500-msp-i2s.3", &msp3_platform_data),
+	{},
+};
+
+static const struct of_device_id u8500_local_bus_nodes[] = {
+	/* only create devices below soc node */
+	{ .compatible = "stericsson,db8500", },
+	{ .compatible = "stericsson,db8500-prcmu", },
+	{ .compatible = "simple-bus"},
+	{ },
+};
+
+static void __init u8500_init_machine(void)
+{
+	struct device *parent = NULL;
+
+	/* Pinmaps must be in place before devices register */
+	if (of_machine_is_compatible("st-ericsson,mop500"))
+		mop500_pinmaps_init();
+	else if (of_machine_is_compatible("calaosystems,snowball-a9500"))
+		snowball_pinmaps_init();
+	else if (of_machine_is_compatible("st-ericsson,hrefv60+"))
+		hrefv60_pinmaps_init();
+	else if (of_machine_is_compatible("st-ericsson,ccu9540")) {}
+		/* TODO: Add pinmaps for ccu9540 board. */
+
+	/* TODO: Export SoC, USB, cpu-freq and DMA40 */
+	parent = u8500_of_init_devices();
+
+	/* automatically probe child nodes of db8500 device */
+	of_platform_populate(NULL, u8500_local_bus_nodes, u8500_auxdata_lookup, parent);
+}
+
+static const char * stericsson_dt_platform_compat[] = {
+	"st-ericsson,u8500",
+	"st-ericsson,u8540",
+	"st-ericsson,u9500",
+	"st-ericsson,u9540",
+	NULL,
+};
+
+DT_MACHINE_START(U8500_DT, "ST-Ericsson Ux5x0 platform (Device Tree Support)")
+	.smp            = smp_ops(ux500_smp_ops),
+	.map_io		= u8500_map_io,
+	.init_irq	= ux500_init_irq,
+	/* we re-use nomadik timer here */
+	.timer		= &ux500_timer,
+	.handle_irq	= gic_handle_irq,
+	.init_machine	= u8500_init_machine,
+	.init_late	= NULL,
+	.dt_compat      = stericsson_dt_platform_compat,
+MACHINE_END
+
+#endif
diff --git a/arch/arm/mach-ux500/cpu.c b/arch/arm/mach-ux500/cpu.c
index 1f3fbc2..721e7b4 100644
--- a/arch/arm/mach-ux500/cpu.c
+++ b/arch/arm/mach-ux500/cpu.c
@@ -26,6 +26,8 @@
 #include <mach/setup.h>
 #include <mach/devices.h>
 
+#include "board-mop500.h"
+
 void __iomem *_PRCMU_BASE;
 
 /*
@@ -82,6 +84,7 @@
 
 void __init ux500_init_late(void)
 {
+	mop500_uib_init();
 }
 
 static const char * __init ux500_get_machine(void)
diff --git a/arch/arm/mach-ux500/devices-common.c b/arch/arm/mach-ux500/devices-common.c
index 692a77a..16b5f71 100644
--- a/arch/arm/mach-ux500/devices-common.c
+++ b/arch/arm/mach-ux500/devices-common.c
@@ -14,6 +14,7 @@
 #include <linux/platform_data/pinctrl-nomadik.h>
 
 #include <mach/hardware.h>
+#include <mach/irqs.h>
 
 #include "devices-common.h"
 
diff --git a/arch/arm/mach-ux500/devices-db8500.c b/arch/arm/mach-ux500/devices-db8500.c
index 91754a8..318d490 100644
--- a/arch/arm/mach-ux500/devices-db8500.c
+++ b/arch/arm/mach-ux500/devices-db8500.c
@@ -12,11 +12,11 @@
 #include <linux/gpio.h>
 #include <linux/amba/bus.h>
 #include <linux/amba/pl022.h>
-
-#include <plat/ste_dma40.h>
+#include <linux/platform_data/dma-ste-dma40.h>
 
 #include <mach/hardware.h>
 #include <mach/setup.h>
+#include <mach/irqs.h>
 
 #include "ste-dma40-db8500.h"
 
diff --git a/arch/arm/mach-ux500/devices-db8500.h b/arch/arm/mach-ux500/devices-db8500.h
index 3c8010f..4b24c99 100644
--- a/arch/arm/mach-ux500/devices-db8500.h
+++ b/arch/arm/mach-ux500/devices-db8500.h
@@ -8,6 +8,7 @@
 #ifndef __DEVICES_DB8500_H
 #define __DEVICES_DB8500_H
 
+#include <mach/irqs.h>
 #include "devices-common.h"
 
 struct ske_keypad_platform_data;
diff --git a/arch/arm/mach-ux500/include/mach/irqs.h b/arch/arm/mach-ux500/include/mach/irqs.h
index e892854..fc77b42 100644
--- a/arch/arm/mach-ux500/include/mach/irqs.h
+++ b/arch/arm/mach-ux500/include/mach/irqs.h
@@ -46,6 +46,6 @@
 #include <mach/irqs-board-mop500.h>
 #endif
 
-#define NR_IRQS			IRQ_BOARD_END
+#define UX500_NR_IRQS		IRQ_BOARD_END
 
 #endif /* ASM_ARCH_IRQS_H */
diff --git a/arch/arm/mach-ux500/include/mach/msp.h b/arch/arm/mach-ux500/include/mach/msp.h
index 3cc7142..9991aea 100644
--- a/arch/arm/mach-ux500/include/mach/msp.h
+++ b/arch/arm/mach-ux500/include/mach/msp.h
@@ -8,7 +8,7 @@
 #ifndef __MSP_H
 #define __MSP_H
 
-#include <plat/ste_dma40.h>
+#include <linux/platform_data/dma-ste-dma40.h>
 
 enum msp_i2s_id {
 	MSP_I2S_0 = 0,
diff --git a/arch/arm/mach-ux500/timer.c b/arch/arm/mach-ux500/timer.c
index 6f39731..875309a 100644
--- a/arch/arm/mach-ux500/timer.c
+++ b/arch/arm/mach-ux500/timer.c
@@ -9,11 +9,10 @@
 #include <linux/clksrc-dbx500-prcmu.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
+#include <linux/platform_data/clocksource-nomadik-mtu.h>
 
 #include <asm/smp_twd.h>
 
-#include <plat/mtu.h>
-
 #include <mach/setup.h>
 #include <mach/hardware.h>
 #include <mach/irqs.h>
@@ -96,7 +95,7 @@
 	 *
 	 */
 
-	nmdk_timer_init(mtu_timer_base);
+	nmdk_timer_init(mtu_timer_base, IRQ_MTU0);
 	clksrc_dbx500_prcmu_init(prcmu_timer_base);
 	ux500_twd_init();
 }
diff --git a/arch/arm/mach-ux500/usb.c b/arch/arm/mach-ux500/usb.c
index 145482e..78ac65f 100644
--- a/arch/arm/mach-ux500/usb.c
+++ b/arch/arm/mach-ux500/usb.c
@@ -7,10 +7,10 @@
 #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 <linux/platform_data/usb-musb-ux500.h>
+#include <linux/platform_data/dma-ste-dma40.h>
+
+#include <mach/hardware.h>
 
 #define MUSB_DMA40_RX_CH { \
 		.mode = STEDMA40_MODE_LOGICAL, \
diff --git a/arch/arm/mach-vexpress/reset.c b/arch/arm/mach-vexpress/reset.c
new file mode 100644
index 0000000..465923a
--- /dev/null
+++ b/arch/arm/mach-vexpress/reset.c
@@ -0,0 +1,141 @@
+/*
+ * 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.
+ *
+ * Copyright (C) 2012 ARM Limited
+ */
+
+#include <linux/jiffies.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/stat.h>
+#include <linux/vexpress.h>
+
+static void vexpress_reset_do(struct device *dev, const char *what)
+{
+	int err = -ENOENT;
+	struct vexpress_config_func *func =
+			vexpress_config_func_get_by_dev(dev);
+
+	if (func) {
+		unsigned long timeout;
+
+		err = vexpress_config_write(func, 0, 0);
+
+		timeout = jiffies + HZ;
+		while (time_before(jiffies, timeout))
+			cpu_relax();
+	}
+
+	dev_emerg(dev, "Unable to %s (%d)\n", what, err);
+}
+
+static struct device *vexpress_power_off_device;
+
+void vexpress_power_off(void)
+{
+	vexpress_reset_do(vexpress_power_off_device, "power off");
+}
+
+static struct device *vexpress_restart_device;
+
+void vexpress_restart(char str, const char *cmd)
+{
+	vexpress_reset_do(vexpress_restart_device, "restart");
+}
+
+static ssize_t vexpress_reset_active_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	return sprintf(buf, "%d\n", vexpress_restart_device == dev);
+}
+
+static ssize_t vexpress_reset_active_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count)
+{
+	long value;
+	int err = kstrtol(buf, 0, &value);
+
+	if (!err && value)
+		vexpress_restart_device = dev;
+
+	return err ? err : count;
+}
+
+DEVICE_ATTR(active, S_IRUGO | S_IWUSR, vexpress_reset_active_show,
+		vexpress_reset_active_store);
+
+
+enum vexpress_reset_func { FUNC_RESET, FUNC_SHUTDOWN, FUNC_REBOOT };
+
+static struct of_device_id vexpress_reset_of_match[] = {
+	{
+		.compatible = "arm,vexpress-reset",
+		.data = (void *)FUNC_RESET,
+	}, {
+		.compatible = "arm,vexpress-shutdown",
+		.data = (void *)FUNC_SHUTDOWN
+	}, {
+		.compatible = "arm,vexpress-reboot",
+		.data = (void *)FUNC_REBOOT
+	},
+	{}
+};
+
+static int vexpress_reset_probe(struct platform_device *pdev)
+{
+	enum vexpress_reset_func func;
+	const struct of_device_id *match =
+			of_match_device(vexpress_reset_of_match, &pdev->dev);
+
+	if (match)
+		func = (enum vexpress_reset_func)match->data;
+	else
+		func = pdev->id_entry->driver_data;
+
+	switch (func) {
+	case FUNC_SHUTDOWN:
+		vexpress_power_off_device = &pdev->dev;
+		break;
+	case FUNC_RESET:
+		if (!vexpress_restart_device)
+			vexpress_restart_device = &pdev->dev;
+		device_create_file(&pdev->dev, &dev_attr_active);
+		break;
+	case FUNC_REBOOT:
+		vexpress_restart_device = &pdev->dev;
+		device_create_file(&pdev->dev, &dev_attr_active);
+		break;
+	};
+
+	return 0;
+}
+
+static const struct platform_device_id vexpress_reset_id_table[] = {
+	{ .name = "vexpress-reset", .driver_data = FUNC_RESET, },
+	{ .name = "vexpress-shutdown", .driver_data = FUNC_SHUTDOWN, },
+	{ .name = "vexpress-reboot", .driver_data = FUNC_REBOOT, },
+	{}
+};
+
+static struct platform_driver vexpress_reset_driver = {
+	.probe = vexpress_reset_probe,
+	.driver = {
+		.name = "vexpress-reset",
+		.of_match_table = vexpress_reset_of_match,
+	},
+	.id_table = vexpress_reset_id_table,
+};
+
+static int __init vexpress_reset_init(void)
+{
+	return platform_driver_register(&vexpress_reset_driver);
+}
+device_initcall(vexpress_reset_init);
diff --git a/arch/arm/mach-vt8500/Kconfig b/arch/arm/mach-vt8500/Kconfig
new file mode 100644
index 0000000..2ed0b7d
--- /dev/null
+++ b/arch/arm/mach-vt8500/Kconfig
@@ -0,0 +1,12 @@
+config ARCH_VT8500
+	bool "VIA/WonderMedia 85xx" if ARCH_MULTI_V5
+	default ARCH_VT8500_SINGLE
+	select ARCH_HAS_CPUFREQ
+	select ARCH_REQUIRE_GPIOLIB
+	select CLKDEV_LOOKUP
+	select CPU_ARM926T
+	select GENERIC_CLOCKEVENTS
+	select GENERIC_GPIO
+	select HAVE_CLK
+	help
+	  Support for VIA/WonderMedia VT8500/WM85xx System-on-Chip.
diff --git a/arch/arm/mach-vt8500/common.h b/arch/arm/mach-vt8500/common.h
index 2b24196..6f2b843 100644
--- a/arch/arm/mach-vt8500/common.h
+++ b/arch/arm/mach-vt8500/common.h
@@ -25,4 +25,7 @@
 /* defined in drivers/clk/clk-vt8500.c */
 void __init vtwm_clk_init(void __iomem *pmc_base);
 
+/* defined in irq.c */
+asmlinkage void vt8500_handle_irq(struct pt_regs *regs);
+
 #endif
diff --git a/arch/arm/mach-vt8500/include/mach/entry-macro.S b/arch/arm/mach-vt8500/include/mach/entry-macro.S
deleted file mode 100644
index 367d1b5..0000000
--- a/arch/arm/mach-vt8500/include/mach/entry-macro.S
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * arch/arm/mach-vt8500/include/mach/entry-macro.S
- *
- * Low-level IRQ helper macros for VIA VT8500
- *
- * 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.
- */
-
-	.macro  get_irqnr_preamble, base, tmp
-	@ physical 0xd8140000 is virtual 0xf8140000
-	mov	\base, #0xf8000000
-	orr	\base, \base, #0x00140000
-	.endm
-
-	.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
-	ldr	\irqnr, [\base]
-	cmp	\irqnr, #63 @ may be false positive, check interrupt status
-	bne	1001f
-	ldr	\irqstat, [\base, #0x84]
-	ands	\irqstat, #0x80000000
-	moveq	\irqnr, #0
-1001:
-	.endm
-
diff --git a/arch/arm/mach-vt8500/irq.c b/arch/arm/mach-vt8500/irq.c
index f8f9ab9..b9cf5ce 100644
--- a/arch/arm/mach-vt8500/irq.c
+++ b/arch/arm/mach-vt8500/irq.c
@@ -36,7 +36,7 @@
 #include <linux/of_address.h>
 
 #include <asm/irq.h>
-
+#include <asm/exception.h>
 
 #define VT8500_ICPC_IRQ		0x20
 #define VT8500_ICPC_FIQ		0x24
@@ -66,30 +66,34 @@
 #define VT8500_EDGE		( VT8500_TRIGGER_RISING \
 				| VT8500_TRIGGER_FALLING)
 
-static int irq_cnt;
+/* vt8500 has 1 intc, wm8505 and wm8650 have 2 */
+#define VT8500_INTC_MAX		2
 
-struct vt8500_irq_priv {
-	void __iomem *base;
+struct vt8500_irq_data {
+	void __iomem 		*base;		/* IO Memory base address */
+	struct irq_domain	*domain;	/* Domain for this controller */
 };
 
+/* Global variable for accessing io-mem addresses */
+static struct vt8500_irq_data intc[VT8500_INTC_MAX];
+static u32 active_cnt = 0;
+
 static void vt8500_irq_mask(struct irq_data *d)
 {
-	struct vt8500_irq_priv *priv =
-			(struct vt8500_irq_priv *)(d->domain->host_data);
+	struct vt8500_irq_data *priv = d->domain->host_data;
 	void __iomem *base = priv->base;
-	u8 edge;
+	void __iomem *stat_reg = base + VT8500_ICIS + (d->hwirq < 32 ? 0 : 4);
+	u8 edge, dctr;
+	u32 status;
 
 	edge = readb(base + VT8500_ICDC + d->hwirq) & VT8500_EDGE;
 	if (edge) {
-		void __iomem *stat_reg = base + VT8500_ICIS
-						+ (d->hwirq < 32 ? 0 : 4);
-		unsigned status = readl(stat_reg);
+		status = readl(stat_reg);
 
 		status |= (1 << (d->hwirq & 0x1f));
 		writel(status, stat_reg);
 	} else {
-		u8 dctr = readb(base + VT8500_ICDC + d->hwirq);
-
+		dctr = readb(base + VT8500_ICDC + d->hwirq);
 		dctr &= ~VT8500_INT_ENABLE;
 		writeb(dctr, base + VT8500_ICDC + d->hwirq);
 	}
@@ -97,8 +101,7 @@
 
 static void vt8500_irq_unmask(struct irq_data *d)
 {
-	struct vt8500_irq_priv *priv =
-			(struct vt8500_irq_priv *)(d->domain->host_data);
+	struct vt8500_irq_data *priv = d->domain->host_data;
 	void __iomem *base = priv->base;
 	u8 dctr;
 
@@ -109,8 +112,7 @@
 
 static int vt8500_irq_set_type(struct irq_data *d, unsigned int flow_type)
 {
-	struct vt8500_irq_priv *priv =
-			(struct vt8500_irq_priv *)(d->domain->host_data);
+	struct vt8500_irq_data *priv = d->domain->host_data;
 	void __iomem *base = priv->base;
 	u8 dctr;
 
@@ -148,17 +150,15 @@
 
 static void __init vt8500_init_irq_hw(void __iomem *base)
 {
-	unsigned int i;
+	u32 i;
 
 	/* Enable rotating priority for IRQ */
 	writel(ICPC_ROTATE, base + VT8500_ICPC_IRQ);
 	writel(0x00, base + VT8500_ICPC_FIQ);
 
-	for (i = 0; i < 64; i++) {
-		/* Disable all interrupts and route them to IRQ */
-		writeb(VT8500_INT_DISABLE | ICDC_IRQ,
-						base + VT8500_ICDC + i);
-	}
+	/* Disable all interrupts and route them to IRQ */
+	for (i = 0; i < 64; i++)
+		writeb(VT8500_INT_DISABLE | ICDC_IRQ, base + VT8500_ICDC + i);
 }
 
 static int vt8500_irq_map(struct irq_domain *h, unsigned int virq,
@@ -175,33 +175,67 @@
 	.xlate = irq_domain_xlate_onecell,
 };
 
+asmlinkage void __exception_irq_entry vt8500_handle_irq(struct pt_regs *regs)
+{
+	u32 stat, i;
+	int irqnr, virq;
+	void __iomem *base;
+
+	/* Loop through each active controller */
+	for (i=0; i<active_cnt; i++) {
+		base = intc[i].base;
+		irqnr = readl_relaxed(base) & 0x3F;
+		/*
+		  Highest Priority register default = 63, so check that this
+		  is a real interrupt by checking the status register
+		*/
+		if (irqnr == 63) {
+			stat = readl_relaxed(base + VT8500_ICIS + 4);
+			if (!(stat & BIT(31)))
+				continue;
+		}
+
+		virq = irq_find_mapping(intc[i].domain, irqnr);
+		handle_IRQ(virq, regs);
+	}
+}
+
 int __init vt8500_irq_init(struct device_node *node, struct device_node *parent)
 {
-	struct irq_domain *vt8500_irq_domain;
-	struct vt8500_irq_priv *priv;
 	int irq, i;
 	struct device_node *np = node;
 
-	priv = kzalloc(sizeof(struct vt8500_irq_priv), GFP_KERNEL);
-	priv->base = of_iomap(np, 0);
+	if (active_cnt == VT8500_INTC_MAX) {
+		pr_err("%s: Interrupt controllers > VT8500_INTC_MAX\n",
+								__func__);
+		goto out;
+	}
 
-	vt8500_irq_domain = irq_domain_add_legacy(node, 64, irq_cnt, 0,
-				&vt8500_irq_domain_ops, priv);
-	if (!vt8500_irq_domain)
-		pr_err("%s: Unable to add wmt irq domain!\n", __func__);
+	intc[active_cnt].base = of_iomap(np, 0);
+	intc[active_cnt].domain = irq_domain_add_linear(node, 64,
+			&vt8500_irq_domain_ops,	&intc[active_cnt]);
 
-	irq_set_default_host(vt8500_irq_domain);
+	if (!intc[active_cnt].base) {
+		pr_err("%s: Unable to map IO memory\n", __func__);
+		goto out;
+	}
 
-	vt8500_init_irq_hw(priv->base);
+	if (!intc[active_cnt].domain) {
+		pr_err("%s: Unable to add irq domain!\n", __func__);
+		goto out;
+	}
 
-	pr_info("Added IRQ Controller @ %x [virq_base = %d]\n",
-						(u32)(priv->base), irq_cnt);
+	vt8500_init_irq_hw(intc[active_cnt].base);
+
+	pr_info("vt8500-irq: Added interrupt controller\n");
+
+	active_cnt++;
 
 	/* check if this is a slaved controller */
 	if (of_irq_count(np) != 0) {
 		/* check that we have the correct number of interrupts */
 		if (of_irq_count(np) != 8) {
-			pr_err("%s: Incorrect IRQ map for slave controller\n",
+			pr_err("%s: Incorrect IRQ map for slaved controller\n",
 					__func__);
 			return -EINVAL;
 		}
@@ -213,9 +247,7 @@
 
 		pr_info("vt8500-irq: Enabled slave->parent interrupts\n");
 	}
-
-	irq_cnt += 64;
-
+out:
 	return 0;
 }
 
diff --git a/arch/arm/mach-vt8500/vt8500.c b/arch/arm/mach-vt8500/vt8500.c
index a5bd286..3c66d48 100644
--- a/arch/arm/mach-vt8500/vt8500.c
+++ b/arch/arm/mach-vt8500/vt8500.c
@@ -192,5 +192,6 @@
 	.timer		= &vt8500_timer,
 	.init_machine	= vt8500_init,
 	.restart	= vt8500_restart,
+	.handle_irq	= vt8500_handle_irq,
 MACHINE_END
 
diff --git a/arch/arm/mach-zynq/Kconfig b/arch/arm/mach-zynq/Kconfig
new file mode 100644
index 0000000..adb6c0e
--- /dev/null
+++ b/arch/arm/mach-zynq/Kconfig
@@ -0,0 +1,13 @@
+config ARCH_ZYNQ
+	bool "Xilinx Zynq ARM Cortex A9 Platform" if ARCH_MULTI_V7
+	select ARM_AMBA
+	select ARM_GIC
+	select COMMON_CLK
+	select CPU_V7
+	select GENERIC_CLOCKEVENTS
+	select ICST
+	select MIGHT_HAVE_CACHE_L2X0
+	select USE_OF
+	select SPARSE_IRQ
+	help
+	  Support for Xilinx Zynq ARM Cortex A9 Platform
diff --git a/arch/arm/mach-zynq/common.c b/arch/arm/mach-zynq/common.c
index ba8d14f..e16d4be 100644
--- a/arch/arm/mach-zynq/common.c
+++ b/arch/arm/mach-zynq/common.c
@@ -19,18 +19,21 @@
 #include <linux/cpumask.h>
 #include <linux/platform_device.h>
 #include <linux/clk.h>
+#include <linux/clk/zynq.h>
+#include <linux/of_address.h>
 #include <linux/of_irq.h>
 #include <linux/of_platform.h>
 #include <linux/of.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
+#include <asm/mach/time.h>
 #include <asm/mach-types.h>
 #include <asm/page.h>
+#include <asm/pgtable.h>
 #include <asm/hardware/gic.h>
 #include <asm/hardware/cache-l2x0.h>
 
-#include <mach/zynq_soc.h>
 #include "common.h"
 
 static struct of_device_id zynq_of_bus_ids[] __initdata = {
@@ -65,32 +68,36 @@
 	of_irq_init(irq_match);
 }
 
-/* The minimum devices needed to be mapped before the VM system is up and
- * running include the GIC, UART and Timer Counter.
+#define SCU_PERIPH_PHYS		0xF8F00000
+#define SCU_PERIPH_SIZE		SZ_8K
+#define SCU_PERIPH_VIRT		(VMALLOC_END - SCU_PERIPH_SIZE)
+
+static struct map_desc scu_desc __initdata = {
+	.virtual	= SCU_PERIPH_VIRT,
+	.pfn		= __phys_to_pfn(SCU_PERIPH_PHYS),
+	.length		= SCU_PERIPH_SIZE,
+	.type		= MT_DEVICE,
+};
+
+static void __init xilinx_zynq_timer_init(void)
+{
+	struct device_node *np;
+	void __iomem *slcr;
+
+	np = of_find_compatible_node(NULL, NULL, "xlnx,zynq-slcr");
+	slcr = of_iomap(np, 0);
+	WARN_ON(!slcr);
+
+	xilinx_zynq_clocks_init(slcr);
+
+	xttcpss_timer_init();
+}
+
+/*
+ * Instantiate and initialize the system timer structure
  */
-
-static struct map_desc io_desc[] __initdata = {
-	{
-		.virtual	= TTC0_VIRT,
-		.pfn		= __phys_to_pfn(TTC0_PHYS),
-		.length		= TTC0_SIZE,
-		.type		= MT_DEVICE,
-	}, {
-		.virtual	= SCU_PERIPH_VIRT,
-		.pfn		= __phys_to_pfn(SCU_PERIPH_PHYS),
-		.length		= SCU_PERIPH_SIZE,
-		.type		= MT_DEVICE,
-	},
-
-#ifdef CONFIG_DEBUG_LL
-	{
-		.virtual	= UART0_VIRT,
-		.pfn		= __phys_to_pfn(UART0_PHYS),
-		.length		= UART0_SIZE,
-		.type		= MT_DEVICE,
-	},
-#endif
-
+static struct sys_timer xttcpss_sys_timer = {
+	.init		= xilinx_zynq_timer_init,
 };
 
 /**
@@ -98,11 +105,13 @@
  */
 static void __init xilinx_map_io(void)
 {
-	iotable_init(io_desc, ARRAY_SIZE(io_desc));
+	debug_ll_io_init();
+	iotable_init(&scu_desc, 1);
 }
 
 static const char *xilinx_dt_match[] = {
-	"xlnx,zynq-ep107",
+	"xlnx,zynq-zc702",
+	"xlnx,zynq-7000",
 	NULL
 };
 
diff --git a/arch/arm/mach-zynq/common.h b/arch/arm/mach-zynq/common.h
index a009644..954b91c 100644
--- a/arch/arm/mach-zynq/common.h
+++ b/arch/arm/mach-zynq/common.h
@@ -17,8 +17,6 @@
 #ifndef __MACH_ZYNQ_COMMON_H__
 #define __MACH_ZYNQ_COMMON_H__
 
-#include <asm/mach/time.h>
-
-extern struct sys_timer xttcpss_sys_timer;
+void __init xttcpss_timer_init(void);
 
 #endif
diff --git a/arch/arm/mach-zynq/include/mach/hardware.h b/arch/arm/mach-zynq/include/mach/hardware.h
deleted file mode 100644
index d558d8a..0000000
--- a/arch/arm/mach-zynq/include/mach/hardware.h
+++ /dev/null
@@ -1,18 +0,0 @@
-/* arch/arm/mach-zynq/include/mach/hardware.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_HARDWARE_H__
-#define __MACH_HARDWARE_H__
-
-#endif
diff --git a/arch/arm/mach-zynq/include/mach/irqs.h b/arch/arm/mach-zynq/include/mach/irqs.h
deleted file mode 100644
index 5fb04fd..0000000
--- a/arch/arm/mach-zynq/include/mach/irqs.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/* arch/arm/mach-zynq/include/mach/irqs.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_IRQS_H
-#define __MACH_IRQS_H
-
-#define ARCH_NR_GPIOS	118
-#define NR_IRQS		(128 + ARCH_NR_GPIOS)
-
-#endif
diff --git a/arch/arm/mach-zynq/include/mach/timex.h b/arch/arm/mach-zynq/include/mach/timex.h
deleted file mode 100644
index 6c0245e..0000000
--- a/arch/arm/mach-zynq/include/mach/timex.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/* arch/arm/mach-zynq/include/mach/timex.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_TIMEX_H__
-#define __MACH_TIMEX_H__
-
-/* the following is needed for the system to build but will be removed
-   in the future, the value is not important but won't hurt
-*/
-#define CLOCK_TICK_RATE	(100 * HZ)
-
-#endif
diff --git a/arch/arm/mach-zynq/include/mach/uart.h b/arch/arm/mach-zynq/include/mach/uart.h
deleted file mode 100644
index 5c47c97..0000000
--- a/arch/arm/mach-zynq/include/mach/uart.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/* arch/arm/mach-zynq/include/mach/uart.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_UART_H__
-#define __MACH_UART_H__
-
-#define UART_CR_OFFSET		0x00  /* Control Register [8:0] */
-#define UART_SR_OFFSET		0x2C  /* Channel Status [11:0] */
-#define UART_FIFO_OFFSET	0x30  /* FIFO [15:0] or [7:0] */
-
-#define UART_SR_TXFULL		0x00000010	/* TX FIFO full */
-#define UART_SR_TXEMPTY		0x00000008	/* TX FIFO empty */
-
-#endif
diff --git a/arch/arm/mach-zynq/include/mach/uncompress.h b/arch/arm/mach-zynq/include/mach/uncompress.h
deleted file mode 100644
index af4e844..0000000
--- a/arch/arm/mach-zynq/include/mach/uncompress.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/* arch/arm/mach-zynq/include/mach/uncompress.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_UNCOMPRESS_H__
-#define __MACH_UNCOMPRESS_H__
-
-#include <linux/io.h>
-#include <asm/processor.h>
-#include <mach/zynq_soc.h>
-#include <mach/uart.h>
-
-void arch_decomp_setup(void)
-{
-}
-
-static inline void flush(void)
-{
-	/*
-	 * Wait while the FIFO is not empty
-	 */
-	while (!(__raw_readl(IOMEM(LL_UART_PADDR + UART_SR_OFFSET)) &
-		UART_SR_TXEMPTY))
-		cpu_relax();
-}
-
-#define arch_decomp_wdog()
-
-static void putc(char ch)
-{
-	/*
-	 * Wait for room in the FIFO, then write the char into the FIFO
-	 */
-	while (__raw_readl(IOMEM(LL_UART_PADDR + UART_SR_OFFSET)) &
-		UART_SR_TXFULL)
-		cpu_relax();
-
-	__raw_writel(ch, IOMEM(LL_UART_PADDR + UART_FIFO_OFFSET));
-}
-
-#endif
diff --git a/arch/arm/mach-zynq/include/mach/zynq_soc.h b/arch/arm/mach-zynq/include/mach/zynq_soc.h
deleted file mode 100644
index 1b8bf0e..0000000
--- a/arch/arm/mach-zynq/include/mach/zynq_soc.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/* arch/arm/mach-zynq/include/mach/zynq_soc.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_XILINX_SOC_H__
-#define __MACH_XILINX_SOC_H__
-
-#include <asm/pgtable.h>
-
-#define PERIPHERAL_CLOCK_RATE		2500000
-
-/* Static peripheral mappings are mapped at the top of the vmalloc region.  The
- * early uart mapping causes intermediate problems/failure at certain
- * addresses, including the very top of the vmalloc region.  Map it at an
- * address that is known to work.
- */
-#define UART0_PHYS		0xE0000000
-#define UART0_SIZE		SZ_4K
-#define UART0_VIRT		0xF0001000
-
-#define TTC0_PHYS		0xF8001000
-#define TTC0_SIZE		SZ_4K
-#define TTC0_VIRT		(VMALLOC_END - TTC0_SIZE)
-
-#define SCU_PERIPH_PHYS		0xF8F00000
-#define SCU_PERIPH_SIZE		SZ_8K
-#define SCU_PERIPH_VIRT		(TTC0_VIRT - SCU_PERIPH_SIZE)
-
-/* The following are intended for the devices that are mapped early */
-
-#define TTC0_BASE			IOMEM(TTC0_VIRT)
-#define SCU_PERIPH_BASE			IOMEM(SCU_PERIPH_VIRT)
-
-#define LL_UART_PADDR	UART0_PHYS
-#define LL_UART_VADDR	UART0_VIRT
-
-#endif
diff --git a/arch/arm/mach-zynq/timer.c b/arch/arm/mach-zynq/timer.c
index c2c96cc..de3df28 100644
--- a/arch/arm/mach-zynq/timer.c
+++ b/arch/arm/mach-zynq/timer.c
@@ -23,32 +23,14 @@
 #include <linux/clocksource.h>
 #include <linux/clockchips.h>
 #include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/slab.h>
+#include <linux/clk-provider.h>
 
-#include <asm/mach/time.h>
-#include <mach/zynq_soc.h>
 #include "common.h"
 
-#define IRQ_TIMERCOUNTER0	42
-
-/*
- * This driver configures the 2 16-bit count-up timers as follows:
- *
- * T1: Timer 1, clocksource for generic timekeeping
- * T2: Timer 2, clockevent source for hrtimers
- * T3: Timer 3, <unused>
- *
- * The input frequency to the timer module for emulation is 2.5MHz which is
- * common to all the timer channels (T1, T2, and T3). With a pre-scaler of 32,
- * the timers are clocked at 78.125KHz (12.8 us resolution).
- *
- * The input frequency to the timer module in silicon will be 200MHz. With the
- * pre-scaler of 32, the timers are clocked at 6.25MHz (160ns resolution).
- */
-#define XTTCPSS_CLOCKSOURCE	0	/* Timer 1 as a generic timekeeping */
-#define XTTCPSS_CLOCKEVENT	1	/* Timer 2 as a clock event */
-
-#define XTTCPSS_TIMER_BASE		TTC0_BASE
-#define XTTCPCC_EVENT_TIMER_IRQ		(IRQ_TIMERCOUNTER0 + 1)
 /*
  * Timer Register Offset Definitions of Timer 1, Increment base address by 4
  * and use same offsets for Timer 2
@@ -65,9 +47,14 @@
 
 #define XTTCPSS_CNT_CNTRL_DISABLE_MASK	0x1
 
-/* Setup the timers to use pre-scaling */
-
-#define TIMER_RATE (PERIPHERAL_CLOCK_RATE / 32)
+/* Setup the timers to use pre-scaling, using a fixed value for now that will
+ * work across most input frequency, but it may need to be more dynamic
+ */
+#define PRESCALE_EXPONENT	11	/* 2 ^ PRESCALE_EXPONENT = PRESCALE */
+#define PRESCALE		2048	/* The exponent must match this */
+#define CLK_CNTRL_PRESCALE	((PRESCALE_EXPONENT - 1) << 1)
+#define CLK_CNTRL_PRESCALE_EN	1
+#define CNT_CNTRL_RESET		(1<<4)
 
 /**
  * struct xttcpss_timer - This definition defines local timer structure
@@ -75,11 +62,25 @@
  * @base_addr:	Base address of timer
  **/
 struct xttcpss_timer {
-	void __iomem *base_addr;
+	void __iomem	*base_addr;
 };
 
-static struct xttcpss_timer timers[2];
-static struct clock_event_device xttcpss_clockevent;
+struct xttcpss_timer_clocksource {
+	struct xttcpss_timer	xttc;
+	struct clocksource	cs;
+};
+
+#define to_xttcpss_timer_clksrc(x) \
+		container_of(x, struct xttcpss_timer_clocksource, cs)
+
+struct xttcpss_timer_clockevent {
+	struct xttcpss_timer		xttc;
+	struct clock_event_device	ce;
+	struct clk			*clk;
+};
+
+#define to_xttcpss_timer_clkevent(x) \
+		container_of(x, struct xttcpss_timer_clockevent, ce)
 
 /**
  * xttcpss_set_interval - Set the timer interval value
@@ -101,7 +102,7 @@
 
 	/* Reset the counter (0x10) so that it starts from 0, one-shot
 	   mode makes this needed for timing to be right. */
-	ctrl_reg |= 0x10;
+	ctrl_reg |= CNT_CNTRL_RESET;
 	ctrl_reg &= ~XTTCPSS_CNT_CNTRL_DISABLE_MASK;
 	__raw_writel(ctrl_reg, timer->base_addr + XTTCPSS_CNT_CNTRL_OFFSET);
 }
@@ -116,90 +117,31 @@
  **/
 static irqreturn_t xttcpss_clock_event_interrupt(int irq, void *dev_id)
 {
-	struct clock_event_device *evt = &xttcpss_clockevent;
-	struct xttcpss_timer *timer = dev_id;
+	struct xttcpss_timer_clockevent *xttce = dev_id;
+	struct xttcpss_timer *timer = &xttce->xttc;
 
 	/* Acknowledge the interrupt and call event handler */
 	__raw_writel(__raw_readl(timer->base_addr + XTTCPSS_ISR_OFFSET),
 			timer->base_addr + XTTCPSS_ISR_OFFSET);
 
-	evt->event_handler(evt);
+	xttce->ce.event_handler(&xttce->ce);
 
 	return IRQ_HANDLED;
 }
 
-static struct irqaction event_timer_irq = {
-	.name	= "xttcpss clockevent",
-	.flags	= IRQF_DISABLED | IRQF_TIMER,
-	.handler = xttcpss_clock_event_interrupt,
-};
-
 /**
- * xttcpss_timer_hardware_init - Initialize the timer hardware
- *
- * Initialize the hardware to start the clock source, get the clock
- * event timer ready to use, and hook up the interrupt.
- **/
-static void __init xttcpss_timer_hardware_init(void)
-{
-	/* Setup the clock source counter to be an incrementing counter
-	 * with no interrupt and it rolls over at 0xFFFF. Pre-scale
-	   it by 32 also. Let it start running now.
-	 */
-	timers[XTTCPSS_CLOCKSOURCE].base_addr = XTTCPSS_TIMER_BASE;
-
-	__raw_writel(0x0, timers[XTTCPSS_CLOCKSOURCE].base_addr +
-				XTTCPSS_IER_OFFSET);
-	__raw_writel(0x9, timers[XTTCPSS_CLOCKSOURCE].base_addr +
-				XTTCPSS_CLK_CNTRL_OFFSET);
-	__raw_writel(0x10, timers[XTTCPSS_CLOCKSOURCE].base_addr +
-				XTTCPSS_CNT_CNTRL_OFFSET);
-
-	/* Setup the clock event timer to be an interval timer which
-	 * is prescaled by 32 using the interval interrupt. Leave it
-	 * disabled for now.
-	 */
-
-	timers[XTTCPSS_CLOCKEVENT].base_addr = XTTCPSS_TIMER_BASE + 4;
-
-	__raw_writel(0x23, timers[XTTCPSS_CLOCKEVENT].base_addr +
-			XTTCPSS_CNT_CNTRL_OFFSET);
-	__raw_writel(0x9, timers[XTTCPSS_CLOCKEVENT].base_addr +
-			XTTCPSS_CLK_CNTRL_OFFSET);
-	__raw_writel(0x1, timers[XTTCPSS_CLOCKEVENT].base_addr +
-			XTTCPSS_IER_OFFSET);
-
-	/* Setup IRQ the clock event timer */
-	event_timer_irq.dev_id = &timers[XTTCPSS_CLOCKEVENT];
-	setup_irq(XTTCPCC_EVENT_TIMER_IRQ, &event_timer_irq);
-}
-
-/**
- * __raw_readl_cycles - Reads the timer counter register
+ * __xttc_clocksource_read - Reads the timer counter register
  *
  * returns: Current timer counter register value
  **/
-static cycle_t __raw_readl_cycles(struct clocksource *cs)
+static cycle_t __xttc_clocksource_read(struct clocksource *cs)
 {
-	struct xttcpss_timer *timer = &timers[XTTCPSS_CLOCKSOURCE];
+	struct xttcpss_timer *timer = &to_xttcpss_timer_clksrc(cs)->xttc;
 
 	return (cycle_t)__raw_readl(timer->base_addr +
 				XTTCPSS_COUNT_VAL_OFFSET);
 }
 
-
-/*
- * Instantiate and initialize the clock source structure
- */
-static struct clocksource clocksource_xttcpss = {
-	.name		= "xttcpss_timer1",
-	.rating		= 200,			/* Reasonable clock source */
-	.read		= __raw_readl_cycles,
-	.mask		= CLOCKSOURCE_MASK(16),
-	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
-};
-
-
 /**
  * xttcpss_set_next_event - Sets the time interval for next event
  *
@@ -211,7 +153,8 @@
 static int xttcpss_set_next_event(unsigned long cycles,
 					struct clock_event_device *evt)
 {
-	struct xttcpss_timer *timer = &timers[XTTCPSS_CLOCKEVENT];
+	struct xttcpss_timer_clockevent *xttce = to_xttcpss_timer_clkevent(evt);
+	struct xttcpss_timer *timer = &xttce->xttc;
 
 	xttcpss_set_interval(timer, cycles);
 	return 0;
@@ -226,12 +169,15 @@
 static void xttcpss_set_mode(enum clock_event_mode mode,
 					struct clock_event_device *evt)
 {
-	struct xttcpss_timer *timer = &timers[XTTCPSS_CLOCKEVENT];
+	struct xttcpss_timer_clockevent *xttce = to_xttcpss_timer_clkevent(evt);
+	struct xttcpss_timer *timer = &xttce->xttc;
 	u32 ctrl_reg;
 
 	switch (mode) {
 	case CLOCK_EVT_MODE_PERIODIC:
-		xttcpss_set_interval(timer, TIMER_RATE / HZ);
+		xttcpss_set_interval(timer,
+				     DIV_ROUND_CLOSEST(clk_get_rate(xttce->clk),
+						       PRESCALE * HZ));
 		break;
 	case CLOCK_EVT_MODE_ONESHOT:
 	case CLOCK_EVT_MODE_UNUSED:
@@ -252,15 +198,106 @@
 	}
 }
 
-/*
- * Instantiate and initialize the clock event structure
- */
-static struct clock_event_device xttcpss_clockevent = {
-	.name		= "xttcpss_timer2",
-	.features	= CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
-	.set_next_event	= xttcpss_set_next_event,
-	.set_mode	= xttcpss_set_mode,
-	.rating		= 200,
+static void __init zynq_ttc_setup_clocksource(struct device_node *np,
+					     void __iomem *base)
+{
+	struct xttcpss_timer_clocksource *ttccs;
+	struct clk *clk;
+	int err;
+	u32 reg;
+
+	ttccs = kzalloc(sizeof(*ttccs), GFP_KERNEL);
+	if (WARN_ON(!ttccs))
+		return;
+
+	err = of_property_read_u32(np, "reg", &reg);
+	if (WARN_ON(err))
+		return;
+
+	clk = of_clk_get_by_name(np, "cpu_1x");
+	if (WARN_ON(IS_ERR(clk)))
+		return;
+
+	err = clk_prepare_enable(clk);
+	if (WARN_ON(err))
+		return;
+
+	ttccs->xttc.base_addr = base + reg * 4;
+
+	ttccs->cs.name = np->name;
+	ttccs->cs.rating = 200;
+	ttccs->cs.read = __xttc_clocksource_read;
+	ttccs->cs.mask = CLOCKSOURCE_MASK(16);
+	ttccs->cs.flags = CLOCK_SOURCE_IS_CONTINUOUS;
+
+	__raw_writel(0x0,  ttccs->xttc.base_addr + XTTCPSS_IER_OFFSET);
+	__raw_writel(CLK_CNTRL_PRESCALE | CLK_CNTRL_PRESCALE_EN,
+		     ttccs->xttc.base_addr + XTTCPSS_CLK_CNTRL_OFFSET);
+	__raw_writel(CNT_CNTRL_RESET,
+		     ttccs->xttc.base_addr + XTTCPSS_CNT_CNTRL_OFFSET);
+
+	err = clocksource_register_hz(&ttccs->cs, clk_get_rate(clk) / PRESCALE);
+	if (WARN_ON(err))
+		return;
+}
+
+static void __init zynq_ttc_setup_clockevent(struct device_node *np,
+					    void __iomem *base)
+{
+	struct xttcpss_timer_clockevent *ttcce;
+	int err, irq;
+	u32 reg;
+
+	ttcce = kzalloc(sizeof(*ttcce), GFP_KERNEL);
+	if (WARN_ON(!ttcce))
+		return;
+
+	err = of_property_read_u32(np, "reg", &reg);
+	if (WARN_ON(err))
+		return;
+
+	ttcce->xttc.base_addr = base + reg * 4;
+
+	ttcce->clk = of_clk_get_by_name(np, "cpu_1x");
+	if (WARN_ON(IS_ERR(ttcce->clk)))
+		return;
+
+	err = clk_prepare_enable(ttcce->clk);
+	if (WARN_ON(err))
+		return;
+
+	irq = irq_of_parse_and_map(np, 0);
+	if (WARN_ON(!irq))
+		return;
+
+	ttcce->ce.name = np->name;
+	ttcce->ce.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT;
+	ttcce->ce.set_next_event = xttcpss_set_next_event;
+	ttcce->ce.set_mode = xttcpss_set_mode;
+	ttcce->ce.rating = 200;
+	ttcce->ce.irq = irq;
+
+	__raw_writel(0x23, ttcce->xttc.base_addr + XTTCPSS_CNT_CNTRL_OFFSET);
+	__raw_writel(CLK_CNTRL_PRESCALE | CLK_CNTRL_PRESCALE_EN,
+		     ttcce->xttc.base_addr + XTTCPSS_CLK_CNTRL_OFFSET);
+	__raw_writel(0x1,  ttcce->xttc.base_addr + XTTCPSS_IER_OFFSET);
+
+	err = request_irq(irq, xttcpss_clock_event_interrupt, IRQF_TIMER,
+			  np->name, ttcce);
+	if (WARN_ON(err))
+		return;
+
+	clockevents_config_and_register(&ttcce->ce,
+					clk_get_rate(ttcce->clk) / PRESCALE,
+					1, 0xfffe);
+}
+
+static const __initconst struct of_device_id zynq_ttc_match[] = {
+	{ .compatible = "xlnx,ttc-counter-clocksource",
+		.data = zynq_ttc_setup_clocksource, },
+	{ .compatible = "xlnx,ttc-counter-clockevent",
+		.data = zynq_ttc_setup_clockevent, },
+	{}
 };
 
 /**
@@ -269,30 +306,27 @@
  * Initializes the timer hardware and register the clock source and clock event
  * timers with Linux kernal timer framework
  **/
-static void __init xttcpss_timer_init(void)
+void __init xttcpss_timer_init(void)
 {
-	xttcpss_timer_hardware_init();
-	clocksource_register_hz(&clocksource_xttcpss, TIMER_RATE);
+	struct device_node *np;
 
-	/* Calculate the parameters to allow the clockevent to operate using
-	   integer math
-	*/
-	clockevents_calc_mult_shift(&xttcpss_clockevent, TIMER_RATE, 4);
+	for_each_compatible_node(np, NULL, "xlnx,ttc") {
+		struct device_node *np_chld;
+		void __iomem *base;
 
-	xttcpss_clockevent.max_delta_ns =
-		clockevent_delta2ns(0xfffe, &xttcpss_clockevent);
-	xttcpss_clockevent.min_delta_ns =
-		clockevent_delta2ns(1, &xttcpss_clockevent);
+		base = of_iomap(np, 0);
+		if (WARN_ON(!base))
+			return;
 
-	/* Indicate that clock event is on 1st CPU as SMP boot needs it */
+		for_each_available_child_of_node(np, np_chld) {
+			int (*cb)(struct device_node *np, void __iomem *base);
+			const struct of_device_id *match;
 
-	xttcpss_clockevent.cpumask = cpumask_of(0);
-	clockevents_register_device(&xttcpss_clockevent);
+			match = of_match_node(zynq_ttc_match, np_chld);
+			if (match) {
+				cb = match->data;
+				cb(np_chld, base);
+			}
+		}
+	}
 }
-
-/*
- * Instantiate and initialize the system timer structure
- */
-struct sys_timer xttcpss_sys_timer = {
-	.init		= xttcpss_timer_init,
-};
diff --git a/arch/arm/plat-nomadik/Kconfig b/arch/arm/plat-nomadik/Kconfig
deleted file mode 100644
index 19f55ca..0000000
--- a/arch/arm/plat-nomadik/Kconfig
+++ /dev/null
@@ -1,29 +0,0 @@
-# We keep common IP's here for Nomadik and other similar
-# familiy of processors from ST-Ericsson. At the moment we have
-# just MTU, others to follow soon.
-
-config PLAT_NOMADIK
-	bool
-	depends on ARCH_NOMADIK || ARCH_U8500
-	default y
-	select CLKSRC_MMIO
-	help
-	  Common platform code for Nomadik and other ST-Ericsson
-	  platforms.
-
-if PLAT_NOMADIK
-
-config HAS_MTU
-	bool
-	help
-	  Support for Multi Timer Unit. MTU provides access
-	  to multiple interrupt generating programmable
-	  32-bit free running decrementing counters.
-
-config NOMADIK_MTU_SCHED_CLOCK
-	bool
-	depends on HAS_MTU
-	help
-	  Use the Multi Timer Unit as the sched_clock.
-
-endif
diff --git a/arch/arm/plat-nomadik/Makefile b/arch/arm/plat-nomadik/Makefile
deleted file mode 100644
index 37c7cdd..0000000
--- a/arch/arm/plat-nomadik/Makefile
+++ /dev/null
@@ -1,5 +0,0 @@
-# arch/arm/plat-nomadik/Makefile
-# Copyright 2009 ST-Ericsson
-# Licensed under GPLv2
-
-obj-$(CONFIG_HAS_MTU)	+= timer.o
diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c
index c288b76..37a488a 100644
--- a/arch/arm/plat-omap/dma.c
+++ b/arch/arm/plat-omap/dma.c
@@ -36,7 +36,7 @@
 #include <linux/slab.h>
 #include <linux/delay.h>
 
-#include <plat-omap/dma-omap.h>
+#include <linux/omap-dma.h>
 
 /*
  * MAX_LOGICAL_DMA_CH_COUNT: the maximum number of logical DMA
diff --git a/arch/arm/plat-omap/include/plat-omap/dma-omap.h b/arch/arm/plat-omap/include/plat-omap/dma-omap.h
deleted file mode 100644
index 6f506ba..0000000
--- a/arch/arm/plat-omap/include/plat-omap/dma-omap.h
+++ /dev/null
@@ -1,377 +0,0 @@
-/*
- *  OMAP DMA handling defines and function
- *
- *  Copyright (C) 2003 Nokia Corporation
- *  Author: Juha Yrjölä <juha.yrjola@nokia.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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-#ifndef __ASM_ARCH_DMA_H
-#define __ASM_ARCH_DMA_H
-
-#include <linux/platform_device.h>
-
-#define INT_DMA_LCD			25
-
-#define OMAP1_DMA_TOUT_IRQ		(1 << 0)
-#define OMAP_DMA_DROP_IRQ		(1 << 1)
-#define OMAP_DMA_HALF_IRQ		(1 << 2)
-#define OMAP_DMA_FRAME_IRQ		(1 << 3)
-#define OMAP_DMA_LAST_IRQ		(1 << 4)
-#define OMAP_DMA_BLOCK_IRQ		(1 << 5)
-#define OMAP1_DMA_SYNC_IRQ		(1 << 6)
-#define OMAP2_DMA_PKT_IRQ		(1 << 7)
-#define OMAP2_DMA_TRANS_ERR_IRQ		(1 << 8)
-#define OMAP2_DMA_SECURE_ERR_IRQ	(1 << 9)
-#define OMAP2_DMA_SUPERVISOR_ERR_IRQ	(1 << 10)
-#define OMAP2_DMA_MISALIGNED_ERR_IRQ	(1 << 11)
-
-#define OMAP_DMA_CCR_EN			(1 << 7)
-#define OMAP_DMA_CCR_RD_ACTIVE		(1 << 9)
-#define OMAP_DMA_CCR_WR_ACTIVE		(1 << 10)
-#define OMAP_DMA_CCR_SEL_SRC_DST_SYNC	(1 << 24)
-#define OMAP_DMA_CCR_BUFFERING_DISABLE	(1 << 25)
-
-#define OMAP_DMA_DATA_TYPE_S8		0x00
-#define OMAP_DMA_DATA_TYPE_S16		0x01
-#define OMAP_DMA_DATA_TYPE_S32		0x02
-
-#define OMAP_DMA_SYNC_ELEMENT		0x00
-#define OMAP_DMA_SYNC_FRAME		0x01
-#define OMAP_DMA_SYNC_BLOCK		0x02
-#define OMAP_DMA_SYNC_PACKET		0x03
-
-#define OMAP_DMA_DST_SYNC_PREFETCH	0x02
-#define OMAP_DMA_SRC_SYNC		0x01
-#define OMAP_DMA_DST_SYNC		0x00
-
-#define OMAP_DMA_PORT_EMIFF		0x00
-#define OMAP_DMA_PORT_EMIFS		0x01
-#define OMAP_DMA_PORT_OCP_T1		0x02
-#define OMAP_DMA_PORT_TIPB		0x03
-#define OMAP_DMA_PORT_OCP_T2		0x04
-#define OMAP_DMA_PORT_MPUI		0x05
-
-#define OMAP_DMA_AMODE_CONSTANT		0x00
-#define OMAP_DMA_AMODE_POST_INC		0x01
-#define OMAP_DMA_AMODE_SINGLE_IDX	0x02
-#define OMAP_DMA_AMODE_DOUBLE_IDX	0x03
-
-#define DMA_DEFAULT_FIFO_DEPTH		0x10
-#define DMA_DEFAULT_ARB_RATE		0x01
-/* Pass THREAD_RESERVE ORed with THREAD_FIFO for tparams */
-#define DMA_THREAD_RESERVE_NORM		(0x00 << 12) /* Def */
-#define DMA_THREAD_RESERVE_ONET		(0x01 << 12)
-#define DMA_THREAD_RESERVE_TWOT		(0x02 << 12)
-#define DMA_THREAD_RESERVE_THREET	(0x03 << 12)
-#define DMA_THREAD_FIFO_NONE		(0x00 << 14) /* Def */
-#define DMA_THREAD_FIFO_75		(0x01 << 14)
-#define DMA_THREAD_FIFO_25		(0x02 << 14)
-#define DMA_THREAD_FIFO_50		(0x03 << 14)
-
-/* DMA4_OCP_SYSCONFIG bits */
-#define DMA_SYSCONFIG_MIDLEMODE_MASK		(3 << 12)
-#define DMA_SYSCONFIG_CLOCKACTIVITY_MASK	(3 << 8)
-#define DMA_SYSCONFIG_EMUFREE			(1 << 5)
-#define DMA_SYSCONFIG_SIDLEMODE_MASK		(3 << 3)
-#define DMA_SYSCONFIG_SOFTRESET			(1 << 2)
-#define DMA_SYSCONFIG_AUTOIDLE			(1 << 0)
-
-#define DMA_SYSCONFIG_MIDLEMODE(n)		((n) << 12)
-#define DMA_SYSCONFIG_SIDLEMODE(n)		((n) << 3)
-
-#define DMA_IDLEMODE_SMARTIDLE			0x2
-#define DMA_IDLEMODE_NO_IDLE			0x1
-#define DMA_IDLEMODE_FORCE_IDLE			0x0
-
-/* Chaining modes*/
-#ifndef CONFIG_ARCH_OMAP1
-#define OMAP_DMA_STATIC_CHAIN		0x1
-#define OMAP_DMA_DYNAMIC_CHAIN		0x2
-#define OMAP_DMA_CHAIN_ACTIVE		0x1
-#define OMAP_DMA_CHAIN_INACTIVE		0x0
-#endif
-
-#define DMA_CH_PRIO_HIGH		0x1
-#define DMA_CH_PRIO_LOW			0x0 /* Def */
-
-/* Errata handling */
-#define IS_DMA_ERRATA(id)		(errata & (id))
-#define SET_DMA_ERRATA(id)		(errata |= (id))
-
-#define DMA_ERRATA_IFRAME_BUFFERING	BIT(0x0)
-#define DMA_ERRATA_PARALLEL_CHANNELS	BIT(0x1)
-#define DMA_ERRATA_i378			BIT(0x2)
-#define DMA_ERRATA_i541			BIT(0x3)
-#define DMA_ERRATA_i88			BIT(0x4)
-#define DMA_ERRATA_3_3			BIT(0x5)
-#define DMA_ROMCODE_BUG			BIT(0x6)
-
-/* Attributes for OMAP DMA Contrller */
-#define DMA_LINKED_LCH			BIT(0x0)
-#define GLOBAL_PRIORITY			BIT(0x1)
-#define RESERVE_CHANNEL			BIT(0x2)
-#define IS_CSSA_32			BIT(0x3)
-#define IS_CDSA_32			BIT(0x4)
-#define IS_RW_PRIORITY			BIT(0x5)
-#define ENABLE_1510_MODE		BIT(0x6)
-#define SRC_PORT			BIT(0x7)
-#define DST_PORT			BIT(0x8)
-#define SRC_INDEX			BIT(0x9)
-#define DST_INDEX			BIT(0xa)
-#define IS_BURST_ONLY4			BIT(0xb)
-#define CLEAR_CSR_ON_READ		BIT(0xc)
-#define IS_WORD_16			BIT(0xd)
-#define ENABLE_16XX_MODE		BIT(0xe)
-#define HS_CHANNELS_RESERVED		BIT(0xf)
-
-/* Defines for DMA Capabilities */
-#define DMA_HAS_TRANSPARENT_CAPS	(0x1 << 18)
-#define DMA_HAS_CONSTANT_FILL_CAPS	(0x1 << 19)
-#define DMA_HAS_DESCRIPTOR_CAPS		(0x3 << 20)
-
-enum omap_reg_offsets {
-
-GCR,		GSCR,		GRST1,		HW_ID,
-PCH2_ID,	PCH0_ID,	PCH1_ID,	PCHG_ID,
-PCHD_ID,	CAPS_0,		CAPS_1,		CAPS_2,
-CAPS_3,		CAPS_4,		PCH2_SR,	PCH0_SR,
-PCH1_SR,	PCHD_SR,	REVISION,	IRQSTATUS_L0,
-IRQSTATUS_L1,	IRQSTATUS_L2,	IRQSTATUS_L3,	IRQENABLE_L0,
-IRQENABLE_L1,	IRQENABLE_L2,	IRQENABLE_L3,	SYSSTATUS,
-OCP_SYSCONFIG,
-
-/* omap1+ specific */
-CPC, CCR2, LCH_CTRL,
-
-/* Common registers for all omap's */
-CSDP,		CCR,		CICR,		CSR,
-CEN,		CFN,		CSFI,		CSEI,
-CSAC,		CDAC,		CDEI,
-CDFI,		CLNK_CTRL,
-
-/* Channel specific registers */
-CSSA,		CDSA,		COLOR,
-CCEN,		CCFN,
-
-/* omap3630 and omap4 specific */
-CDP,		CNDP,		CCDN,
-
-};
-
-enum omap_dma_burst_mode {
-	OMAP_DMA_DATA_BURST_DIS = 0,
-	OMAP_DMA_DATA_BURST_4,
-	OMAP_DMA_DATA_BURST_8,
-	OMAP_DMA_DATA_BURST_16,
-};
-
-enum end_type {
-	OMAP_DMA_LITTLE_ENDIAN = 0,
-	OMAP_DMA_BIG_ENDIAN
-};
-
-enum omap_dma_color_mode {
-	OMAP_DMA_COLOR_DIS = 0,
-	OMAP_DMA_CONSTANT_FILL,
-	OMAP_DMA_TRANSPARENT_COPY
-};
-
-enum omap_dma_write_mode {
-	OMAP_DMA_WRITE_NON_POSTED = 0,
-	OMAP_DMA_WRITE_POSTED,
-	OMAP_DMA_WRITE_LAST_NON_POSTED
-};
-
-enum omap_dma_channel_mode {
-	OMAP_DMA_LCH_2D = 0,
-	OMAP_DMA_LCH_G,
-	OMAP_DMA_LCH_P,
-	OMAP_DMA_LCH_PD
-};
-
-struct omap_dma_channel_params {
-	int data_type;		/* data type 8,16,32 */
-	int elem_count;		/* number of elements in a frame */
-	int frame_count;	/* number of frames in a element */
-
-	int src_port;		/* Only on OMAP1 REVISIT: Is this needed? */
-	int src_amode;		/* constant, post increment, indexed,
-					double indexed */
-	unsigned long src_start;	/* source address : physical */
-	int src_ei;		/* source element index */
-	int src_fi;		/* source frame index */
-
-	int dst_port;		/* Only on OMAP1 REVISIT: Is this needed? */
-	int dst_amode;		/* constant, post increment, indexed,
-					double indexed */
-	unsigned long dst_start;	/* source address : physical */
-	int dst_ei;		/* source element index */
-	int dst_fi;		/* source frame index */
-
-	int trigger;		/* trigger attached if the channel is
-					synchronized */
-	int sync_mode;		/* sycn on element, frame , block or packet */
-	int src_or_dst_synch;	/* source synch(1) or destination synch(0) */
-
-	int ie;			/* interrupt enabled */
-
-	unsigned char read_prio;/* read priority */
-	unsigned char write_prio;/* write priority */
-
-#ifndef CONFIG_ARCH_OMAP1
-	enum omap_dma_burst_mode burst_mode; /* Burst mode 4/8/16 words */
-#endif
-};
-
-struct omap_dma_lch {
-	int next_lch;
-	int dev_id;
-	u16 saved_csr;
-	u16 enabled_irqs;
-	const char *dev_name;
-	void (*callback)(int lch, u16 ch_status, void *data);
-	void *data;
-	long flags;
-	/* required for Dynamic chaining */
-	int prev_linked_ch;
-	int next_linked_ch;
-	int state;
-	int chain_id;
-	int status;
-};
-
-struct omap_dma_dev_attr {
-	u32 dev_caps;
-	u16 lch_count;
-	u16 chan_count;
-	struct omap_dma_lch *chan;
-};
-
-/* System DMA platform data structure */
-struct omap_system_dma_plat_info {
-	struct omap_dma_dev_attr *dma_attr;
-	u32 errata;
-	void (*disable_irq_lch)(int lch);
-	void (*show_dma_caps)(void);
-	void (*clear_lch_regs)(int lch);
-	void (*clear_dma)(int lch);
-	void (*dma_write)(u32 val, int reg, int lch);
-	u32 (*dma_read)(int reg, int lch);
-};
-
-#ifdef CONFIG_ARCH_OMAP2PLUS
-#define dma_omap2plus()	1
-#else
-#define dma_omap2plus()	0
-#endif
-#define dma_omap1()	(!dma_omap2plus())
-#define dma_omap15xx()	((dma_omap1() && (d->dev_caps & ENABLE_1510_MODE)))
-#define dma_omap16xx()	((dma_omap1() && (d->dev_caps & ENABLE_16XX_MODE)))
-
-extern void omap_set_dma_priority(int lch, int dst_port, int priority);
-extern int omap_request_dma(int dev_id, const char *dev_name,
-			void (*callback)(int lch, u16 ch_status, void *data),
-			void *data, int *dma_ch);
-extern void omap_enable_dma_irq(int ch, u16 irq_bits);
-extern void omap_disable_dma_irq(int ch, u16 irq_bits);
-extern void omap_free_dma(int ch);
-extern void omap_start_dma(int lch);
-extern void omap_stop_dma(int lch);
-extern void omap_set_dma_transfer_params(int lch, int data_type,
-					 int elem_count, int frame_count,
-					 int sync_mode,
-					 int dma_trigger, int src_or_dst_synch);
-extern void omap_set_dma_color_mode(int lch, enum omap_dma_color_mode mode,
-				    u32 color);
-extern void omap_set_dma_write_mode(int lch, enum omap_dma_write_mode mode);
-extern void omap_set_dma_channel_mode(int lch, enum omap_dma_channel_mode mode);
-
-extern void omap_set_dma_src_params(int lch, int src_port, int src_amode,
-				    unsigned long src_start,
-				    int src_ei, int src_fi);
-extern void omap_set_dma_src_index(int lch, int eidx, int fidx);
-extern void omap_set_dma_src_data_pack(int lch, int enable);
-extern void omap_set_dma_src_burst_mode(int lch,
-					enum omap_dma_burst_mode burst_mode);
-
-extern void omap_set_dma_dest_params(int lch, int dest_port, int dest_amode,
-				     unsigned long dest_start,
-				     int dst_ei, int dst_fi);
-extern void omap_set_dma_dest_index(int lch, int eidx, int fidx);
-extern void omap_set_dma_dest_data_pack(int lch, int enable);
-extern void omap_set_dma_dest_burst_mode(int lch,
-					 enum omap_dma_burst_mode burst_mode);
-
-extern void omap_set_dma_params(int lch,
-				struct omap_dma_channel_params *params);
-
-extern void omap_dma_link_lch(int lch_head, int lch_queue);
-extern void omap_dma_unlink_lch(int lch_head, int lch_queue);
-
-extern int omap_set_dma_callback(int lch,
-			void (*callback)(int lch, u16 ch_status, void *data),
-			void *data);
-extern dma_addr_t omap_get_dma_src_pos(int lch);
-extern dma_addr_t omap_get_dma_dst_pos(int lch);
-extern void omap_clear_dma(int lch);
-extern int omap_get_dma_active_status(int lch);
-extern int omap_dma_running(void);
-extern void omap_dma_set_global_params(int arb_rate, int max_fifo_depth,
-				       int tparams);
-extern int omap_dma_set_prio_lch(int lch, unsigned char read_prio,
-				 unsigned char write_prio);
-extern void omap_set_dma_dst_endian_type(int lch, enum end_type etype);
-extern void omap_set_dma_src_endian_type(int lch, enum end_type etype);
-extern int omap_get_dma_index(int lch, int *ei, int *fi);
-
-void omap_dma_global_context_save(void);
-void omap_dma_global_context_restore(void);
-
-extern void omap_dma_disable_irq(int lch);
-
-/* Chaining APIs */
-#ifndef CONFIG_ARCH_OMAP1
-extern int omap_request_dma_chain(int dev_id, const char *dev_name,
-				  void (*callback) (int lch, u16 ch_status,
-						    void *data),
-				  int *chain_id, int no_of_chans,
-				  int chain_mode,
-				  struct omap_dma_channel_params params);
-extern int omap_free_dma_chain(int chain_id);
-extern int omap_dma_chain_a_transfer(int chain_id, int src_start,
-				     int dest_start, int elem_count,
-				     int frame_count, void *callbk_data);
-extern int omap_start_dma_chain_transfers(int chain_id);
-extern int omap_stop_dma_chain_transfers(int chain_id);
-extern int omap_get_dma_chain_index(int chain_id, int *ei, int *fi);
-extern int omap_get_dma_chain_dst_pos(int chain_id);
-extern int omap_get_dma_chain_src_pos(int chain_id);
-
-extern int omap_modify_dma_chain_params(int chain_id,
-					struct omap_dma_channel_params params);
-extern int omap_dma_chain_status(int chain_id);
-#endif
-
-#if defined(CONFIG_ARCH_OMAP1) && defined(CONFIG_FB_OMAP)
-#include <mach/lcd_dma.h>
-#else
-static inline int omap_lcd_dma_running(void)
-{
-	return 0;
-}
-#endif
-
-#endif /* __ASM_ARCH_DMA_H */
diff --git a/arch/arm/plat-orion/irq.c b/arch/arm/plat-orion/irq.c
index 1867944..8db0b98 100644
--- a/arch/arm/plat-orion/irq.c
+++ b/arch/arm/plat-orion/irq.c
@@ -41,7 +41,7 @@
 static int __init orion_add_irq_domain(struct device_node *np,
 				       struct device_node *interrupt_parent)
 {
-	int i = 0, irq_gpio;
+	int i = 0;
 	void __iomem *base;
 
 	do {
@@ -54,10 +54,6 @@
 
 	irq_domain_add_legacy(np, i * 32, 0, 0,
 			      &irq_domain_simple_ops, NULL);
-
-	irq_gpio = i * 32;
-	orion_gpio_of_init(irq_gpio);
-
 	return 0;
 }
 
diff --git a/arch/arm/plat-s3c24xx/dma.c b/arch/arm/plat-s3c24xx/dma.c
index 0abd1c4..ba3e76c 100644
--- a/arch/arm/plat-s3c24xx/dma.c
+++ b/arch/arm/plat-s3c24xx/dma.c
@@ -325,7 +325,7 @@
 
 	chan->state = S3C2410_DMA_RUNNING;
 
-	/* check wether there is anything to load, and if not, see
+	/* check whether there is anything to load, and if not, see
 	 * if we can find anything to load
 	 */
 
diff --git a/arch/arm/plat-samsung/devs.c b/arch/arm/plat-samsung/devs.c
index a17d7b3..51afedd 100644
--- a/arch/arm/plat-samsung/devs.c
+++ b/arch/arm/plat-samsung/devs.c
@@ -146,15 +146,6 @@
 
 /* ASOC DMA */
 
-struct platform_device samsung_asoc_dma = {
-	.name		= "samsung-audio",
-	.id		= -1,
-	.dev		= {
-		.dma_mask		= &samsung_device_dma_mask,
-		.coherent_dma_mask	= DMA_BIT_MASK(32),
-	}
-};
-
 struct platform_device samsung_asoc_idma = {
 	.name		= "samsung-idma",
 	.id		= -1,
@@ -929,6 +920,7 @@
 		.coherent_dma_mask	= DMA_BIT_MASK(32),
 	},
 };
+
 #endif /* CONFIG_S5P_DEV_MFC */
 
 /* MIPI CSIS */
diff --git a/arch/arm/plat-samsung/include/plat/devs.h b/arch/arm/plat-samsung/include/plat/devs.h
index a9b8096..87d501f 100644
--- a/arch/arm/plat-samsung/include/plat/devs.h
+++ b/arch/arm/plat-samsung/include/plat/devs.h
@@ -132,9 +132,6 @@
 extern struct platform_device exynos4_device_pcm2;
 extern struct platform_device exynos4_device_spdif;
 
-extern struct platform_device exynos_device_drm;
-
-extern struct platform_device samsung_asoc_dma;
 extern struct platform_device samsung_asoc_idma;
 extern struct platform_device samsung_device_keypad;
 
diff --git a/arch/arm/plat-samsung/include/plat/gpio-core.h b/arch/arm/plat-samsung/include/plat/gpio-core.h
index 1fe6917..dfd8b7a 100644
--- a/arch/arm/plat-samsung/include/plat/gpio-core.h
+++ b/arch/arm/plat-samsung/include/plat/gpio-core.h
@@ -48,6 +48,7 @@
  * @config: special function and pull-resistor control information.
  * @lock: Lock for exclusive access to this gpio bank.
  * @pm_save: Save information for suspend/resume support.
+ * @bitmap_gpio_int: Bitmap for representing GPIO interrupt or not.
  *
  * This wrapper provides the necessary information for the Samsung
  * specific gpios being registered with gpiolib.
@@ -71,6 +72,7 @@
 #ifdef CONFIG_PM
 	u32			pm_save[4];
 #endif
+	u32			bitmap_gpio_int;
 };
 
 static inline struct samsung_gpio_chip *to_samsung_gpio(struct gpio_chip *gpc)
diff --git a/arch/arm/plat-samsung/include/plat/mfc.h b/arch/arm/plat-samsung/include/plat/mfc.h
index ac13227..e6d7c42 100644
--- a/arch/arm/plat-samsung/include/plat/mfc.h
+++ b/arch/arm/plat-samsung/include/plat/mfc.h
@@ -10,6 +10,14 @@
 #ifndef __PLAT_SAMSUNG_MFC_H
 #define __PLAT_SAMSUNG_MFC_H __FILE__
 
+struct s5p_mfc_dt_meminfo {
+	unsigned long	loff;
+	unsigned long	lsize;
+	unsigned long	roff;
+	unsigned long	rsize;
+	char		*compatible;
+};
+
 /**
  * s5p_mfc_reserve_mem - function to early reserve memory for MFC driver
  * @rbase:	base address for MFC 'right' memory interface
@@ -24,4 +32,7 @@
 void __init s5p_mfc_reserve_mem(phys_addr_t rbase, unsigned int rsize,
 				phys_addr_t lbase, unsigned int lsize);
 
+int __init s5p_fdt_find_mfc_mem(unsigned long node, const char *uname,
+				int depth, void *data);
+
 #endif /* __PLAT_SAMSUNG_MFC_H */
diff --git a/arch/arm/plat-samsung/include/plat/pm.h b/arch/arm/plat-samsung/include/plat/pm.h
index 61fc537..887a0c9 100644
--- a/arch/arm/plat-samsung/include/plat/pm.h
+++ b/arch/arm/plat-samsung/include/plat/pm.h
@@ -107,10 +107,12 @@
 extern void s3c_pm_do_restore_core(struct sleep_save *ptr, int count);
 
 #ifdef CONFIG_PM
+extern int s3c_irq_wake(struct irq_data *data, unsigned int state);
 extern int s3c_irqext_wake(struct irq_data *data, unsigned int state);
 extern int s3c24xx_irq_suspend(void);
 extern void s3c24xx_irq_resume(void);
 #else
+#define s3c_irq_wake NULL
 #define s3c_irqext_wake NULL
 #define s3c24xx_irq_suspend NULL
 #define s3c24xx_irq_resume  NULL
diff --git a/arch/arm/plat-samsung/s5p-dev-mfc.c b/arch/arm/plat-samsung/s5p-dev-mfc.c
index ad60894..5ec104b 100644
--- a/arch/arm/plat-samsung/s5p-dev-mfc.c
+++ b/arch/arm/plat-samsung/s5p-dev-mfc.c
@@ -14,6 +14,8 @@
 #include <linux/dma-mapping.h>
 #include <linux/memblock.h>
 #include <linux/ioport.h>
+#include <linux/of_fdt.h>
+#include <linux/of.h>
 
 #include <mach/map.h>
 #include <plat/devs.h>
@@ -69,3 +71,35 @@
 	return 0;
 }
 device_initcall(s5p_mfc_memory_init);
+
+#ifdef CONFIG_OF
+int __init s5p_fdt_find_mfc_mem(unsigned long node, const char *uname,
+				int depth, void *data)
+{
+	__be32 *prop;
+	unsigned long len;
+	struct s5p_mfc_dt_meminfo *mfc_mem = data;
+
+	if (!data)
+		return 0;
+
+	if (!of_flat_dt_is_compatible(node, mfc_mem->compatible))
+		return 0;
+
+	prop = of_get_flat_dt_prop(node, "samsung,mfc-l", &len);
+	if (!prop || (len != 2 * sizeof(unsigned long)))
+		return 0;
+
+	mfc_mem->loff = be32_to_cpu(prop[0]);
+	mfc_mem->lsize = be32_to_cpu(prop[1]);
+
+	prop = of_get_flat_dt_prop(node, "samsung,mfc-r", &len);
+	if (!prop || (len != 2 * sizeof(unsigned long)))
+		return 0;
+
+	mfc_mem->roff = be32_to_cpu(prop[0]);
+	mfc_mem->rsize = be32_to_cpu(prop[1]);
+
+	return 1;
+}
+#endif
diff --git a/arch/arm/plat-samsung/s5p-irq-gpioint.c b/arch/arm/plat-samsung/s5p-irq-gpioint.c
index 23557d3..bae5613 100644
--- a/arch/arm/plat-samsung/s5p-irq-gpioint.c
+++ b/arch/arm/plat-samsung/s5p-irq-gpioint.c
@@ -185,7 +185,7 @@
 
 	/* check if the group has been already registered */
 	if (my_chip->irq_base)
-		return my_chip->irq_base + offset;
+		goto success;
 
 	/* register gpio group */
 	ret = s5p_gpioint_add(my_chip);
@@ -193,9 +193,13 @@
 		my_chip->chip.to_irq = samsung_gpiolib_to_irq;
 		printk(KERN_INFO "Registered interrupt support for gpio group %d.\n",
 		       group);
-		return my_chip->irq_base + offset;
+		goto success;
 	}
 	return ret;
+success:
+	my_chip->bitmap_gpio_int |= BIT(offset);
+
+	return my_chip->irq_base + offset;
 }
 
 int __init s5p_register_gpioint_bank(int chain_irq, int start, int nr_groups)
diff --git a/arch/blackfin/mach-bf609/Kconfig b/arch/blackfin/mach-bf609/Kconfig
index 101b33e..95a4f1b 100644
--- a/arch/blackfin/mach-bf609/Kconfig
+++ b/arch/blackfin/mach-bf609/Kconfig
@@ -56,7 +56,7 @@
 	default 7
 	range 0 7
 	help
-	  Devide the total number of interrupt priority levels into sub-levels.
+	  Divide the total number of interrupt priority levels into sub-levels.
 	  There is 2 ^ (SEC_IRQ_PRIORITY_LEVELS + 1) different levels.
 
 endmenu
diff --git a/arch/blackfin/mm/sram-alloc.c b/arch/blackfin/mm/sram-alloc.c
index 342e378..1f3b3ef 100644
--- a/arch/blackfin/mm/sram-alloc.c
+++ b/arch/blackfin/mm/sram-alloc.c
@@ -191,7 +191,7 @@
 {
 	int status;
 
-	printk(KERN_ERR "L2 ecc error happend\n");
+	printk(KERN_ERR "L2 ecc error happened\n");
 	status = bfin_read32(L2CTL0_STAT);
 	if (status & 0x1)
 		printk(KERN_ERR "Core channel error type:0x%x, addr:0x%x\n",
diff --git a/arch/cris/include/arch-v10/arch/irq.h b/arch/cris/include/arch-v10/arch/irq.h
index 7d34594..ca2675a 100644
--- a/arch/cris/include/arch-v10/arch/irq.h
+++ b/arch/cris/include/arch-v10/arch/irq.h
@@ -142,7 +142,7 @@
  * it here, we would not get the multiple_irq at all.
  *
  * The non-blocking here is based on the knowledge that the timer interrupt is 
- * registred as a fast interrupt (IRQF_DISABLED) so that we _know_ there will not
+ * registered as a fast interrupt (IRQF_DISABLED) so that we _know_ there will not
  * be an sti() before the timer irq handler is run to acknowledge the interrupt.
  */
 
diff --git a/arch/cris/include/arch-v32/arch/irq.h b/arch/cris/include/arch-v32/arch/irq.h
index b31e998..fe3cdd2 100644
--- a/arch/cris/include/arch-v32/arch/irq.h
+++ b/arch/cris/include/arch-v32/arch/irq.h
@@ -103,7 +103,7 @@
  * if we had BLOCK'edit here, we would not get the multiple_irq at all.
  *
  * The non-blocking here is based on the knowledge that the timer interrupt is
- * registred as a fast interrupt (IRQF_DISABLED) so that we _know_ there will not
+ * registered as a fast interrupt (IRQF_DISABLED) so that we _know_ there will not
  * be an sti() before the timer irq handler is run to acknowledge the interrupt.
  */
 #define BUILD_TIMER_IRQ(nr, mask) 	\
diff --git a/arch/frv/mm/pgalloc.c b/arch/frv/mm/pgalloc.c
index 4fb63a3..f6084bc 100644
--- a/arch/frv/mm/pgalloc.c
+++ b/arch/frv/mm/pgalloc.c
@@ -77,7 +77,7 @@
  * checks at dup_mmap(), exec(), and other mmlist addition points
  * could be used. The locking scheme was chosen on the basis of
  * manfred's recommendations and having no core impact whatsoever.
- * -- wli
+ * -- nyc
  */
 DEFINE_SPINLOCK(pgd_lock);
 struct page *pgd_list;
diff --git a/arch/ia64/kvm/kvm-ia64.c b/arch/ia64/kvm/kvm-ia64.c
index 8b3a9c0..0a88cb5 100644
--- a/arch/ia64/kvm/kvm-ia64.c
+++ b/arch/ia64/kvm/kvm-ia64.c
@@ -1,5 +1,5 @@
 /*
- * kvm_ia64.c: Basic KVM suppport On Itanium series processors
+ * kvm_ia64.c: Basic KVM support On Itanium series processors
  *
  *
  * 	Copyright (C) 2007, Intel Corporation.
diff --git a/arch/m68k/math-emu/fp_log.c b/arch/m68k/math-emu/fp_log.c
index 3384a52..0663067 100644
--- a/arch/m68k/math-emu/fp_log.c
+++ b/arch/m68k/math-emu/fp_log.c
@@ -50,7 +50,7 @@
 	 * sqrt(m*2^e) =
 	 *		 sqrt(2*m) * 2^(p)	, if e = 2*p + 1
 	 *
-	 * So we use the last bit of the exponent to decide wether to
+	 * So we use the last bit of the exponent to decide whether to
 	 * use the m or 2*m.
 	 *
 	 * Since only the fractional part of the mantissa is stored and
diff --git a/arch/mips/include/asm/pgtable.h b/arch/mips/include/asm/pgtable.h
index c02158b..14490e9 100644
--- a/arch/mips/include/asm/pgtable.h
+++ b/arch/mips/include/asm/pgtable.h
@@ -76,16 +76,7 @@
 
 #define ZERO_PAGE(vaddr) \
 	(virt_to_page((void *)(empty_zero_page + (((unsigned long)(vaddr)) & zero_page_mask))))
-
-#define is_zero_pfn is_zero_pfn
-static inline int is_zero_pfn(unsigned long pfn)
-{
-	extern unsigned long zero_pfn;
-	unsigned long offset_from_zero_pfn = pfn - zero_pfn;
-	return offset_from_zero_pfn <= (zero_page_mask >> PAGE_SHIFT);
-}
-
-#define my_zero_pfn(addr)	page_to_pfn(ZERO_PAGE(addr))
+#define __HAVE_COLOR_ZERO_PAGE
 
 extern void paging_init(void);
 
diff --git a/arch/mips/txx9/generic/pci.c b/arch/mips/txx9/generic/pci.c
index 4efd918..b14ee53 100644
--- a/arch/mips/txx9/generic/pci.c
+++ b/arch/mips/txx9/generic/pci.c
@@ -341,7 +341,7 @@
 
 static void __devinit tc35815_fixup(struct pci_dev *dev)
 {
-	/* This device may have PM registers but not they are not suported. */
+	/* This device may have PM registers but not they are not supported. */
 	if (dev->pm_cap) {
 		dev_info(&dev->dev, "PM disabled\n");
 		dev->pm_cap = 0;
diff --git a/arch/mn10300/mm/pgtable.c b/arch/mn10300/mm/pgtable.c
index 4ebf117..bd9ada6 100644
--- a/arch/mn10300/mm/pgtable.c
+++ b/arch/mn10300/mm/pgtable.c
@@ -95,7 +95,7 @@
  * checks at dup_mmap(), exec(), and other mmlist addition points
  * could be used. The locking scheme was chosen on the basis of
  * manfred's recommendations and having no core impact whatsoever.
- * -- wli
+ * -- nyc
  */
 DEFINE_SPINLOCK(pgd_lock);
 struct page *pgd_list;
diff --git a/arch/openrisc/Kconfig b/arch/openrisc/Kconfig
index e7f1a29..ec37e18 100644
--- a/arch/openrisc/Kconfig
+++ b/arch/openrisc/Kconfig
@@ -146,7 +146,7 @@
 	help
 	  Make extra checks for space available on stack in some
           critical functions. This will cause kernel to run a bit slower,
-	  but will catch most of kernel stack overruns and exit gracefuly.
+	  but will catch most of kernel stack overruns and exit gracefully.
 
 	  Say Y if you are unsure.
 
diff --git a/arch/powerpc/include/asm/oprofile_impl.h b/arch/powerpc/include/asm/oprofile_impl.h
index 639dc96..d697b08 100644
--- a/arch/powerpc/include/asm/oprofile_impl.h
+++ b/arch/powerpc/include/asm/oprofile_impl.h
@@ -34,7 +34,7 @@
 	unsigned long mmcra;
 #ifdef CONFIG_OPROFILE_CELL
 	/* Register for oprofile user tool to check cell kernel profiling
-	 * suport.
+	 * support.
 	 */
 	unsigned long cell_support;
 #endif
diff --git a/arch/powerpc/include/asm/pte-hash64-64k.h b/arch/powerpc/include/asm/pte-hash64-64k.h
index eedf427c9..3e13e23 100644
--- a/arch/powerpc/include/asm/pte-hash64-64k.h
+++ b/arch/powerpc/include/asm/pte-hash64-64k.h
@@ -23,7 +23,7 @@
 
 /* Note the full page bits must be in the same location as for normal
  * 4k pages as the same assembly will be used to insert 64K pages
- * wether the kernel has CONFIG_PPC_64K_PAGES or not
+ * whether the kernel has CONFIG_PPC_64K_PAGES or not
  */
 #define _PAGE_F_SECOND  0x00008000 /* full page: hidx bits */
 #define _PAGE_F_GIX     0x00007000 /* full page: hidx bits */
diff --git a/arch/powerpc/include/asm/smu.h b/arch/powerpc/include/asm/smu.h
index ae20ce1a..6e909f3 100644
--- a/arch/powerpc/include/asm/smu.h
+++ b/arch/powerpc/include/asm/smu.h
@@ -132,7 +132,7 @@
   *
   * At this point, the OF driver seems to have a limitation on transfer
   * sizes of 0xd bytes on reads and 0x5 bytes on writes. I do not know
-  * wether this is just an OF limit due to some temporary buffer size
+  * whether this is just an OF limit due to some temporary buffer size
   * or if this is an SMU imposed limit. This driver has the same limitation
   * for now as I use a 0x10 bytes temporary buffer as well
   *
@@ -236,7 +236,7 @@
  *   3 (optional): enable nmi? [0x00 or 0x01]
  *
  * Returns:
- *   If parameter 2 is 0x00 and parameter 3 is not specified, returns wether
+ *   If parameter 2 is 0x00 and parameter 3 is not specified, returns whether
  *   NMI is enabled. Otherwise unknown.
  */
 #define   SMU_CMD_MISC_df_NMI_OPTION		0x04
diff --git a/arch/powerpc/kernel/legacy_serial.c b/arch/powerpc/kernel/legacy_serial.c
index bedd12e..0733b05 100644
--- a/arch/powerpc/kernel/legacy_serial.c
+++ b/arch/powerpc/kernel/legacy_serial.c
@@ -387,7 +387,7 @@
 			of_node_put(parent);
 			continue;
 		}
-		/* Check for known pciclass, and also check wether we have
+		/* Check for known pciclass, and also check whether we have
 		 * a device with child nodes for ports or not
 		 */
 		if (of_device_is_compatible(np, "pciclass,0700") ||
diff --git a/arch/powerpc/kernel/of_platform.c b/arch/powerpc/kernel/of_platform.c
index 2049f2d0..9db8ec0 100644
--- a/arch/powerpc/kernel/of_platform.c
+++ b/arch/powerpc/kernel/of_platform.c
@@ -82,7 +82,7 @@
 		return -ENXIO;
 
 	/* Claim resources. This might need some rework as well depending
-	 * wether we are doing probe-only or not, like assigning unassigned
+	 * whether we are doing probe-only or not, like assigning unassigned
 	 * resources etc...
 	 */
 	pcibios_claim_one_bus(phb->bus);
diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_64.c
index d183f87..1ca045d 100644
--- a/arch/powerpc/kernel/signal_64.c
+++ b/arch/powerpc/kernel/signal_64.c
@@ -83,7 +83,7 @@
 	 * the context). This is very important because we must ensure we
 	 * don't lose the VRSAVE content that may have been set prior to
 	 * the process doing its first vector operation
-	 * Userland shall check AT_HWCAP to know wether it can rely on the
+	 * Userland shall check AT_HWCAP to know whether it can rely on the
 	 * v_regs pointer or not
 	 */
 #ifdef CONFIG_ALTIVEC
diff --git a/arch/powerpc/mm/fault.c b/arch/powerpc/mm/fault.c
index 0a6b283..3a8489a 100644
--- a/arch/powerpc/mm/fault.c
+++ b/arch/powerpc/mm/fault.c
@@ -113,19 +113,6 @@
 #define MM_FAULT_CONTINUE	-1
 #define MM_FAULT_ERR(sig)	(sig)
 
-static int out_of_memory(struct pt_regs *regs)
-{
-	/*
-	 * We ran out of memory, or some other thing happened to us that made
-	 * us unable to handle the page fault gracefully.
-	 */
-	up_read(&current->mm->mmap_sem);
-	if (!user_mode(regs))
-		return MM_FAULT_ERR(SIGKILL);
-	pagefault_out_of_memory();
-	return MM_FAULT_RETURN;
-}
-
 static int do_sigbus(struct pt_regs *regs, unsigned long address)
 {
 	siginfo_t info;
@@ -169,8 +156,18 @@
 		return MM_FAULT_CONTINUE;
 
 	/* Out of memory */
-	if (fault & VM_FAULT_OOM)
-		return out_of_memory(regs);
+	if (fault & VM_FAULT_OOM) {
+		up_read(&current->mm->mmap_sem);
+
+		/*
+		 * We ran out of memory, or some other thing happened to us that
+		 * made us unable to handle the page fault gracefully.
+		 */
+		if (!user_mode(regs))
+			return MM_FAULT_ERR(SIGKILL);
+		pagefault_out_of_memory();
+		return MM_FAULT_RETURN;
+	}
 
 	/* Bus error. x86 handles HWPOISON here, we'll add this if/when
 	 * we support the feature in HW
diff --git a/arch/powerpc/mm/slice.c b/arch/powerpc/mm/slice.c
index 5829d2a..cf9dada 100644
--- a/arch/powerpc/mm/slice.c
+++ b/arch/powerpc/mm/slice.c
@@ -722,7 +722,7 @@
 }
 
 /*
- * is_hugepage_only_range() is used by generic code to verify wether
+ * is_hugepage_only_range() is used by generic code to verify whether
  * a normal mmap mapping (non hugetlbfs) is valid on a given area.
  *
  * until the generic code provides a more generic hook and/or starts
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_gpt.c b/arch/powerpc/platforms/52xx/mpc52xx_gpt.c
index 028470b..a51cb07 100644
--- a/arch/powerpc/platforms/52xx/mpc52xx_gpt.c
+++ b/arch/powerpc/platforms/52xx/mpc52xx_gpt.c
@@ -526,7 +526,7 @@
 
 #define WDT_IDENTITY	    "mpc52xx watchdog on GPT0"
 
-/* wdt_is_active stores wether or not the /dev/watchdog device is opened */
+/* wdt_is_active stores whether or not the /dev/watchdog device is opened */
 static unsigned long wdt_is_active;
 
 /* wdt-capable gpt */
diff --git a/arch/powerpc/platforms/cell/iommu.c b/arch/powerpc/platforms/cell/iommu.c
index dca2136..e56bb65 100644
--- a/arch/powerpc/platforms/cell/iommu.c
+++ b/arch/powerpc/platforms/cell/iommu.c
@@ -728,7 +728,7 @@
 		 nid, np->full_name);
 
 	/* XXX todo: If we can have multiple windows on the same IOMMU, which
-	 * isn't the case today, we probably want here to check wether the
+	 * isn't the case today, we probably want here to check whether the
 	 * iommu for that node is already setup.
 	 * However, there might be issue with getting the size right so let's
 	 * ignore that for now. We might want to completely get rid of the
diff --git a/arch/powerpc/platforms/cell/spider-pic.c b/arch/powerpc/platforms/cell/spider-pic.c
index d8b7cc8..8e29944 100644
--- a/arch/powerpc/platforms/cell/spider-pic.c
+++ b/arch/powerpc/platforms/cell/spider-pic.c
@@ -148,7 +148,7 @@
 
 	/* Configure the source. One gross hack that was there before and
 	 * that I've kept around is the priority to the BE which I set to
-	 * be the same as the interrupt source number. I don't know wether
+	 * be the same as the interrupt source number. I don't know whether
 	 * that's supposed to make any kind of sense however, we'll have to
 	 * decide that, but for now, I'm not changing the behaviour.
 	 */
@@ -220,7 +220,7 @@
 /* For hooking up the cascace we have a problem. Our device-tree is
  * crap and we don't know on which BE iic interrupt we are hooked on at
  * least not the "standard" way. We can reconstitute it based on two
- * informations though: which BE node we are connected to and wether
+ * informations though: which BE node we are connected to and whether
  * we are connected to IOIF0 or IOIF1. Right now, we really only care
  * about the IBM cell blade and we know that its firmware gives us an
  * interrupt-map property which is pretty strange.
@@ -232,7 +232,7 @@
 	int imaplen, intsize, unit;
 	struct device_node *iic;
 
-	/* First, we check wether we have a real "interrupts" in the device
+	/* First, we check whether we have a real "interrupts" in the device
 	 * tree in case the device-tree is ever fixed
 	 */
 	struct of_irq oirq;
diff --git a/arch/powerpc/platforms/powermac/pic.c b/arch/powerpc/platforms/powermac/pic.c
index c4e6305..31036b5 100644
--- a/arch/powerpc/platforms/powermac/pic.c
+++ b/arch/powerpc/platforms/powermac/pic.c
@@ -529,7 +529,7 @@
 void __init pmac_pic_init(void)
 {
 	/* We configure the OF parsing based on our oldworld vs. newworld
-	 * platform type and wether we were booted by BootX.
+	 * platform type and whether we were booted by BootX.
 	 */
 #ifdef CONFIG_PPC32
 	if (!pmac_newworld)
diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h
index 2d3b7cb..c814e6f 100644
--- a/arch/s390/include/asm/pgtable.h
+++ b/arch/s390/include/asm/pgtable.h
@@ -55,16 +55,7 @@
 #define ZERO_PAGE(vaddr) \
 	(virt_to_page((void *)(empty_zero_page + \
 	 (((unsigned long)(vaddr)) &zero_page_mask))))
-
-#define is_zero_pfn is_zero_pfn
-static inline int is_zero_pfn(unsigned long pfn)
-{
-	extern unsigned long zero_pfn;
-	unsigned long offset_from_zero_pfn = pfn - zero_pfn;
-	return offset_from_zero_pfn <= (zero_page_mask >> PAGE_SHIFT);
-}
-
-#define my_zero_pfn(addr)	page_to_pfn(ZERO_PAGE(addr))
+#define __HAVE_COLOR_ZERO_PAGE
 
 #endif /* !__ASSEMBLY__ */
 
diff --git a/arch/sh/boards/board-espt.c b/arch/sh/boards/board-espt.c
index 6cba0a7..d71a0bc 100644
--- a/arch/sh/boards/board-espt.c
+++ b/arch/sh/boards/board-espt.c
@@ -1,5 +1,5 @@
 /*
- * Data Technology Inc. ESPT-GIGA board suport
+ * Data Technology Inc. ESPT-GIGA board support
  *
  * Copyright (C) 2008, 2009 Renesas Solutions Corp.
  * Copyright (C) 2008, 2009 Nobuhiro Iwamatsu <iwamatsu.nobuhiro@renesas.com>
diff --git a/arch/sh/mm/fault.c b/arch/sh/mm/fault.c
index cbbdcad..1f49c28a 100644
--- a/arch/sh/mm/fault.c
+++ b/arch/sh/mm/fault.c
@@ -301,17 +301,6 @@
 	__bad_area(regs, error_code, address, SEGV_ACCERR);
 }
 
-static void out_of_memory(void)
-{
-	/*
-	 * We ran out of memory, call the OOM killer, and return the userspace
-	 * (which will retry the fault, or kill us if we got oom-killed):
-	 */
-	up_read(&current->mm->mmap_sem);
-
-	pagefault_out_of_memory();
-}
-
 static void
 do_sigbus(struct pt_regs *regs, unsigned long error_code, unsigned long address)
 {
@@ -353,8 +342,14 @@
 			no_context(regs, error_code, address);
 			return 1;
 		}
+		up_read(&current->mm->mmap_sem);
 
-		out_of_memory();
+		/*
+		 * We ran out of memory, call the OOM killer, and return the
+		 * userspace (which will retry the fault, or kill us if we got
+		 * oom-killed):
+		 */
+		pagefault_out_of_memory();
 	} else {
 		if (fault & VM_FAULT_SIGBUS)
 			do_sigbus(regs, error_code, address);
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 9195fd8..65a872b 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -370,6 +370,7 @@
 	depends on NUMA
 	depends on SMP
 	depends on X86_X2APIC
+	depends on PCI_MMCONFIG
 	---help---
 	  Adds support for Numascale NumaChip large-SMP systems. Needed to
 	  enable more than ~168 cores.
diff --git a/arch/x86/boot/.gitignore b/arch/x86/boot/.gitignore
index 851fe93..e3cf9f6 100644
--- a/arch/x86/boot/.gitignore
+++ b/arch/x86/boot/.gitignore
@@ -2,7 +2,6 @@
 bzImage
 cpustr.h
 mkcpustr
-offsets.h
 voffset.h
 zoffset.h
 setup
diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c
index e87b0ca..b1942e2 100644
--- a/arch/x86/boot/compressed/eboot.c
+++ b/arch/x86/boot/compressed/eboot.c
@@ -8,6 +8,7 @@
  * ----------------------------------------------------------------------- */
 
 #include <linux/efi.h>
+#include <linux/pci.h>
 #include <asm/efi.h>
 #include <asm/setup.h>
 #include <asm/desc.h>
@@ -245,6 +246,121 @@
 	*size = len;
 }
 
+static efi_status_t setup_efi_pci(struct boot_params *params)
+{
+	efi_pci_io_protocol *pci;
+	efi_status_t status;
+	void **pci_handle;
+	efi_guid_t pci_proto = EFI_PCI_IO_PROTOCOL_GUID;
+	unsigned long nr_pci, size = 0;
+	int i;
+	struct setup_data *data;
+
+	data = (struct setup_data *)params->hdr.setup_data;
+
+	while (data && data->next)
+		data = (struct setup_data *)data->next;
+
+	status = efi_call_phys5(sys_table->boottime->locate_handle,
+				EFI_LOCATE_BY_PROTOCOL, &pci_proto,
+				NULL, &size, pci_handle);
+
+	if (status == EFI_BUFFER_TOO_SMALL) {
+		status = efi_call_phys3(sys_table->boottime->allocate_pool,
+					EFI_LOADER_DATA, size, &pci_handle);
+
+		if (status != EFI_SUCCESS)
+			return status;
+
+		status = efi_call_phys5(sys_table->boottime->locate_handle,
+					EFI_LOCATE_BY_PROTOCOL, &pci_proto,
+					NULL, &size, pci_handle);
+	}
+
+	if (status != EFI_SUCCESS)
+		goto free_handle;
+
+	nr_pci = size / sizeof(void *);
+	for (i = 0; i < nr_pci; i++) {
+		void *h = pci_handle[i];
+		uint64_t attributes;
+		struct pci_setup_rom *rom;
+
+		status = efi_call_phys3(sys_table->boottime->handle_protocol,
+					h, &pci_proto, &pci);
+
+		if (status != EFI_SUCCESS)
+			continue;
+
+		if (!pci)
+			continue;
+
+		status = efi_call_phys4(pci->attributes, pci,
+					EfiPciIoAttributeOperationGet, 0,
+					&attributes);
+
+		if (status != EFI_SUCCESS)
+			continue;
+
+		if (!attributes & EFI_PCI_IO_ATTRIBUTE_EMBEDDED_ROM)
+			continue;
+
+		if (!pci->romimage || !pci->romsize)
+			continue;
+
+		size = pci->romsize + sizeof(*rom);
+
+		status = efi_call_phys3(sys_table->boottime->allocate_pool,
+				EFI_LOADER_DATA, size, &rom);
+
+		if (status != EFI_SUCCESS)
+			continue;
+
+		rom->data.type = SETUP_PCI;
+		rom->data.len = size - sizeof(struct setup_data);
+		rom->data.next = 0;
+		rom->pcilen = pci->romsize;
+
+		status = efi_call_phys5(pci->pci.read, pci,
+					EfiPciIoWidthUint16, PCI_VENDOR_ID,
+					1, &(rom->vendor));
+
+		if (status != EFI_SUCCESS)
+			goto free_struct;
+
+		status = efi_call_phys5(pci->pci.read, pci,
+					EfiPciIoWidthUint16, PCI_DEVICE_ID,
+					1, &(rom->devid));
+
+		if (status != EFI_SUCCESS)
+			goto free_struct;
+
+		status = efi_call_phys5(pci->get_location, pci,
+					&(rom->segment), &(rom->bus),
+					&(rom->device), &(rom->function));
+
+		if (status != EFI_SUCCESS)
+			goto free_struct;
+
+		memcpy(rom->romdata, pci->romimage, pci->romsize);
+
+		if (data)
+			data->next = (uint64_t)rom;
+		else
+			params->hdr.setup_data = (uint64_t)rom;
+
+		data = (struct setup_data *)rom;
+
+		continue;
+	free_struct:
+		efi_call_phys1(sys_table->boottime->free_pool, rom);
+	}
+
+free_handle:
+	efi_call_phys1(sys_table->boottime->free_pool, pci_handle);
+	return status;
+}
+
 /*
  * See if we have Graphics Output Protocol
  */
@@ -1028,6 +1144,8 @@
 
 	setup_graphics(boot_params);
 
+	setup_efi_pci(boot_params);
+
 	status = efi_call_phys3(sys_table->boottime->allocate_pool,
 				EFI_LOADER_DATA, sizeof(*gdt),
 				(void **)&gdt);
diff --git a/arch/x86/include/asm/bootparam.h b/arch/x86/include/asm/bootparam.h
index 2ad874c..92862cd 100644
--- a/arch/x86/include/asm/bootparam.h
+++ b/arch/x86/include/asm/bootparam.h
@@ -13,6 +13,7 @@
 #define SETUP_NONE			0
 #define SETUP_E820_EXT			1
 #define SETUP_DTB			2
+#define SETUP_PCI			3
 
 /* extensible setup data list node */
 struct setup_data {
diff --git a/arch/x86/include/asm/numachip/numachip.h b/arch/x86/include/asm/numachip/numachip.h
new file mode 100644
index 0000000..1c6f7f6
--- /dev/null
+++ b/arch/x86/include/asm/numachip/numachip.h
@@ -0,0 +1,19 @@
+/*
+ * 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.
+ *
+ * Numascale NumaConnect-specific header file
+ *
+ * Copyright (C) 2012 Numascale AS. All rights reserved.
+ *
+ * Send feedback to <support@numascale.com>
+ *
+ */
+
+#ifndef _ASM_X86_NUMACHIP_NUMACHIP_H
+#define _ASM_X86_NUMACHIP_NUMACHIP_H
+
+extern int __init pci_numachip_init(void);
+
+#endif /* _ASM_X86_NUMACHIP_NUMACHIP_H */
diff --git a/arch/x86/include/asm/pci.h b/arch/x86/include/asm/pci.h
index 6e41b93..dba7805 100644
--- a/arch/x86/include/asm/pci.h
+++ b/arch/x86/include/asm/pci.h
@@ -171,4 +171,16 @@
 }
 #endif
 
+struct pci_setup_rom {
+	struct setup_data data;
+	uint16_t vendor;
+	uint16_t devid;
+	uint64_t pcilen;
+	unsigned long segment;
+	unsigned long bus;
+	unsigned long device;
+	unsigned long function;
+	uint8_t romdata[0];
+};
+
 #endif /* _ASM_X86_PCI_H */
diff --git a/arch/x86/kernel/apic/apic_numachip.c b/arch/x86/kernel/apic/apic_numachip.c
index a65829a..9c2aa89 100644
--- a/arch/x86/kernel/apic/apic_numachip.c
+++ b/arch/x86/kernel/apic/apic_numachip.c
@@ -22,6 +22,7 @@
 #include <linux/hardirq.h>
 #include <linux/delay.h>
 
+#include <asm/numachip/numachip.h>
 #include <asm/numachip/numachip_csr.h>
 #include <asm/smp.h>
 #include <asm/apic.h>
@@ -179,6 +180,7 @@
 		return 0;
 
 	x86_cpuinit.fixup_cpu_id = fixup_cpu_id;
+	x86_init.pci.arch_init = pci_numachip_init;
 
 	map_csrs();
 
diff --git a/arch/x86/kernel/cpu/mtrr/main.c b/arch/x86/kernel/cpu/mtrr/main.c
index e4c1a41..726bf96 100644
--- a/arch/x86/kernel/cpu/mtrr/main.c
+++ b/arch/x86/kernel/cpu/mtrr/main.c
@@ -606,7 +606,7 @@
 
 		/*
 		 * This is an AMD specific MSR, but we assume(hope?) that
-		 * Intel will implement it to when they extend the address
+		 * Intel will implement it too when they extend the address
 		 * bus of the Xeon.
 		 */
 		if (cpuid_eax(0x80000000) >= 0x80000008) {
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index ca45696..c228322 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -143,11 +143,7 @@
 }
 #endif
 
-#ifndef CONFIG_DEBUG_BOOT_PARAMS
-struct boot_params __initdata boot_params;
-#else
 struct boot_params boot_params;
-#endif
 
 /*
  * Machine setup..
diff --git a/arch/x86/kernel/vm86_32.c b/arch/x86/kernel/vm86_32.c
index 5c9687b..1dfe69c 100644
--- a/arch/x86/kernel/vm86_32.c
+++ b/arch/x86/kernel/vm86_32.c
@@ -182,7 +182,7 @@
 	if (pud_none_or_clear_bad(pud))
 		goto out;
 	pmd = pmd_offset(pud, 0xA0000);
-	split_huge_page_pmd(mm, pmd);
+	split_huge_page_pmd_mm(mm, 0xA0000, pmd);
 	if (pmd_none_or_clear_bad(pmd))
 		goto out;
 	pte = pte_offset_map_lock(mm, pmd, 0xA0000, &ptl);
diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c
index 7a529cb..027088f 100644
--- a/arch/x86/mm/fault.c
+++ b/arch/x86/mm/fault.c
@@ -803,20 +803,6 @@
 	__bad_area(regs, error_code, address, SEGV_ACCERR);
 }
 
-/* TODO: fixup for "mm-invoke-oom-killer-from-page-fault.patch" */
-static void
-out_of_memory(struct pt_regs *regs, unsigned long error_code,
-	      unsigned long address)
-{
-	/*
-	 * We ran out of memory, call the OOM killer, and return the userspace
-	 * (which will retry the fault, or kill us if we got oom-killed):
-	 */
-	up_read(&current->mm->mmap_sem);
-
-	pagefault_out_of_memory();
-}
-
 static void
 do_sigbus(struct pt_regs *regs, unsigned long error_code, unsigned long address,
 	  unsigned int fault)
@@ -879,7 +865,14 @@
 			return 1;
 		}
 
-		out_of_memory(regs, error_code, address);
+		up_read(&current->mm->mmap_sem);
+
+		/*
+		 * We ran out of memory, call the OOM killer, and return the
+		 * userspace (which will retry the fault, or kill us if we got
+		 * oom-killed):
+		 */
+		pagefault_out_of_memory();
 	} else {
 		if (fault & (VM_FAULT_SIGBUS|VM_FAULT_HWPOISON|
 			     VM_FAULT_HWPOISON_LARGE))
diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c
index 3baff25..2ead3c8 100644
--- a/arch/x86/mm/init_64.c
+++ b/arch/x86/mm/init_64.c
@@ -630,7 +630,9 @@
 	 *	 numa support is not compiled in, and later node_set_state
 	 *	 will not set it back.
 	 */
-	node_clear_state(0, N_NORMAL_MEMORY);
+	node_clear_state(0, N_MEMORY);
+	if (N_MEMORY != N_NORMAL_MEMORY)
+		node_clear_state(0, N_NORMAL_MEMORY);
 
 	zone_sizes_init();
 }
diff --git a/arch/x86/mm/pgtable.c b/arch/x86/mm/pgtable.c
index 8573b83..217eb70 100644
--- a/arch/x86/mm/pgtable.c
+++ b/arch/x86/mm/pgtable.c
@@ -137,7 +137,7 @@
  * against pageattr.c; it is the unique case in which a valid change
  * of kernel pagetables can't be lazily synchronized by vmalloc faults.
  * vmalloc faults work because attached pagetables are never freed.
- * -- wli
+ * -- nyc
  */
 
 #ifdef CONFIG_X86_PAE
diff --git a/arch/x86/pci/Makefile b/arch/x86/pci/Makefile
index 3af5a1e..ee0af58 100644
--- a/arch/x86/pci/Makefile
+++ b/arch/x86/pci/Makefile
@@ -16,6 +16,7 @@
 obj-$(CONFIG_X86_VISWS)		+= visws.o
 
 obj-$(CONFIG_X86_NUMAQ)		+= numaq_32.o
+obj-$(CONFIG_X86_NUMACHIP)	+= numachip.o
 
 obj-$(CONFIG_X86_INTEL_MID)	+= mrst.o
 
diff --git a/arch/x86/pci/acpi.c b/arch/x86/pci/acpi.c
index 192397c..0c01261f 100644
--- a/arch/x86/pci/acpi.c
+++ b/arch/x86/pci/acpi.c
@@ -12,6 +12,7 @@
 	char name[16];
 	unsigned int res_num;
 	struct resource *res;
+	resource_size_t *res_offset;
 	struct pci_sysdata sd;
 #ifdef	CONFIG_PCI_MMCONFIG
 	bool mcfg_added;
@@ -22,6 +23,7 @@
 };
 
 static bool pci_use_crs = true;
+static bool pci_ignore_seg = false;
 
 static int __init set_use_crs(const struct dmi_system_id *id)
 {
@@ -35,7 +37,14 @@
 	return 0;
 }
 
-static const struct dmi_system_id pci_use_crs_table[] __initconst = {
+static int __init set_ignore_seg(const struct dmi_system_id *id)
+{
+	printk(KERN_INFO "PCI: %s detected: ignoring ACPI _SEG\n", id->ident);
+	pci_ignore_seg = true;
+	return 0;
+}
+
+static const struct dmi_system_id pci_crs_quirks[] __initconst = {
 	/* http://bugzilla.kernel.org/show_bug.cgi?id=14183 */
 	{
 		.callback = set_use_crs,
@@ -98,6 +107,16 @@
 			DMI_MATCH(DMI_BIOS_VERSION, "6JET85WW (1.43 )"),
 		},
 	},
+
+	/* https://bugzilla.kernel.org/show_bug.cgi?id=15362 */
+	{
+		.callback = set_ignore_seg,
+		.ident = "HP xw9300",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "HP xw9300 Workstation"),
+		},
+	},
 	{}
 };
 
@@ -108,7 +127,7 @@
 	if (dmi_get_date(DMI_BIOS_DATE, &year, NULL, NULL) && year < 2008)
 		pci_use_crs = false;
 
-	dmi_check_system(pci_use_crs_table);
+	dmi_check_system(pci_crs_quirks);
 
 	/*
 	 * If the user specifies "pci=use_crs" or "pci=nocrs" explicitly, that
@@ -305,6 +324,7 @@
 	res->flags = flags;
 	res->start = start;
 	res->end = end;
+	info->res_offset[info->res_num] = addr.translation_offset;
 
 	if (!pci_use_crs) {
 		dev_printk(KERN_DEBUG, &info->bridge->dev,
@@ -374,7 +394,8 @@
 				 "ignoring host bridge window %pR (conflicts with %s %pR)\n",
 				 res, conflict->name, conflict);
 		else
-			pci_add_resource(resources, res);
+			pci_add_resource_offset(resources, res,
+					info->res_offset[i]);
 	}
 }
 
@@ -382,6 +403,8 @@
 {
 	kfree(info->res);
 	info->res = NULL;
+	kfree(info->res_offset);
+	info->res_offset = NULL;
 	info->res_num = 0;
 }
 
@@ -432,10 +455,20 @@
 		return;
 
 	size = sizeof(*info->res) * info->res_num;
-	info->res_num = 0;
 	info->res = kzalloc(size, GFP_KERNEL);
-	if (!info->res)
+	if (!info->res) {
+		info->res_num = 0;
 		return;
+	}
+
+	size = sizeof(*info->res_offset) * info->res_num;
+	info->res_num = 0;
+	info->res_offset = kzalloc(size, GFP_KERNEL);
+	if (!info->res_offset) {
+		kfree(info->res);
+		info->res = NULL;
+		return;
+	}
 
 	acpi_walk_resources(device->handle, METHOD_NAME__CRS, setup_resource,
 				info);
@@ -455,6 +488,9 @@
 	int pxm;
 #endif
 
+	if (pci_ignore_seg)
+		domain = 0;
+
 	if (domain && !pci_domains_supported) {
 		printk(KERN_WARNING "pci_bus %04x:%02x: "
 		       "ignored (multiple domains not supported)\n",
diff --git a/arch/x86/pci/common.c b/arch/x86/pci/common.c
index 720e973f..1b1dda9 100644
--- a/arch/x86/pci/common.c
+++ b/arch/x86/pci/common.c
@@ -17,6 +17,7 @@
 #include <asm/io.h>
 #include <asm/smp.h>
 #include <asm/pci_x86.h>
+#include <asm/setup.h>
 
 unsigned int pci_probe = PCI_PROBE_BIOS | PCI_PROBE_CONF1 | PCI_PROBE_CONF2 |
 				PCI_PROBE_MMCONF;
@@ -608,6 +609,35 @@
 	return (pci_probe & PCI_ASSIGN_ALL_BUSSES) ? 1 : 0;
 }
 
+int pcibios_add_device(struct pci_dev *dev)
+{
+	struct setup_data *data;
+	struct pci_setup_rom *rom;
+	u64 pa_data;
+
+	pa_data = boot_params.hdr.setup_data;
+	while (pa_data) {
+		data = phys_to_virt(pa_data);
+
+		if (data->type == SETUP_PCI) {
+			rom = (struct pci_setup_rom *)data;
+
+			if ((pci_domain_nr(dev->bus) == rom->segment) &&
+			    (dev->bus->number == rom->bus) &&
+			    (PCI_SLOT(dev->devfn) == rom->device) &&
+			    (PCI_FUNC(dev->devfn) == rom->function) &&
+			    (dev->vendor == rom->vendor) &&
+			    (dev->device == rom->devid)) {
+				dev->rom = pa_data +
+				      offsetof(struct pci_setup_rom, romdata);
+				dev->romlen = rom->pcilen;
+			}
+		}
+		pa_data = data->next;
+	}
+	return 0;
+}
+
 int pcibios_enable_device(struct pci_dev *dev, int mask)
 {
 	int err;
@@ -626,7 +656,7 @@
 		pcibios_disable_irq(dev);
 }
 
-int pci_ext_cfg_avail(struct pci_dev *dev)
+int pci_ext_cfg_avail(void)
 {
 	if (raw_pci_ext_ops)
 		return 1;
diff --git a/arch/x86/pci/numachip.c b/arch/x86/pci/numachip.c
new file mode 100644
index 0000000..7307d9d
--- /dev/null
+++ b/arch/x86/pci/numachip.c
@@ -0,0 +1,129 @@
+/*
+ * 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.
+ *
+ * Numascale NumaConnect-specific PCI code
+ *
+ * Copyright (C) 2012 Numascale AS. All rights reserved.
+ *
+ * Send feedback to <support@numascale.com>
+ *
+ * PCI accessor functions derived from mmconfig_64.c
+ *
+ */
+
+#include <linux/pci.h>
+#include <asm/pci_x86.h>
+
+static u8 limit __read_mostly;
+
+static inline char __iomem *pci_dev_base(unsigned int seg, unsigned int bus, unsigned int devfn)
+{
+	struct pci_mmcfg_region *cfg = pci_mmconfig_lookup(seg, bus);
+
+	if (cfg && cfg->virt)
+		return cfg->virt + (PCI_MMCFG_BUS_OFFSET(bus) | (devfn << 12));
+	return NULL;
+}
+
+static int pci_mmcfg_read_numachip(unsigned int seg, unsigned int bus,
+			  unsigned int devfn, int reg, int len, u32 *value)
+{
+	char __iomem *addr;
+
+	/* Why do we have this when nobody checks it. How about a BUG()!? -AK */
+	if (unlikely((bus > 255) || (devfn > 255) || (reg > 4095))) {
+err:		*value = -1;
+		return -EINVAL;
+	}
+
+	/* Ensure AMD Northbridges don't decode reads to other devices */
+	if (unlikely(bus == 0 && devfn >= limit)) {
+		*value = -1;
+		return 0;
+	}
+
+	rcu_read_lock();
+	addr = pci_dev_base(seg, bus, devfn);
+	if (!addr) {
+		rcu_read_unlock();
+		goto err;
+	}
+
+	switch (len) {
+	case 1:
+		*value = mmio_config_readb(addr + reg);
+		break;
+	case 2:
+		*value = mmio_config_readw(addr + reg);
+		break;
+	case 4:
+		*value = mmio_config_readl(addr + reg);
+		break;
+	}
+	rcu_read_unlock();
+
+	return 0;
+}
+
+static int pci_mmcfg_write_numachip(unsigned int seg, unsigned int bus,
+			   unsigned int devfn, int reg, int len, u32 value)
+{
+	char __iomem *addr;
+
+	/* Why do we have this when nobody checks it. How about a BUG()!? -AK */
+	if (unlikely((bus > 255) || (devfn > 255) || (reg > 4095)))
+		return -EINVAL;
+
+	/* Ensure AMD Northbridges don't decode writes to other devices */
+	if (unlikely(bus == 0 && devfn >= limit))
+		return 0;
+
+	rcu_read_lock();
+	addr = pci_dev_base(seg, bus, devfn);
+	if (!addr) {
+		rcu_read_unlock();
+		return -EINVAL;
+	}
+
+	switch (len) {
+	case 1:
+		mmio_config_writeb(addr + reg, value);
+		break;
+	case 2:
+		mmio_config_writew(addr + reg, value);
+		break;
+	case 4:
+		mmio_config_writel(addr + reg, value);
+		break;
+	}
+	rcu_read_unlock();
+
+	return 0;
+}
+
+const struct pci_raw_ops pci_mmcfg_numachip = {
+	.read = pci_mmcfg_read_numachip,
+	.write = pci_mmcfg_write_numachip,
+};
+
+int __init pci_numachip_init(void)
+{
+	int ret = 0;
+	u32 val;
+
+	/* For remote I/O, restrict bus 0 access to the actual number of AMD
+	   Northbridges, which starts at device number 0x18 */
+	ret = raw_pci_read(0, 0, PCI_DEVFN(0x18, 0), 0x60, sizeof(val), &val);
+	if (ret)
+		goto out;
+
+	/* HyperTransport fabric size in bits 6:4 */
+	limit = PCI_DEVFN(0x18 + ((val >> 4) & 7) + 1, 0);
+
+	/* Use NumaChip PCI accessors for non-extended and extended access */
+	raw_pci_ops = raw_pci_ext_ops = &pci_mmcfg_numachip;
+out:
+	return ret;
+}
diff --git a/drivers/acpi/acpica/dsopcode.c b/drivers/acpi/acpica/dsopcode.c
index 0df024e..d09c6b4 100644
--- a/drivers/acpi/acpica/dsopcode.c
+++ b/drivers/acpi/acpica/dsopcode.c
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Module Name: dsopcode - Dispatcher suport for regions and fields
+ * Module Name: dsopcode - Dispatcher support for regions and fields
  *
  *****************************************************************************/
 
diff --git a/drivers/acpi/pci_bind.c b/drivers/acpi/pci_bind.c
index 2ef0409..a1dee29 100644
--- a/drivers/acpi/pci_bind.c
+++ b/drivers/acpi/pci_bind.c
@@ -45,11 +45,12 @@
 
 	device_set_run_wake(&dev->dev, false);
 	pci_acpi_remove_pm_notifier(device);
+	acpi_power_resource_unregister_device(&dev->dev, device->handle);
 
 	if (!dev->subordinate)
 		goto out;
 
-	acpi_pci_irq_del_prt(dev->subordinate);
+	acpi_pci_irq_del_prt(pci_domain_nr(dev->bus), dev->subordinate->number);
 
 	device->ops.bind = NULL;
 	device->ops.unbind = NULL;
@@ -63,7 +64,7 @@
 {
 	acpi_status status;
 	acpi_handle handle;
-	struct pci_bus *bus;
+	unsigned char bus;
 	struct pci_dev *dev;
 
 	dev = acpi_get_pci_dev(device->handle);
@@ -71,6 +72,7 @@
 		return 0;
 
 	pci_acpi_add_pm_notifier(device, dev);
+	acpi_power_resource_register_device(&dev->dev, device->handle);
 	if (device->wakeup.flags.run_wake)
 		device_set_run_wake(&dev->dev, true);
 
@@ -100,11 +102,11 @@
 		goto out;
 
 	if (dev->subordinate)
-		bus = dev->subordinate;
+		bus = dev->subordinate->number;
 	else
-		bus = dev->bus;
+		bus = dev->bus->number;
 
-	acpi_pci_irq_add_prt(device->handle, bus);
+	acpi_pci_irq_add_prt(device->handle, pci_domain_nr(dev->bus), bus);
 
 out:
 	pci_dev_put(dev);
diff --git a/drivers/acpi/pci_irq.c b/drivers/acpi/pci_irq.c
index 23a0324..68a921d 100644
--- a/drivers/acpi/pci_irq.c
+++ b/drivers/acpi/pci_irq.c
@@ -184,7 +184,7 @@
 	}
 }
 
-static int acpi_pci_irq_add_entry(acpi_handle handle, struct pci_bus *bus,
+static int acpi_pci_irq_add_entry(acpi_handle handle, int segment, int bus,
 				  struct acpi_pci_routing_table *prt)
 {
 	struct acpi_prt_entry *entry;
@@ -198,8 +198,8 @@
 	 * 1=INTA, 2=INTB.  We use the PCI encoding throughout, so convert
 	 * it here.
 	 */
-	entry->id.segment = pci_domain_nr(bus);
-	entry->id.bus = bus->number;
+	entry->id.segment = segment;
+	entry->id.bus = bus;
 	entry->id.device = (prt->address >> 16) & 0xFFFF;
 	entry->pin = prt->pin + 1;
 
@@ -244,7 +244,7 @@
 	return 0;
 }
 
-int acpi_pci_irq_add_prt(acpi_handle handle, struct pci_bus *bus)
+int acpi_pci_irq_add_prt(acpi_handle handle, int segment, int bus)
 {
 	acpi_status status;
 	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
@@ -273,7 +273,7 @@
 
 	entry = buffer.pointer;
 	while (entry && (entry->length > 0)) {
-		acpi_pci_irq_add_entry(handle, bus, entry);
+		acpi_pci_irq_add_entry(handle, segment, bus, entry);
 		entry = (struct acpi_pci_routing_table *)
 		    ((unsigned long)entry + entry->length);
 	}
@@ -282,17 +282,16 @@
 	return 0;
 }
 
-void acpi_pci_irq_del_prt(struct pci_bus *bus)
+void acpi_pci_irq_del_prt(int segment, int bus)
 {
 	struct acpi_prt_entry *entry, *tmp;
 
 	printk(KERN_DEBUG
 	       "ACPI: Delete PCI Interrupt Routing Table for %04x:%02x\n",
-	       pci_domain_nr(bus), bus->number);
+	       segment, bus);
 	spin_lock(&acpi_prt_lock);
 	list_for_each_entry_safe(entry, tmp, &acpi_prt_list, list) {
-		if (pci_domain_nr(bus) == entry->id.segment
-			&& bus->number == entry->id.bus) {
+		if (segment == entry->id.segment && bus == entry->id.bus) {
 			list_del(&entry->list);
 			kfree(entry);
 		}
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index f70b9e5..7928d4d 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -454,6 +454,7 @@
 	acpi_handle handle;
 	struct acpi_device *child;
 	u32 flags, base_flags;
+	bool is_osc_granted = false;
 
 	root = kzalloc(sizeof(struct acpi_pci_root), GFP_KERNEL);
 	if (!root)
@@ -501,6 +502,20 @@
 	strcpy(acpi_device_class(device), ACPI_PCI_ROOT_CLASS);
 	device->driver_data = root;
 
+	printk(KERN_INFO PREFIX "%s [%s] (domain %04x %pR)\n",
+	       acpi_device_name(device), acpi_device_bid(device),
+	       root->segment, &root->secondary);
+
+	/*
+	 * PCI Routing Table
+	 * -----------------
+	 * Evaluate and parse _PRT, if exists.
+	 */
+	status = acpi_get_handle(device->handle, METHOD_NAME__PRT, &handle);
+	if (ACPI_SUCCESS(status))
+		result = acpi_pci_irq_add_prt(device->handle, root->segment,
+					      root->secondary.start);
+
 	root->mcfg_addr = acpi_pci_root_get_mcfg_addr(device->handle);
 
 	/*
@@ -510,6 +525,60 @@
 	flags = base_flags = OSC_PCI_SEGMENT_GROUPS_SUPPORT;
 	acpi_pci_osc_support(root, flags);
 
+	/* Indicate support for various _OSC capabilities. */
+	if (pci_ext_cfg_avail())
+		flags |= OSC_EXT_PCI_CONFIG_SUPPORT;
+	if (pcie_aspm_support_enabled()) {
+		flags |= OSC_ACTIVE_STATE_PWR_SUPPORT |
+		OSC_CLOCK_PWR_CAPABILITY_SUPPORT;
+	}
+	if (pci_msi_enabled())
+		flags |= OSC_MSI_SUPPORT;
+	if (flags != base_flags) {
+		status = acpi_pci_osc_support(root, flags);
+		if (ACPI_FAILURE(status)) {
+			dev_info(&device->dev, "ACPI _OSC support "
+				"notification failed, disabling PCIe ASPM\n");
+			pcie_no_aspm();
+			flags = base_flags;
+		}
+	}
+	if (!pcie_ports_disabled
+	    && (flags & ACPI_PCIE_REQ_SUPPORT) == ACPI_PCIE_REQ_SUPPORT) {
+		flags = OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL
+			| OSC_PCI_EXPRESS_NATIVE_HP_CONTROL
+			| OSC_PCI_EXPRESS_PME_CONTROL;
+
+		if (pci_aer_available()) {
+			if (aer_acpi_firmware_first())
+				dev_dbg(&device->dev,
+					"PCIe errors handled by BIOS.\n");
+			else
+				flags |= OSC_PCI_EXPRESS_AER_CONTROL;
+		}
+
+		dev_info(&device->dev,
+			"Requesting ACPI _OSC control (0x%02x)\n", flags);
+
+		status = acpi_pci_osc_control_set(device->handle, &flags,
+				       OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL);
+		if (ACPI_SUCCESS(status)) {
+			is_osc_granted = true;
+			dev_info(&device->dev,
+				"ACPI _OSC control (0x%02x) granted\n", flags);
+		} else {
+			is_osc_granted = false;
+			dev_info(&device->dev,
+				"ACPI _OSC request failed (%s), "
+				"returned control mask: 0x%02x\n",
+				acpi_format_exception(status), flags);
+		}
+	} else {
+		dev_info(&device->dev,
+			"Unable to request _OSC control "
+			"(_OSC support mask: 0x%02x)\n", flags);
+	}
+
 	/*
 	 * TBD: Need PCI interface for enumeration/configuration of roots.
 	 */
@@ -518,10 +587,6 @@
 	list_add_tail(&root->node, &acpi_pci_roots);
 	mutex_unlock(&acpi_pci_root_lock);
 
-	printk(KERN_INFO PREFIX "%s [%s] (domain %04x %pR)\n",
-	       acpi_device_name(device), acpi_device_bid(device),
-	       root->segment, &root->secondary);
-
 	/*
 	 * Scan the Root Bridge
 	 * --------------------
@@ -548,80 +613,19 @@
 		goto out_del_root;
 
 	/*
-	 * PCI Routing Table
-	 * -----------------
-	 * Evaluate and parse _PRT, if exists.
-	 */
-	status = acpi_get_handle(device->handle, METHOD_NAME__PRT, &handle);
-	if (ACPI_SUCCESS(status))
-		result = acpi_pci_irq_add_prt(device->handle, root->bus);
-
-	/*
 	 * Scan and bind all _ADR-Based Devices
 	 */
 	list_for_each_entry(child, &device->children, node)
 		acpi_pci_bridge_scan(child);
 
-	/* Indicate support for various _OSC capabilities. */
-	if (pci_ext_cfg_avail(root->bus->self))
-		flags |= OSC_EXT_PCI_CONFIG_SUPPORT;
-	if (pcie_aspm_support_enabled())
-		flags |= OSC_ACTIVE_STATE_PWR_SUPPORT |
-			OSC_CLOCK_PWR_CAPABILITY_SUPPORT;
-	if (pci_msi_enabled())
-		flags |= OSC_MSI_SUPPORT;
-	if (flags != base_flags) {
-		status = acpi_pci_osc_support(root, flags);
-		if (ACPI_FAILURE(status)) {
-			dev_info(root->bus->bridge, "ACPI _OSC support "
-				"notification failed, disabling PCIe ASPM\n");
-			pcie_no_aspm();
-			flags = base_flags;
-		}
-	}
-
-	if (!pcie_ports_disabled
-	    && (flags & ACPI_PCIE_REQ_SUPPORT) == ACPI_PCIE_REQ_SUPPORT) {
-		flags = OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL
-			| OSC_PCI_EXPRESS_NATIVE_HP_CONTROL
-			| OSC_PCI_EXPRESS_PME_CONTROL;
-
-		if (pci_aer_available()) {
-			if (aer_acpi_firmware_first())
-				dev_dbg(root->bus->bridge,
-					"PCIe errors handled by BIOS.\n");
-			else
-				flags |= OSC_PCI_EXPRESS_AER_CONTROL;
-		}
-
-		dev_info(root->bus->bridge,
-			"Requesting ACPI _OSC control (0x%02x)\n", flags);
-
-		status = acpi_pci_osc_control_set(device->handle, &flags,
-					OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL);
-		if (ACPI_SUCCESS(status)) {
-			dev_info(root->bus->bridge,
-				"ACPI _OSC control (0x%02x) granted\n", flags);
-			if (acpi_gbl_FADT.boot_flags & ACPI_FADT_NO_ASPM) {
-				/*
-				 * We have ASPM control, but the FADT indicates
-				 * that it's unsupported. Clear it.
-				 */
-				pcie_clear_aspm(root->bus);
-			}
-		} else {
-			dev_info(root->bus->bridge,
-				"ACPI _OSC request failed (%s), "
-				"returned control mask: 0x%02x\n",
-				acpi_format_exception(status), flags);
-			pr_info("ACPI _OSC control for PCIe not granted, "
-				"disabling ASPM\n");
-			pcie_no_aspm();
-		}
+	/* ASPM setting */
+	if (is_osc_granted) {
+		if (acpi_gbl_FADT.boot_flags & ACPI_FADT_NO_ASPM)
+			pcie_clear_aspm(root->bus);
 	} else {
-		dev_info(root->bus->bridge,
-			 "Unable to request _OSC control "
-			 "(_OSC support mask: 0x%02x)\n", flags);
+		pr_info("ACPI _OSC control for PCIe not granted, "
+			"disabling ASPM\n");
+		pcie_no_aspm();
 	}
 
 	pci_acpi_add_bus_pm_notifier(device, root->bus);
@@ -634,6 +638,8 @@
 	mutex_lock(&acpi_pci_root_lock);
 	list_del(&root->node);
 	mutex_unlock(&acpi_pci_root_lock);
+
+	acpi_pci_irq_del_prt(root->segment, root->secondary.start);
 end:
 	kfree(root);
 	return result;
@@ -644,12 +650,19 @@
 	struct acpi_pci_root *root = acpi_driver_data(device);
 	struct acpi_pci_driver *driver;
 
+	if (system_state != SYSTEM_BOOTING)
+		pci_assign_unassigned_bus_resources(root->bus);
+
 	mutex_lock(&acpi_pci_root_lock);
 	list_for_each_entry(driver, &acpi_pci_drivers, node)
 		if (driver->add)
 			driver->add(root);
 	mutex_unlock(&acpi_pci_root_lock);
 
+	/* need to after hot-added ioapic is registered */
+	if (system_state != SYSTEM_BOOTING)
+		pci_enable_bridges(root->bus);
+
 	pci_bus_add_devices(root->bus);
 
 	return 0;
@@ -657,17 +670,29 @@
 
 static int acpi_pci_root_remove(struct acpi_device *device, int type)
 {
+	acpi_status status;
+	acpi_handle handle;
 	struct acpi_pci_root *root = acpi_driver_data(device);
 	struct acpi_pci_driver *driver;
 
+	pci_stop_root_bus(root->bus);
+
 	mutex_lock(&acpi_pci_root_lock);
-	list_for_each_entry(driver, &acpi_pci_drivers, node)
+	list_for_each_entry_reverse(driver, &acpi_pci_drivers, node)
 		if (driver->remove)
 			driver->remove(root);
+	mutex_unlock(&acpi_pci_root_lock);
 
 	device_set_run_wake(root->bus->bridge, false);
 	pci_acpi_remove_bus_pm_notifier(device);
 
+	status = acpi_get_handle(device->handle, METHOD_NAME__PRT, &handle);
+	if (ACPI_SUCCESS(status))
+		acpi_pci_irq_del_prt(root->segment, root->secondary.start);
+
+	pci_remove_root_bus(root->bus);
+
+	mutex_lock(&acpi_pci_root_lock);
 	list_del(&root->node);
 	mutex_unlock(&acpi_pci_root_lock);
 	kfree(root);
diff --git a/drivers/base/node.c b/drivers/base/node.c
index 294e316..fac124a 100644
--- a/drivers/base/node.c
+++ b/drivers/base/node.c
@@ -227,7 +227,7 @@
 static inline bool hugetlb_register_node(struct node *node)
 {
 	if (__hugetlb_register_node &&
-			node_state(node->dev.id, N_HIGH_MEMORY)) {
+			node_state(node->dev.id, N_MEMORY)) {
 		__hugetlb_register_node(node);
 		return true;
 	}
@@ -644,6 +644,9 @@
 #ifdef CONFIG_HIGHMEM
 	[N_HIGH_MEMORY] = _NODE_ATTR(has_high_memory, N_HIGH_MEMORY),
 #endif
+#ifdef CONFIG_MOVABLE_NODE
+	[N_MEMORY] = _NODE_ATTR(has_memory, N_MEMORY),
+#endif
 	[N_CPU] = _NODE_ATTR(has_cpu, N_CPU),
 };
 
@@ -654,6 +657,9 @@
 #ifdef CONFIG_HIGHMEM
 	&node_state_attr[N_HIGH_MEMORY].attr.attr,
 #endif
+#ifdef CONFIG_MOVABLE_NODE
+	&node_state_attr[N_MEMORY].attr.attr,
+#endif
 	&node_state_attr[N_CPU].attr.attr,
 	NULL
 };
diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig
index c58ea9b..c5a0262 100644
--- a/drivers/char/hw_random/Kconfig
+++ b/drivers/char/hw_random/Kconfig
@@ -216,7 +216,7 @@
 
 config HW_RANDOM_NOMADIK
 	tristate "ST-Ericsson Nomadik Random Number Generator support"
-	depends on HW_RANDOM && PLAT_NOMADIK
+	depends on HW_RANDOM && ARCH_NOMADIK
 	---help---
 	  This driver provides kernel-side support for the Random Number
 	  Generator hardware found on ST-Ericsson SoCs (8815 and 8500).
diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c
index a0c84bb..053201b 100644
--- a/drivers/char/ipmi/ipmi_msghandler.c
+++ b/drivers/char/ipmi/ipmi_msghandler.c
@@ -3789,7 +3789,7 @@
 
 	} else if ((msg->rsp[0] == ((IPMI_NETFN_APP_REQUEST|1) << 2))
 		   && (msg->rsp[1] == IPMI_READ_EVENT_MSG_BUFFER_CMD)) {
-		/* It's an asyncronous event. */
+		/* It's an asynchronous event. */
 		requeue = handle_read_event_rsp(intf, msg);
 	} else {
 		/* It's a response from the local BMC. */
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c
index 20ab5b3..cfdfecd 100644
--- a/drivers/char/ipmi/ipmi_si_intf.c
+++ b/drivers/char/ipmi/ipmi_si_intf.c
@@ -155,7 +155,7 @@
 	/* Number of watchdog pretimeouts. */
 	SI_STAT_watchdog_pretimeouts,
 
-	/* Number of asyncronous messages received. */
+	/* Number of asynchronous messages received. */
 	SI_STAT_incoming_messages,
 
 
diff --git a/drivers/char/ppdev.c b/drivers/char/ppdev.c
index d0d824e..1cd4924 100644
--- a/drivers/char/ppdev.c
+++ b/drivers/char/ppdev.c
@@ -251,12 +251,8 @@
 			break;
 		}
 
-		if (signal_pending (current)) {
-			if (!bytes_written) {
-				bytes_written = -EINTR;
-			}
+		if (signal_pending (current))
 			break;
-		}
 
 		cond_resched();
 	}
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index a96bda3..4e1ccb1 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -20,6 +20,7 @@
 obj-$(CONFIG_ARCH_U8500)	+= ux500/
 obj-$(CONFIG_ARCH_VT8500)	+= clk-vt8500.o
 obj-$(CONFIG_ARCH_SUNXI)	+= clk-sunxi.o
+obj-$(CONFIG_ARCH_ZYNQ)		+= clk-zynq.o
 
 # Chip specific
 obj-$(CONFIG_COMMON_CLK_WM831X) += clk-wm831x.o
diff --git a/drivers/clk/clk-zynq.c b/drivers/clk/clk-zynq.c
new file mode 100644
index 0000000..37a3051
--- /dev/null
+++ b/drivers/clk/clk-zynq.c
@@ -0,0 +1,383 @@
+/*
+ * Copyright (c) 2012 National Instruments
+ *
+ * Josh Cartwright <josh.cartwright@ni.com>
+ *
+ * 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/io.h>
+#include <linux/of.h>
+#include <linux/slab.h>
+#include <linux/kernel.h>
+#include <linux/clk-provider.h>
+
+static void __iomem *slcr_base;
+
+struct zynq_pll_clk {
+	struct clk_hw	hw;
+	void __iomem	*pll_ctrl;
+	void __iomem	*pll_cfg;
+};
+
+#define to_zynq_pll_clk(hw)	container_of(hw, struct zynq_pll_clk, hw)
+
+#define CTRL_PLL_FDIV(x)	((x) >> 12)
+
+static unsigned long zynq_pll_recalc_rate(struct clk_hw *hw,
+					  unsigned long parent_rate)
+{
+	struct zynq_pll_clk *pll = to_zynq_pll_clk(hw);
+	return parent_rate * CTRL_PLL_FDIV(ioread32(pll->pll_ctrl));
+}
+
+static const struct clk_ops zynq_pll_clk_ops = {
+	.recalc_rate	= zynq_pll_recalc_rate,
+};
+
+static void __init zynq_pll_clk_setup(struct device_node *np)
+{
+	struct clk_init_data init;
+	struct zynq_pll_clk *pll;
+	const char *parent_name;
+	struct clk *clk;
+	u32 regs[2];
+	int ret;
+
+	ret = of_property_read_u32_array(np, "reg", regs, ARRAY_SIZE(regs));
+	if (WARN_ON(ret))
+		return;
+
+	pll = kzalloc(sizeof(*pll), GFP_KERNEL);
+	if (WARN_ON(!pll))
+		return;
+
+	pll->pll_ctrl = slcr_base + regs[0];
+	pll->pll_cfg  = slcr_base + regs[1];
+
+	of_property_read_string(np, "clock-output-names", &init.name);
+
+	init.ops = &zynq_pll_clk_ops;
+	parent_name = of_clk_get_parent_name(np, 0);
+	init.parent_names = &parent_name;
+	init.num_parents = 1;
+
+	pll->hw.init = &init;
+
+	clk = clk_register(NULL, &pll->hw);
+	if (WARN_ON(IS_ERR(clk)))
+		return;
+
+	ret = of_clk_add_provider(np, of_clk_src_simple_get, clk);
+	if (WARN_ON(ret))
+		return;
+}
+
+struct zynq_periph_clk {
+	struct clk_hw		hw;
+	struct clk_onecell_data	onecell_data;
+	struct clk		*gates[2];
+	void __iomem		*clk_ctrl;
+	spinlock_t		clkact_lock;
+};
+
+#define to_zynq_periph_clk(hw)	container_of(hw, struct zynq_periph_clk, hw)
+
+static const u8 periph_clk_parent_map[] = {
+	0, 0, 1, 2
+};
+#define PERIPH_CLK_CTRL_SRC(x)	(periph_clk_parent_map[((x) & 0x30) >> 4])
+#define PERIPH_CLK_CTRL_DIV(x)	(((x) & 0x3F00) >> 8)
+
+static unsigned long zynq_periph_recalc_rate(struct clk_hw *hw,
+					     unsigned long parent_rate)
+{
+	struct zynq_periph_clk *periph = to_zynq_periph_clk(hw);
+	return parent_rate / PERIPH_CLK_CTRL_DIV(ioread32(periph->clk_ctrl));
+}
+
+static u8 zynq_periph_get_parent(struct clk_hw *hw)
+{
+	struct zynq_periph_clk *periph = to_zynq_periph_clk(hw);
+	return PERIPH_CLK_CTRL_SRC(ioread32(periph->clk_ctrl));
+}
+
+static const struct clk_ops zynq_periph_clk_ops = {
+	.recalc_rate	= zynq_periph_recalc_rate,
+	.get_parent	= zynq_periph_get_parent,
+};
+
+static void __init zynq_periph_clk_setup(struct device_node *np)
+{
+	struct zynq_periph_clk *periph;
+	const char *parent_names[3];
+	struct clk_init_data init;
+	int clk_num = 0, err;
+	const char *name;
+	struct clk *clk;
+	u32 reg;
+	int i;
+
+	err = of_property_read_u32(np, "reg", &reg);
+	if (WARN_ON(err))
+		return;
+
+	periph = kzalloc(sizeof(*periph), GFP_KERNEL);
+	if (WARN_ON(!periph))
+		return;
+
+	periph->clk_ctrl = slcr_base + reg;
+	spin_lock_init(&periph->clkact_lock);
+
+	init.name = np->name;
+	init.ops = &zynq_periph_clk_ops;
+	for (i = 0; i < ARRAY_SIZE(parent_names); i++)
+		parent_names[i] = of_clk_get_parent_name(np, i);
+	init.parent_names = parent_names;
+	init.num_parents = ARRAY_SIZE(parent_names);
+
+	periph->hw.init = &init;
+
+	clk = clk_register(NULL, &periph->hw);
+	if (WARN_ON(IS_ERR(clk)))
+		return;
+
+	err = of_clk_add_provider(np, of_clk_src_simple_get, clk);
+	if (WARN_ON(err))
+		return;
+
+	err = of_property_read_string_index(np, "clock-output-names", 0,
+					    &name);
+	if (WARN_ON(err))
+		return;
+
+	periph->gates[0] = clk_register_gate(NULL, name, np->name, 0,
+					     periph->clk_ctrl, 0, 0,
+					     &periph->clkact_lock);
+	if (WARN_ON(IS_ERR(periph->gates[0])))
+		return;
+	clk_num++;
+
+	/* some periph clks have 2 downstream gates */
+	err = of_property_read_string_index(np, "clock-output-names", 1,
+					    &name);
+	if (err != -ENODATA) {
+		periph->gates[1] = clk_register_gate(NULL, name, np->name, 0,
+						     periph->clk_ctrl, 1, 0,
+						     &periph->clkact_lock);
+		if (WARN_ON(IS_ERR(periph->gates[1])))
+			return;
+		clk_num++;
+	}
+
+	periph->onecell_data.clks = periph->gates;
+	periph->onecell_data.clk_num = clk_num;
+
+	err = of_clk_add_provider(np, of_clk_src_onecell_get,
+				  &periph->onecell_data);
+	if (WARN_ON(err))
+		return;
+}
+
+/* CPU Clock domain is modelled as a mux with 4 children subclks, whose
+ * derivative rates depend on CLK_621_TRUE
+ */
+
+struct zynq_cpu_clk {
+	struct clk_hw		hw;
+	struct clk_onecell_data	onecell_data;
+	struct clk		*subclks[4];
+	void __iomem		*clk_ctrl;
+	spinlock_t		clkact_lock;
+};
+
+#define to_zynq_cpu_clk(hw)	container_of(hw, struct zynq_cpu_clk, hw)
+
+static const u8 zynq_cpu_clk_parent_map[] = {
+	1, 1, 2, 0
+};
+#define CPU_CLK_SRCSEL(x)	(zynq_cpu_clk_parent_map[(((x) & 0x30) >> 4)])
+#define CPU_CLK_CTRL_DIV(x)	(((x) & 0x3F00) >> 8)
+
+static u8 zynq_cpu_clk_get_parent(struct clk_hw *hw)
+{
+	struct zynq_cpu_clk *cpuclk = to_zynq_cpu_clk(hw);
+	return CPU_CLK_SRCSEL(ioread32(cpuclk->clk_ctrl));
+}
+
+static unsigned long zynq_cpu_clk_recalc_rate(struct clk_hw *hw,
+					      unsigned long parent_rate)
+{
+	struct zynq_cpu_clk *cpuclk = to_zynq_cpu_clk(hw);
+	return parent_rate / CPU_CLK_CTRL_DIV(ioread32(cpuclk->clk_ctrl));
+}
+
+static const struct clk_ops zynq_cpu_clk_ops = {
+	.get_parent	= zynq_cpu_clk_get_parent,
+	.recalc_rate	= zynq_cpu_clk_recalc_rate,
+};
+
+struct zynq_cpu_subclk {
+	struct clk_hw	hw;
+	void __iomem	*clk_621;
+	enum {
+		CPU_SUBCLK_6X4X,
+		CPU_SUBCLK_3X2X,
+		CPU_SUBCLK_2X,
+		CPU_SUBCLK_1X,
+	} which;
+};
+
+#define CLK_621_TRUE(x)	((x) & 1)
+
+#define to_zynq_cpu_subclk(hw)	container_of(hw, struct zynq_cpu_subclk, hw);
+
+static unsigned long zynq_cpu_subclk_recalc_rate(struct clk_hw *hw,
+						 unsigned long parent_rate)
+{
+	unsigned long uninitialized_var(rate);
+	struct zynq_cpu_subclk *subclk;
+	bool is_621;
+
+	subclk = to_zynq_cpu_subclk(hw)
+	is_621 = CLK_621_TRUE(ioread32(subclk->clk_621));
+
+	switch (subclk->which) {
+	case CPU_SUBCLK_6X4X:
+		rate = parent_rate;
+		break;
+	case CPU_SUBCLK_3X2X:
+		rate = parent_rate / 2;
+		break;
+	case CPU_SUBCLK_2X:
+		rate = parent_rate / (is_621 ? 3 : 2);
+		break;
+	case CPU_SUBCLK_1X:
+		rate = parent_rate / (is_621 ? 6 : 4);
+		break;
+	};
+
+	return rate;
+}
+
+static const struct clk_ops zynq_cpu_subclk_ops = {
+	.recalc_rate	= zynq_cpu_subclk_recalc_rate,
+};
+
+static struct clk *zynq_cpu_subclk_setup(struct device_node *np, u8 which,
+					 void __iomem *clk_621)
+{
+	struct zynq_cpu_subclk *subclk;
+	struct clk_init_data init;
+	struct clk *clk;
+	int err;
+
+	err = of_property_read_string_index(np, "clock-output-names",
+					    which, &init.name);
+	if (WARN_ON(err))
+		goto err_read_output_name;
+
+	subclk = kzalloc(sizeof(*subclk), GFP_KERNEL);
+	if (!subclk)
+		goto err_subclk_alloc;
+
+	subclk->clk_621 = clk_621;
+	subclk->which = which;
+
+	init.ops = &zynq_cpu_subclk_ops;
+	init.parent_names = &np->name;
+	init.num_parents = 1;
+
+	subclk->hw.init = &init;
+
+	clk = clk_register(NULL, &subclk->hw);
+	if (WARN_ON(IS_ERR(clk)))
+		goto err_clk_register;
+
+	return clk;
+
+err_clk_register:
+	kfree(subclk);
+err_subclk_alloc:
+err_read_output_name:
+	return ERR_PTR(-EINVAL);
+}
+
+static void __init zynq_cpu_clk_setup(struct device_node *np)
+{
+	struct zynq_cpu_clk *cpuclk;
+	const char *parent_names[3];
+	struct clk_init_data init;
+	void __iomem *clk_621;
+	struct clk *clk;
+	u32 reg[2];
+	int err;
+	int i;
+
+	err = of_property_read_u32_array(np, "reg", reg, ARRAY_SIZE(reg));
+	if (WARN_ON(err))
+		return;
+
+	cpuclk = kzalloc(sizeof(*cpuclk), GFP_KERNEL);
+	if (WARN_ON(!cpuclk))
+		return;
+
+	cpuclk->clk_ctrl = slcr_base + reg[0];
+	clk_621 = slcr_base + reg[1];
+	spin_lock_init(&cpuclk->clkact_lock);
+
+	init.name = np->name;
+	init.ops = &zynq_cpu_clk_ops;
+	for (i = 0; i < ARRAY_SIZE(parent_names); i++)
+		parent_names[i] = of_clk_get_parent_name(np, i);
+	init.parent_names = parent_names;
+	init.num_parents = ARRAY_SIZE(parent_names);
+
+	cpuclk->hw.init = &init;
+
+	clk = clk_register(NULL, &cpuclk->hw);
+	if (WARN_ON(IS_ERR(clk)))
+		return;
+
+	err = of_clk_add_provider(np, of_clk_src_simple_get, clk);
+	if (WARN_ON(err))
+		return;
+
+	for (i = 0; i < 4; i++) {
+		cpuclk->subclks[i] = zynq_cpu_subclk_setup(np, i, clk_621);
+		if (WARN_ON(IS_ERR(cpuclk->subclks[i])))
+			return;
+	}
+
+	cpuclk->onecell_data.clks = cpuclk->subclks;
+	cpuclk->onecell_data.clk_num = i;
+
+	err = of_clk_add_provider(np, of_clk_src_onecell_get,
+				  &cpuclk->onecell_data);
+	if (WARN_ON(err))
+		return;
+}
+
+static const __initconst struct of_device_id zynq_clk_match[] = {
+	{ .compatible = "fixed-clock", .data = of_fixed_clk_setup, },
+	{ .compatible = "xlnx,zynq-pll", .data = zynq_pll_clk_setup, },
+	{ .compatible = "xlnx,zynq-periph-clock",
+		.data = zynq_periph_clk_setup, },
+	{ .compatible = "xlnx,zynq-cpu-clock", .data = zynq_cpu_clk_setup, },
+	{}
+};
+
+void __init xilinx_zynq_clocks_init(void __iomem *slcr)
+{
+	slcr_base = slcr;
+	of_clk_init(zynq_clk_match);
+}
diff --git a/drivers/clk/ux500/u8500_clk.c b/drivers/clk/ux500/u8500_clk.c
index 7d0e025..6b889a0 100644
--- a/drivers/clk/ux500/u8500_clk.c
+++ b/drivers/clk/ux500/u8500_clk.c
@@ -12,7 +12,7 @@
 #include <linux/clk-provider.h>
 #include <linux/mfd/dbx500-prcmu.h>
 #include <linux/platform_data/clk-ux500.h>
-
+#include <mach/db8500-regs.h>
 #include "clk.h"
 
 void u8500_clk_init(void)
@@ -160,12 +160,6 @@
 	clk = clk_reg_prcmu_gate("uiccclk", NULL, PRCMU_UICCCLK, CLK_IS_ROOT);
 	clk_register_clkdev(clk, NULL, "uicc");
 
-	/*
-	 * FIXME: The MTU clocks might need some kind of "parent muxed join"
-	 * and these have no K-clocks. For now, we ignore the missing
-	 * connection to the corresponding P-clocks, p6_mtu0_clk and
-	 * p6_mtu1_clk. Instead timclk is used which is the valid parent.
-	 */
 	clk = clk_reg_prcmu_gate("timclk", NULL, PRCMU_TIMCLK, CLK_IS_ROOT);
 	clk_register_clkdev(clk, NULL, "mtu0");
 	clk_register_clkdev(clk, NULL, "mtu1");
@@ -405,8 +399,11 @@
 
 	clk = clk_reg_prcc_pclk("p6_pclk6", "per6clk", U8500_CLKRST6_BASE,
 				BIT(6), 0);
+	clk_register_clkdev(clk, "apb_pclk", "mtu0");
+
 	clk = clk_reg_prcc_pclk("p6_pclk7", "per6clk", U8500_CLKRST6_BASE,
 				BIT(7), 0);
+	clk_register_clkdev(clk, "apb_pclk", "mtu1");
 
 	/* PRCC K-clocks
 	 *
diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index a098573..7fdcbd3 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -25,6 +25,21 @@
 config SUNXI_TIMER
 	bool
 
+config CLKSRC_NOMADIK_MTU
+	bool
+	depends on (ARCH_NOMADIK || ARCH_U8500)
+	select CLKSRC_MMIO
+	help
+	  Support for Multi Timer Unit. MTU provides access
+	  to multiple interrupt generating programmable
+	  32-bit free running decrementing counters.
+
+config CLKSRC_NOMADIK_MTU_SCHED_CLOCK
+	bool
+	depends on CLKSRC_NOMADIK_MTU
+	help
+	  Use the Multi Timer Unit as the sched_clock.
+
 config CLKSRC_DBX500_PRCMU
 	bool "Clocksource PRCMU Timer"
 	depends on UX500_SOC_DB8500
@@ -34,7 +49,7 @@
 
 config CLKSRC_DBX500_PRCMU_SCHED_CLOCK
 	bool "Clocksource PRCMU Timer sched_clock"
-	depends on (CLKSRC_DBX500_PRCMU && !NOMADIK_MTU_SCHED_CLOCK)
+	depends on (CLKSRC_DBX500_PRCMU && !CLKSRC_NOMADIK_MTU_SCHED_CLOCK)
 	default y
 	help
 	  Use the always on PRCMU Timer as sched_clock
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
index 36f06de..f93453d 100644
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -11,6 +11,7 @@
 obj-$(CONFIG_CLKSRC_MMIO)	+= mmio.o
 obj-$(CONFIG_DW_APB_TIMER)	+= dw_apb_timer.o
 obj-$(CONFIG_DW_APB_TIMER_OF)	+= dw_apb_timer_of.o
+obj-$(CONFIG_CLKSRC_NOMADIK_MTU)	+= nomadik-mtu.o
 obj-$(CONFIG_CLKSRC_DBX500_PRCMU)	+= clksrc-dbx500-prcmu.o
 obj-$(CONFIG_ARMADA_370_XP_TIMER)	+= time-armada-370-xp.o
 obj-$(CONFIG_ARCH_BCM2835)	+= bcm2835_timer.o
diff --git a/arch/arm/plat-nomadik/timer.c b/drivers/clocksource/nomadik-mtu.c
similarity index 92%
rename from arch/arm/plat-nomadik/timer.c
rename to drivers/clocksource/nomadik-mtu.c
index 9222e55..8914c3c 100644
--- a/arch/arm/plat-nomadik/timer.c
+++ b/drivers/clocksource/nomadik-mtu.c
@@ -1,6 +1,4 @@
 /*
- *  linux/arch/arm/plat-nomadik/timer.c
- *
  * Copyright (C) 2008 STMicroelectronics
  * Copyright (C) 2010 Alessandro Rubini
  * Copyright (C) 2010 Linus Walleij for ST-Ericsson
@@ -14,9 +12,11 @@
 #include <linux/irq.h>
 #include <linux/io.h>
 #include <linux/clockchips.h>
+#include <linux/clocksource.h>
 #include <linux/clk.h>
 #include <linux/jiffies.h>
 #include <linux/err.h>
+#include <linux/platform_data/clocksource-nomadik-mtu.h>
 #include <asm/mach/time.h>
 #include <asm/sched_clock.h>
 
@@ -174,12 +174,18 @@
 	       mtu_base + MTU_CR(0));
 }
 
-void __init nmdk_timer_init(void __iomem *base)
+void __init nmdk_timer_init(void __iomem *base, int irq)
 {
 	unsigned long rate;
-	struct clk *clk0;
+	struct clk *clk0, *pclk0;
 
 	mtu_base = base;
+
+	pclk0 = clk_get_sys("mtu0", "apb_pclk");
+	BUG_ON(IS_ERR(pclk0));
+	BUG_ON(clk_prepare(pclk0) < 0);
+	BUG_ON(clk_enable(pclk0) < 0);
+
 	clk0 = clk_get_sys("mtu0", NULL);
 	BUG_ON(IS_ERR(clk0));
 	BUG_ON(clk_prepare(clk0) < 0);
@@ -201,7 +207,8 @@
 		clk_prescale = MTU_CRn_PRESCALE_1;
 	}
 
-	nmdk_cycle = (rate + HZ/2) / HZ;
+	/* Cycles for periodic mode */
+	nmdk_cycle = DIV_ROUND_CLOSEST(rate, HZ);
 
 
 	/* Timer 0 is the free running clocksource */
@@ -217,7 +224,7 @@
 #endif
 
 	/* Timer 1 is used for events, register irq and clockevents */
-	setup_irq(IRQ_MTU0, &nmdk_timer_irq);
+	setup_irq(irq, &nmdk_timer_irq);
 	nmdk_clkevt.cpumask = cpumask_of(0);
 	clockevents_config_and_register(&nmdk_clkevt, rate, 2, 0xffffffffU);
 }
diff --git a/drivers/crypto/omap-aes.c b/drivers/crypto/omap-aes.c
index 649a146..e66e8ee 100644
--- a/drivers/crypto/omap-aes.c
+++ b/drivers/crypto/omap-aes.c
@@ -29,7 +29,7 @@
 #include <crypto/scatterwalk.h>
 #include <crypto/aes.h>
 
-#include <plat-omap/dma-omap.h>
+#include <linux/omap-dma.h>
 
 /* OMAP TRM gives bitfields as start:end, where start is the higher bit
    number. For example 7:0 */
diff --git a/drivers/crypto/omap-sham.c b/drivers/crypto/omap-sham.c
index d76fe06..1d75e6f 100644
--- a/drivers/crypto/omap-sham.c
+++ b/drivers/crypto/omap-sham.c
@@ -37,7 +37,7 @@
 #include <crypto/hash.h>
 #include <crypto/internal/hash.h>
 
-#include <plat-omap/dma-omap.h>
+#include <linux/omap-dma.h>
 #include <mach/irqs.h>
 
 #define SHA_REG_DIGEST(x)		(0x00 + ((x) * 0x04))
diff --git a/drivers/crypto/ux500/cryp/cryp_core.c b/drivers/crypto/ux500/cryp/cryp_core.c
index bc615cc..8bc5fef 100644
--- a/drivers/crypto/ux500/cryp/cryp_core.c
+++ b/drivers/crypto/ux500/cryp/cryp_core.c
@@ -23,6 +23,7 @@
 #include <linux/platform_device.h>
 #include <linux/regulator/consumer.h>
 #include <linux/semaphore.h>
+#include <linux/platform_data/dma-ste-dma40.h>
 
 #include <crypto/aes.h>
 #include <crypto/algapi.h>
@@ -30,8 +31,6 @@
 #include <crypto/des.h>
 #include <crypto/scatterwalk.h>
 
-#include <plat/ste_dma40.h>
-
 #include <linux/platform_data/crypto-ux500.h>
 #include <mach/hardware.h>
 
diff --git a/drivers/dma/omap-dma.c b/drivers/dma/omap-dma.c
index 7d35c23..5a31264 100644
--- a/drivers/dma/omap-dma.c
+++ b/drivers/dma/omap-dma.c
@@ -19,8 +19,6 @@
 
 #include "virt-dma.h"
 
-#include <plat-omap/dma-omap.h>
-
 struct omap_dmadev {
 	struct dma_device ddev;
 	spinlock_t lock;
diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c
index ae55091..23c5573 100644
--- a/drivers/dma/ste_dma40.c
+++ b/drivers/dma/ste_dma40.c
@@ -19,8 +19,7 @@
 #include <linux/err.h>
 #include <linux/amba/bus.h>
 #include <linux/regulator/consumer.h>
-
-#include <plat/ste_dma40.h>
+#include <linux/platform_data/dma-ste-dma40.h>
 
 #include "dmaengine.h"
 #include "ste_dma40_ll.h"
diff --git a/drivers/dma/ste_dma40_ll.c b/drivers/dma/ste_dma40_ll.c
index cad9e1d..851ad56 100644
--- a/drivers/dma/ste_dma40_ll.c
+++ b/drivers/dma/ste_dma40_ll.c
@@ -6,7 +6,7 @@
  */
 
 #include <linux/kernel.h>
-#include <plat/ste_dma40.h>
+#include <linux/platform_data/dma-ste-dma40.h>
 
 #include "ste_dma40_ll.h"
 
diff --git a/drivers/eisa/eisa.ids b/drivers/eisa/eisa.ids
index 6cbb7a5..2d864b4 100644
--- a/drivers/eisa/eisa.ids
+++ b/drivers/eisa/eisa.ids
@@ -985,8 +985,8 @@
 ISABD02 "Racal-Interlan NI5210/8 Ethernet"
 ISABD03 "Racal-Interlan NI5210/16 Ethernet"
 ISABE00 "Qua Tech PXB-1608 Parallel Expansion Board"
-ISABE01 "Qua Tech ES-100 8 Channel Asyncronous"
-ISABE02 "Qua Tech QS-100M 4 Channel Asyncronous"
+ISABE01 "Qua Tech ES-100 8 Channel Asynchronous"
+ISABE02 "Qua Tech QS-100M 4 Channel Asynchronous"
 ISABE03 "Qua Tech MXI-100 IEEE 488 GPIB"
 ISABE04 "Qua Tech DS-201 Dual Channel RS-422"
 ISABE05 "Qua Tech PXB-721 Parallel Expansion"
diff --git a/drivers/firewire/init_ohci1394_dma.c b/drivers/firewire/init_ohci1394_dma.c
index a9a347a..2cc89ce 100644
--- a/drivers/firewire/init_ohci1394_dma.c
+++ b/drivers/firewire/init_ohci1394_dma.c
@@ -149,10 +149,10 @@
 	reg_write(ohci, OHCI1394_IsoXmitIntMaskClear, 0xffffffff);
 	reg_write(ohci, OHCI1394_IsoXmitIntEventClear, 0xffffffff);
 
-	/* Accept asyncronous transfer requests from all nodes for now */
+	/* Accept asynchronous transfer requests from all nodes for now */
 	reg_write(ohci, OHCI1394_AsReqFilterHiSet, 0x80000000);
 
-	/* Specify asyncronous transfer retries */
+	/* Specify asynchronous transfer retries */
 	reg_write(ohci, OHCI1394_ATRetries,
 		  OHCI1394_MAX_AT_REQ_RETRIES |
 		  (OHCI1394_MAX_AT_RESP_RETRIES<<4) |
diff --git a/drivers/firewire/net.c b/drivers/firewire/net.c
index 08c6749..e7a711f5 100644
--- a/drivers/firewire/net.c
+++ b/drivers/firewire/net.c
@@ -828,7 +828,6 @@
 {
 	struct fwnet_device *dev;
 	struct fw_iso_packet packet;
-	struct fw_card *card;
 	__be16 *hdr_ptr;
 	__be32 *buf_ptr;
 	int retval;
@@ -840,7 +839,6 @@
 	unsigned long flags;
 
 	dev = data;
-	card = dev->card;
 	hdr_ptr = header;
 	length = be16_to_cpup(hdr_ptr);
 
@@ -861,8 +859,8 @@
 	if (specifier_id == IANA_SPECIFIER_ID && ver == RFC2734_SW_VERSION) {
 		buf_ptr += 2;
 		length -= IEEE1394_GASP_HDR_SIZE;
-		fwnet_incoming_packet(dev, buf_ptr, length,
-				      source_node_id, -1, true);
+		fwnet_incoming_packet(dev, buf_ptr, length, source_node_id,
+				      context->card->generation, true);
 	}
 
 	packet.payload_length = dev->rcv_buffer_size;
@@ -958,7 +956,12 @@
 			break;
 		}
 
-		skb_pull(skb, ptask->max_payload);
+		if (ptask->dest_node == IEEE1394_ALL_NODES) {
+			skb_pull(skb,
+				 ptask->max_payload + IEEE1394_GASP_HDR_SIZE);
+		} else {
+			skb_pull(skb, ptask->max_payload);
+		}
 		if (ptask->outstanding_pkts > 1) {
 			fwnet_make_sf_hdr(&ptask->hdr, RFC2374_HDR_INTFRAG,
 					  dg_size, fg_off, datagram_label);
@@ -1062,7 +1065,7 @@
 		smp_rmb();
 		node_id = dev->card->node_id;
 
-		p = skb_push(ptask->skb, 8);
+		p = skb_push(ptask->skb, IEEE1394_GASP_HDR_SIZE);
 		put_unaligned_be32(node_id << 16 | IANA_SPECIFIER_ID >> 8, p);
 		put_unaligned_be32((IANA_SPECIFIER_ID & 0xff) << 24
 						| RFC2734_SW_VERSION, &p[4]);
diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c
index f25610b..6ce6e07 100644
--- a/drivers/firewire/ohci.c
+++ b/drivers/firewire/ohci.c
@@ -1281,7 +1281,7 @@
 	d[0].res_count = cpu_to_le16(packet->timestamp);
 
 	/*
-	 * The DMA format for asyncronous link packets is different
+	 * The DMA format for asynchronous link packets is different
 	 * from the IEEE1394 layout, so shift the fields around
 	 * accordingly.
 	 */
diff --git a/drivers/firewire/sbp2.c b/drivers/firewire/sbp2.c
index bb1b392..1162d6b 100644
--- a/drivers/firewire/sbp2.c
+++ b/drivers/firewire/sbp2.c
@@ -1546,8 +1546,6 @@
 	struct sbp2_logical_unit *lu = sdev->hostdata;
 
 	sdev->use_10_for_rw = 1;
-	sdev->no_report_opcodes = 1;
-	sdev->no_write_same = 1;
 
 	if (sbp2_param_exclusive_login)
 		sdev->manage_start_stop = 1;
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 14a6c29..bf892bd 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -171,7 +171,7 @@
 
 config GPIO_MVEBU
 	def_bool y
-	depends on ARCH_MVEBU
+	depends on PLAT_ORION
 	select GPIO_GENERIC
 	select GENERIC_IRQ_CHIP
 
@@ -504,7 +504,7 @@
 	help
 	  This option enables support for N GPIOs found on Avionic Design
 	  I2C GPIO expanders. The register space will be extended by powers
-	  of two, so the controller will need to accomodate for that. For
+	  of two, so the controller will need to accommodate for that. For
 	  example: if a controller provides 48 pins, 6 registers will be
 	  enough to represent all pins, but the driver will assume a
 	  register layout for 64 pins (8 registers).
diff --git a/drivers/gpio/gpio-samsung.c b/drivers/gpio/gpio-samsung.c
index a006f0d..01f7fe9 100644
--- a/drivers/gpio/gpio-samsung.c
+++ b/drivers/gpio/gpio-samsung.c
@@ -42,12 +42,6 @@
 #include <plat/gpio-fns.h>
 #include <plat/pm.h>
 
-#ifndef DEBUG_GPIO
-#define gpio_dbg(x...) do { } while (0)
-#else
-#define gpio_dbg(x...) printk(KERN_DEBUG x)
-#endif
-
 int samsung_gpio_setpull_updown(struct samsung_gpio_chip *chip,
 				unsigned int off, samsung_gpio_pull_t pull)
 {
@@ -596,10 +590,13 @@
 	unsigned long con;
 
 	con = __raw_readl(base + GPIOCON_OFF);
-	con &= ~(0xf << con_4bit_shift(offset));
+	if (ourchip->bitmap_gpio_int & BIT(offset))
+		con |= 0xf << con_4bit_shift(offset);
+	else
+		con &= ~(0xf << con_4bit_shift(offset));
 	__raw_writel(con, base + GPIOCON_OFF);
 
-	gpio_dbg("%s: %p: CON now %08lx\n", __func__, base, con);
+	pr_debug("%s: %p: CON now %08lx\n", __func__, base, con);
 
 	return 0;
 }
@@ -627,7 +624,7 @@
 	__raw_writel(con, base + GPIOCON_OFF);
 	__raw_writel(dat, base + GPIODAT_OFF);
 
-	gpio_dbg("%s: %p: CON %08lx, DAT %08lx\n", __func__, base, con, dat);
+	pr_debug("%s: %p: CON %08lx, DAT %08lx\n", __func__, base, con, dat);
 
 	return 0;
 }
@@ -671,7 +668,7 @@
 	con &= ~(0xf << con_4bit_shift(offset));
 	__raw_writel(con, regcon);
 
-	gpio_dbg("%s: %p: CON %08lx\n", __func__, base, con);
+	pr_debug("%s: %p: CON %08lx\n", __func__, base, con);
 
 	return 0;
 }
@@ -706,7 +703,7 @@
 	__raw_writel(con, regcon);
 	__raw_writel(dat, base + GPIODAT_OFF);
 
-	gpio_dbg("%s: %p: CON %08lx, DAT %08lx\n", __func__, base, con, dat);
+	pr_debug("%s: %p: CON %08lx, DAT %08lx\n", __func__, base, con, dat);
 
 	return 0;
 }
@@ -926,10 +923,10 @@
 #ifdef CONFIG_PM
 	if (chip->pm != NULL) {
 		if (!chip->pm->save || !chip->pm->resume)
-			printk(KERN_ERR "gpio: %s has missing PM functions\n",
+			pr_err("gpio: %s has missing PM functions\n",
 			       gc->label);
 	} else
-		printk(KERN_ERR "gpio: %s has no PM function\n", gc->label);
+		pr_err("gpio: %s has no PM function\n", gc->label);
 #endif
 
 	/* gpiochip_add() prints own failure message on error. */
@@ -1081,6 +1078,8 @@
 		if ((base != NULL) && (chip->base == NULL))
 			chip->base = base + ((i) * 0x20);
 
+		chip->bitmap_gpio_int = 0;
+
 		samsung_gpiolib_add(chip);
 	}
 }
@@ -2797,27 +2796,6 @@
 	int group = 0;
 	void __iomem *gpx_base;
 
-#ifdef CONFIG_PINCTRL_SAMSUNG
-		/*
-		 * This gpio driver includes support for device tree support and
-		 * there are platforms using it. In order to maintain
-		 * compatibility with those platforms, and to allow non-dt
-		 * Exynos4210 platforms to use this gpiolib support, a check
-		 * is added to find out if there is a active pin-controller
-		 * driver support available. If it is available, this gpiolib
-		 * support is ignored and the gpiolib support available in
-		 * pin-controller driver is used. This is a temporary check and
-		 * will go away when all of the Exynos4210 platforms have
-		 * switched to using device tree and the pin-ctrl driver.
-		 */
-		struct device_node *pctrl_np;
-		const char *pctrl_compat = "samsung,pinctrl-exynos4210";
-		pctrl_np = of_find_compatible_node(NULL, NULL, pctrl_compat);
-		if (pctrl_np)
-			if (of_device_is_available(pctrl_np))
-				return;
-#endif
-
 	/* gpio part1 */
 	gpio_base1 = ioremap(EXYNOS4_PA_GPIO1, SZ_4K);
 	if (gpio_base1 == NULL) {
@@ -3032,6 +3010,28 @@
 	int i, nr_chips;
 	int group = 0;
 
+#ifdef CONFIG_PINCTRL_SAMSUNG
+	/*
+	* This gpio driver includes support for device tree support and there
+	* are platforms using it. In order to maintain compatibility with those
+	* platforms, and to allow non-dt Exynos4210 platforms to use this
+	* gpiolib support, a check is added to find out if there is a active
+	* pin-controller driver support available. If it is available, this
+	* gpiolib support is ignored and the gpiolib support available in
+	* pin-controller driver is used. This is a temporary check and will go
+	* away when all of the Exynos4210 platforms have switched to using
+	* device tree and the pin-ctrl driver.
+	*/
+	struct device_node *pctrl_np;
+	static const struct of_device_id exynos_pinctrl_ids[] = {
+		{ .compatible = "samsung,pinctrl-exynos4210", },
+		{ .compatible = "samsung,pinctrl-exynos4x12", },
+	};
+	for_each_matching_node(pctrl_np, exynos_pinctrl_ids)
+		if (pctrl_np && of_device_is_available(pctrl_np))
+			return -ENODEV;
+#endif
+
 	samsung_gpiolib_set_cfg(samsung_gpio_cfgs, ARRAY_SIZE(samsung_gpio_cfgs));
 
 	if (soc_is_s3c24xx()) {
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c
index 219942c..5d1d21a 100644
--- a/drivers/gpu/drm/radeon/evergreen.c
+++ b/drivers/gpu/drm/radeon/evergreen.c
@@ -1650,7 +1650,7 @@
 	ring->wptr = 0;
 	WREG32(CP_RB_WPTR, ring->wptr);
 
-	/* set the wb address wether it's enabled or not */
+	/* set the wb address whether it's enabled or not */
 	WREG32(CP_RB_RPTR_ADDR,
 	       ((rdev->wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET) & 0xFFFFFFFC));
 	WREG32(CP_RB_RPTR_ADDR_HI, upper_32_bits(rdev->wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET) & 0xFF);
diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c
index 81e6a56..cda01f8 100644
--- a/drivers/gpu/drm/radeon/ni.c
+++ b/drivers/gpu/drm/radeon/ni.c
@@ -1059,7 +1059,7 @@
 
 	WREG32(CP_DEBUG, (1 << 27));
 
-	/* set the wb address wether it's enabled or not */
+	/* set the wb address whether it's enabled or not */
 	WREG32(SCRATCH_ADDR, ((rdev->wb.gpu_addr + RADEON_WB_SCRATCH_OFFSET) >> 8) & 0xFFFFFFFF);
 	WREG32(SCRATCH_UMSK, 0xff);
 
@@ -1076,7 +1076,7 @@
 #endif
 		WREG32(cp_rb_cntl[i], rb_cntl);
 
-		/* set the wb address wether it's enabled or not */
+		/* set the wb address whether it's enabled or not */
 		addr = rdev->wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET;
 		WREG32(cp_rb_rptr_addr[i], addr & 0xFFFFFFFC);
 		WREG32(cp_rb_rptr_addr_hi[i], upper_32_bits(addr) & 0xFF);
diff --git a/drivers/gpu/drm/radeon/radeon_ring.c b/drivers/gpu/drm/radeon/radeon_ring.c
index 47634f2..ebd6956 100644
--- a/drivers/gpu/drm/radeon/radeon_ring.c
+++ b/drivers/gpu/drm/radeon/radeon_ring.c
@@ -459,7 +459,7 @@
  *
  * @ring: radeon_ring structure holding ring information
  *
- * Reset the driver's copy of the wtpr (all asics).
+ * Reset the driver's copy of the wptr (all asics).
  */
 void radeon_ring_undo(struct radeon_ring *ring)
 {
@@ -503,7 +503,7 @@
 }
 
 /**
- * radeon_ring_force_activity - update lockup variables
+ * radeon_ring_lockup_update - update lockup variables
  *
  * @ring: radeon_ring structure holding ring information
  *
diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c
index 4422d63..010156d 100644
--- a/drivers/gpu/drm/radeon/si.c
+++ b/drivers/gpu/drm/radeon/si.c
@@ -2007,7 +2007,7 @@
 	ring->wptr = 0;
 	WREG32(CP_RB0_WPTR, ring->wptr);
 
-	/* set the wb address wether it's enabled or not */
+	/* set the wb address whether it's enabled or not */
 	WREG32(CP_RB0_RPTR_ADDR, (rdev->wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET) & 0xFFFFFFFC);
 	WREG32(CP_RB0_RPTR_ADDR_HI, upper_32_bits(rdev->wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET) & 0xFF);
 
@@ -2040,7 +2040,7 @@
 	ring->wptr = 0;
 	WREG32(CP_RB1_WPTR, ring->wptr);
 
-	/* set the wb address wether it's enabled or not */
+	/* set the wb address whether it's enabled or not */
 	WREG32(CP_RB1_RPTR_ADDR, (rdev->wb.gpu_addr + RADEON_WB_CP1_RPTR_OFFSET) & 0xFFFFFFFC);
 	WREG32(CP_RB1_RPTR_ADDR_HI, upper_32_bits(rdev->wb.gpu_addr + RADEON_WB_CP1_RPTR_OFFSET) & 0xFF);
 
@@ -2066,7 +2066,7 @@
 	ring->wptr = 0;
 	WREG32(CP_RB2_WPTR, ring->wptr);
 
-	/* set the wb address wether it's enabled or not */
+	/* set the wb address whether it's enabled or not */
 	WREG32(CP_RB2_RPTR_ADDR, (rdev->wb.gpu_addr + RADEON_WB_CP2_RPTR_OFFSET) & 0xFFFFFFFC);
 	WREG32(CP_RB2_RPTR_ADDR_HI, upper_32_bits(rdev->wb.gpu_addr + RADEON_WB_CP2_RPTR_OFFSET) & 0xFF);
 
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
index 1630150..e7d6a13 100644
--- a/drivers/hid/Kconfig
+++ b/drivers/hid/Kconfig
@@ -265,6 +265,15 @@
 	---help---
 	Support for Gyration remote control.
 
+config HID_ICADE
+	tristate "ION iCade arcade controller"
+	depends on BT_HIDP
+	---help---
+	Support for the ION iCade arcade controller to work as a joystick.
+
+	To compile this driver as a module, choose M here: the
+	module will be called hid-icade.
+
 config HID_TWINHAN
 	tristate "Twinhan IR remote control"
 	depends on USB_HID
@@ -728,4 +737,6 @@
 
 source "drivers/hid/usbhid/Kconfig"
 
+source "drivers/hid/i2c-hid/Kconfig"
+
 endmenu
diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile
index cef68ca..b622157 100644
--- a/drivers/hid/Makefile
+++ b/drivers/hid/Makefile
@@ -52,6 +52,7 @@
 obj-$(CONFIG_HID_HOLTEK)	+= hid-holtek-kbd.o
 obj-$(CONFIG_HID_HOLTEK)	+= hid-holtekff.o
 obj-$(CONFIG_HID_HYPERV_MOUSE)	+= hid-hyperv.o
+obj-$(CONFIG_HID_ICADE)		+= hid-icade.o
 obj-$(CONFIG_HID_KENSINGTON)	+= hid-kensington.o
 obj-$(CONFIG_HID_KEYTOUCH)	+= hid-keytouch.o
 obj-$(CONFIG_HID_KYE)		+= hid-kye.o
@@ -93,8 +94,8 @@
 obj-$(CONFIG_HID_PS3REMOTE)	+= hid-ps3remote.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 \
-	hid-roccat-savu.o
+	hid-roccat-koneplus.o hid-roccat-kovaplus.o hid-roccat-lua.o \
+	hid-roccat-pyra.o hid-roccat-savu.o
 obj-$(CONFIG_HID_SAITEK)	+= hid-saitek.o
 obj-$(CONFIG_HID_SAMSUNG)	+= hid-samsung.o
 obj-$(CONFIG_HID_SMARTJOYPLUS)	+= hid-sjoy.o
@@ -118,3 +119,4 @@
 obj-$(CONFIG_USB_MOUSE)		+= usbhid/
 obj-$(CONFIG_USB_KBD)		+= usbhid/
 
+obj-$(CONFIG_I2C_HID)		+= i2c-hid/
diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c
index fd7722a..d0f7662 100644
--- a/drivers/hid/hid-apple.c
+++ b/drivers/hid/hid-apple.c
@@ -439,7 +439,8 @@
 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_ANSI),
 		.driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_ISO),
-		.driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
+		.driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN |
+			APPLE_ISO_KEYBOARD },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_JIS),
 		.driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN |
 			APPLE_RDESC_JIS },
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index f4109fd..eb2ee11 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -92,6 +92,7 @@
 static struct hid_field *hid_register_field(struct hid_report *report, unsigned usages, unsigned values)
 {
 	struct hid_field *field;
+	int i;
 
 	if (report->maxfield == HID_MAX_FIELDS) {
 		hid_err(report->device, "too many fields in report\n");
@@ -110,6 +111,9 @@
 	field->value = (s32 *)(field->usage + usages);
 	field->report = report;
 
+	for (i = 0; i < usages; i++)
+		field->usage[i].usage_index = i;
+
 	return field;
 }
 
@@ -315,6 +319,7 @@
 
 static int hid_parser_global(struct hid_parser *parser, struct hid_item *item)
 {
+	__u32 raw_value;
 	switch (item->tag) {
 	case HID_GLOBAL_ITEM_TAG_PUSH:
 
@@ -365,7 +370,14 @@
 		return 0;
 
 	case HID_GLOBAL_ITEM_TAG_UNIT_EXPONENT:
-		parser->global.unit_exponent = item_sdata(item);
+		/* Units exponent negative numbers are given through a
+		 * two's complement.
+		 * See "6.2.2.7 Global Items" for more information. */
+		raw_value = item_udata(item);
+		if (!(raw_value & 0xfffffff0))
+			parser->global.unit_exponent = hid_snto32(raw_value, 4);
+		else
+			parser->global.unit_exponent = raw_value;
 		return 0;
 
 	case HID_GLOBAL_ITEM_TAG_UNIT:
@@ -713,7 +725,12 @@
 					hid_scan_usage(hid, u);
 				break;
 			}
-		}
+		} else if (page == HID_UP_SENSOR &&
+			item.type == HID_ITEM_TYPE_MAIN &&
+			item.tag == HID_MAIN_ITEM_TAG_BEGIN_COLLECTION &&
+			(item_udata(&item) & 0xff) == HID_COLLECTION_PHYSICAL &&
+			hid->bus == BUS_USB)
+			hid->group = HID_GROUP_SENSOR_HUB;
 	}
 
 	return 0;
@@ -865,6 +882,12 @@
 	return value & (1 << (n - 1)) ? value | (-1 << n) : value;
 }
 
+s32 hid_snto32(__u32 value, unsigned n)
+{
+	return snto32(value, n);
+}
+EXPORT_SYMBOL_GPL(hid_snto32);
+
 /*
  * Convert a signed 32-bit integer to a signed n-bit integer.
  */
@@ -1465,6 +1488,10 @@
  * there is a proper autodetection and autoloading in place (based on presence
  * of HID_DG_CONTACTID), so those devices don't need to be added to this list,
  * as we are doing the right thing in hid_scan_usage().
+ *
+ * Autodetection for (USB) HID sensor hubs exists too. If a collection of type
+ * physical is found inside a usage page of type sensor, hid-sensor-hub will be
+ * used as a driver. See hid_scan_report().
  */
 static const struct hid_device_id hid_have_special_driver[] = {
 	{ HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU) },
@@ -1538,6 +1565,7 @@
 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI) },
 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO) },
 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS) },
+	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ANSI) },
 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ISO) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) },
@@ -1571,10 +1599,7 @@
 	{ HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE_3) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK, USB_DEVICE_ID_HOLTEK_ON_LINE_GRIP) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_KEYBOARD) },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_INTEL_8086, USB_DEVICE_ID_SENSOR_HUB_1020) },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_INTEL_8086, USB_DEVICE_ID_SENSOR_HUB_09FA) },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_INTEL_8087, USB_DEVICE_ID_SENSOR_HUB_1020) },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_INTEL_8087, USB_DEVICE_ID_SENSOR_HUB_09FA) },
+	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ION, USB_DEVICE_ID_ICADE) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_KENSINGTON, USB_DEVICE_ID_KS_SLIMBLADE) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_KEYTOUCH, USB_DEVICE_ID_KEYTOUCH_IEC) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_ERGO_525V) },
@@ -1658,6 +1683,7 @@
 	{ HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_ISKU) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KONEPLUS) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KOVAPLUS) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_LUA) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_PYRA_WIRED) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_PYRA_WIRELESS) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_SAVU) },
@@ -1672,7 +1698,6 @@
 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_SUNPLUS, USB_DEVICE_ID_SUNPLUS_WDESKTOP) },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_STANTUM_STM, USB_DEVICE_ID_SENSOR_HUB_7014) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb300) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb304) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb323) },
@@ -2150,8 +2175,13 @@
 	{ }
 };
 
-static bool hid_ignore(struct hid_device *hdev)
+bool hid_ignore(struct hid_device *hdev)
 {
+	if (hdev->quirks & HID_QUIRK_NO_IGNORE)
+		return false;
+	if (hdev->quirks & HID_QUIRK_IGNORE)
+		return true;
+
 	switch (hdev->vendor) {
 	case USB_VENDOR_ID_CODEMERCS:
 		/* ignore all Code Mercenaries IOWarrior devices */
@@ -2188,7 +2218,16 @@
 		if (hdev->product == USB_DEVICE_ID_JESS_YUREX &&
 				hdev->type == HID_TYPE_USBNONE)
 			return true;
-	break;
+		break;
+	case USB_VENDOR_ID_DWAV:
+		/* These are handled by usbtouchscreen. hdev->type is probably
+		 * HID_TYPE_USBNONE, but we say !HID_TYPE_USBMOUSE to match
+		 * usbtouchscreen. */
+		if ((hdev->product == USB_DEVICE_ID_EGALAX_TOUCHCONTROLLER ||
+		     hdev->product == USB_DEVICE_ID_DWAV_TOUCHCONTROLLER) &&
+		    hdev->type != HID_TYPE_USBMOUSE)
+			return true;
+		break;
 	}
 
 	if (hdev->type == HID_TYPE_USBMOUSE &&
@@ -2197,6 +2236,7 @@
 
 	return !!hid_match_id(hdev, hid_ignore_list);
 }
+EXPORT_SYMBOL_GPL(hid_ignore);
 
 int hid_add_device(struct hid_device *hdev)
 {
@@ -2208,8 +2248,7 @@
 
 	/* we need to kill them here, otherwise they will stay allocated to
 	 * wait for coming driver */
-	if (!(hdev->quirks & HID_QUIRK_NO_IGNORE)
-            && (hid_ignore(hdev) || (hdev->quirks & HID_QUIRK_IGNORE)))
+	if (hid_ignore(hdev))
 		return -ENODEV;
 
 	/*
diff --git a/drivers/hid/hid-icade.c b/drivers/hid/hid-icade.c
new file mode 100644
index 0000000..1d6565e3
--- /dev/null
+++ b/drivers/hid/hid-icade.c
@@ -0,0 +1,259 @@
+/*
+ *  ION iCade input driver
+ *
+ *  Copyright (c) 2012 Bastien Nocera <hadess@hadess.net>
+ *  Copyright (c) 2012 Benjamin Tissoires <benjamin.tissoires@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 <linux/device.h>
+#include <linux/hid.h>
+#include <linux/module.h>
+
+#include "hid-ids.h"
+
+/*
+ *   ↑      A C Y L
+ *  ← →
+ *   ↓      B X Z R
+ *
+ *
+ *  UP ON,OFF  = w,e
+ *  RT ON,OFF  = d,c
+ *  DN ON,OFF  = x,z
+ *  LT ON,OFF  = a,q
+ *  A  ON,OFF  = y,t
+ *  B  ON,OFF  = h,r
+ *  C  ON,OFF  = u,f
+ *  X  ON,OFF  = j,n
+ *  Y  ON,OFF  = i,m
+ *  Z  ON,OFF  = k,p
+ *  L  ON,OFF  = o,g
+ *  R  ON,OFF  = l,v
+ */
+
+/* The translation code uses HID usage instead of input layer
+ * keys. This code generates a lookup table that makes
+ * translation quick.
+ *
+ * #include <linux/input.h>
+ * #include <stdio.h>
+ * #include <assert.h>
+ *
+ * #define unk     KEY_UNKNOWN
+ *
+ * < copy of hid_keyboard[] from hid-input.c >
+ *
+ * struct icade_key_translation {
+ *     int         from;
+ *     const char *to;
+ *     int         press;
+ * };
+ *
+ * static const struct icade_key_translation icade_keys[] = {
+ *    { KEY_W,        "KEY_UP",         1 },
+ *    { KEY_E,        "KEY_UP",         0 },
+ *    { KEY_D,        "KEY_RIGHT",      1 },
+ *    { KEY_C,        "KEY_RIGHT",      0 },
+ *    { KEY_X,        "KEY_DOWN",       1 },
+ *    { KEY_Z,        "KEY_DOWN",       0 },
+ *    { KEY_A,        "KEY_LEFT",       1 },
+ *    { KEY_Q,        "KEY_LEFT",       0 },
+ *    { KEY_Y,        "BTN_A",          1 },
+ *    { KEY_T,        "BTN_A",          0 },
+ *    { KEY_H,        "BTN_B",          1 },
+ *    { KEY_R,        "BTN_B",          0 },
+ *    { KEY_U,        "BTN_C",          1 },
+ *    { KEY_F,        "BTN_C",          0 },
+ *    { KEY_J,        "BTN_X",          1 },
+ *    { KEY_N,        "BTN_X",          0 },
+ *    { KEY_I,        "BTN_Y",          1 },
+ *    { KEY_M,        "BTN_Y",          0 },
+ *    { KEY_K,        "BTN_Z",          1 },
+ *    { KEY_P,        "BTN_Z",          0 },
+ *    { KEY_O,        "BTN_THUMBL",     1 },
+ *    { KEY_G,        "BTN_THUMBL",     0 },
+ *    { KEY_L,        "BTN_THUMBR",     1 },
+ *    { KEY_V,        "BTN_THUMBR",     0 },
+ *
+ *    { }
+ * };
+ *
+ * static int
+ * usage_for_key (int key)
+ * {
+ *     int i;
+ *     for (i = 0; i < 256; i++) {
+ *     if (hid_keyboard[i] == key)
+ *         return i;
+ *     }
+ *     assert(0);
+ * }
+ *
+ * int main (int argc, char **argv)
+ * {
+ *     const struct icade_key_translation *trans;
+ *     int max_usage = 0;
+ *
+ *     for (trans = icade_keys; trans->from; trans++) {
+ *         int usage = usage_for_key (trans->from);
+ *         max_usage = usage > max_usage ? usage : max_usage;
+ *     }
+ *
+ *     printf ("#define ICADE_MAX_USAGE %d\n\n", max_usage);
+ *     printf ("struct icade_key {\n");
+ *     printf ("\tu16 to;\n");
+ *     printf ("\tu8 press:1;\n");
+ *     printf ("};\n\n");
+ *     printf ("static const struct icade_key "
+ *             "icade_usage_table[%d] = {\n", max_usage + 1);
+ *     for (trans = icade_keys; trans->from; trans++) {
+ *         printf ("\t[%d] = { %s, %d },\n",
+ *                 usage_for_key (trans->from), trans->to, trans->press);
+ *     }
+ *     printf ("};\n");
+ *
+ *     return 0;
+ * }
+ */
+
+#define ICADE_MAX_USAGE 29
+
+struct icade_key {
+	u16 to;
+	u8 press:1;
+};
+
+static const struct icade_key icade_usage_table[30] = {
+	[26] = { KEY_UP, 1 },
+	[8] = { KEY_UP, 0 },
+	[7] = { KEY_RIGHT, 1 },
+	[6] = { KEY_RIGHT, 0 },
+	[27] = { KEY_DOWN, 1 },
+	[29] = { KEY_DOWN, 0 },
+	[4] = { KEY_LEFT, 1 },
+	[20] = { KEY_LEFT, 0 },
+	[28] = { BTN_A, 1 },
+	[23] = { BTN_A, 0 },
+	[11] = { BTN_B, 1 },
+	[21] = { BTN_B, 0 },
+	[24] = { BTN_C, 1 },
+	[9] = { BTN_C, 0 },
+	[13] = { BTN_X, 1 },
+	[17] = { BTN_X, 0 },
+	[12] = { BTN_Y, 1 },
+	[16] = { BTN_Y, 0 },
+	[14] = { BTN_Z, 1 },
+	[19] = { BTN_Z, 0 },
+	[18] = { BTN_THUMBL, 1 },
+	[10] = { BTN_THUMBL, 0 },
+	[15] = { BTN_THUMBR, 1 },
+	[25] = { BTN_THUMBR, 0 },
+};
+
+static const struct icade_key *icade_find_translation(u16 from)
+{
+	if (from < 0 || from > ICADE_MAX_USAGE)
+		return NULL;
+	return &icade_usage_table[from];
+}
+
+static int icade_event(struct hid_device *hdev, struct hid_field *field,
+		struct hid_usage *usage, __s32 value)
+{
+	const struct icade_key *trans;
+
+	if (!(hdev->claimed & HID_CLAIMED_INPUT) || !field->hidinput ||
+			!usage->type)
+		return 0;
+
+	/* We ignore the fake key up, and act only on key down */
+	if (!value)
+		return 1;
+
+	trans = icade_find_translation(usage->hid & HID_USAGE);
+
+	if (!trans)
+		return 1;
+
+	input_event(field->hidinput->input, usage->type,
+			trans->to, trans->press);
+
+	return 1;
+}
+
+static int icade_input_mapping(struct hid_device *hdev, struct hid_input *hi,
+		struct hid_field *field, struct hid_usage *usage,
+		unsigned long **bit, int *max)
+{
+	const struct icade_key *trans;
+
+	if ((usage->hid & HID_USAGE_PAGE) == HID_UP_KEYBOARD) {
+		trans = icade_find_translation(usage->hid & HID_USAGE);
+
+		if (!trans)
+			return -1;
+
+		hid_map_usage(hi, usage, bit, max, EV_KEY, trans->to);
+		set_bit(trans->to, hi->input->keybit);
+
+		return 1;
+	}
+
+	/* ignore others */
+	return -1;
+
+}
+
+static int icade_input_mapped(struct hid_device *hdev, struct hid_input *hi,
+		struct hid_field *field, struct hid_usage *usage,
+		unsigned long **bit, int *max)
+{
+	if (usage->type == EV_KEY)
+		set_bit(usage->type, hi->input->evbit);
+
+	return -1;
+}
+
+static const struct hid_device_id icade_devices[] = {
+	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ION, USB_DEVICE_ID_ICADE) },
+
+	{ }
+};
+MODULE_DEVICE_TABLE(hid, icade_devices);
+
+static struct hid_driver icade_driver = {
+	.name = "icade",
+	.id_table = icade_devices,
+	.event = icade_event,
+	.input_mapped = icade_input_mapped,
+	.input_mapping = icade_input_mapping,
+};
+
+static int __init icade_init(void)
+{
+	int ret;
+
+	ret = hid_register_driver(&icade_driver);
+	if (ret)
+		pr_err("can't register icade driver\n");
+
+	return ret;
+}
+
+static void __exit icade_exit(void)
+{
+	hid_unregister_driver(&icade_driver);
+}
+
+module_init(icade_init);
+module_exit(icade_exit);
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Bastien Nocera <hadess@hadess.net>");
+MODULE_DESCRIPTION("ION iCade input driver");
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index 9d7a428..4dfa605 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -257,6 +257,7 @@
 
 #define USB_VENDOR_ID_DWAV		0x0eef
 #define USB_DEVICE_ID_EGALAX_TOUCHCONTROLLER	0x0001
+#define USB_DEVICE_ID_DWAV_TOUCHCONTROLLER	0x0002
 #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_480D	0x480d
 #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_480E	0x480e
 #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7207	0x7207
@@ -423,6 +424,9 @@
 #define USB_VENDOR_ID_ILITEK		0x222a
 #define USB_DEVICE_ID_ILITEK_MULTITOUCH	0x0001
 
+#define USB_VENDOR_ID_ION		0x15e4
+#define USB_DEVICE_ID_ICADE		0x0132
+
 #define USB_VENDOR_ID_HOLTEK		0x1241
 #define USB_DEVICE_ID_HOLTEK_ON_LINE_GRIP	0x5015
 
@@ -432,11 +436,6 @@
 #define USB_VENDOR_ID_IMATION		0x0718
 #define USB_DEVICE_ID_DISC_STAKKA	0xd000
 
-#define USB_VENDOR_ID_INTEL_8086	0x8086
-#define USB_VENDOR_ID_INTEL_8087	0x8087
-#define USB_DEVICE_ID_SENSOR_HUB_1020	0x1020
-#define USB_DEVICE_ID_SENSOR_HUB_09FA	0x09FA
-
 #define USB_VENDOR_ID_IRTOUCHSYSTEMS	0x6615
 #define USB_DEVICE_ID_IRTOUCH_INFRARED_USB	0x0070
 
@@ -603,6 +602,7 @@
 
 #define USB_VENDOR_ID_NOVATEK		0x0603
 #define USB_DEVICE_ID_NOVATEK_PCT	0x0600
+#define USB_DEVICE_ID_NOVATEK_MOUSE	0x1602
 
 #define USB_VENDOR_ID_NTRIG		0x1b96
 #define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN   0x0001
@@ -677,7 +677,9 @@
 #define USB_DEVICE_ID_ROCCAT_ISKU	0x319c
 #define USB_DEVICE_ID_ROCCAT_KONE	0x2ced
 #define USB_DEVICE_ID_ROCCAT_KONEPLUS	0x2d51
+#define USB_DEVICE_ID_ROCCAT_KONEXTD	0x2e22
 #define USB_DEVICE_ID_ROCCAT_KOVAPLUS	0x2d50
+#define USB_DEVICE_ID_ROCCAT_LUA	0x2c2e
 #define USB_DEVICE_ID_ROCCAT_PYRA_WIRED	0x2c24
 #define USB_DEVICE_ID_ROCCAT_PYRA_WIRELESS	0x2cf6
 #define USB_DEVICE_ID_ROCCAT_SAVU	0x2d5a
@@ -696,6 +698,9 @@
 #define USB_VENDOR_ID_SIGMA_MICRO	0x1c4f
 #define USB_DEVICE_ID_SIGMA_MICRO_KEYBOARD	0x0002
 
+#define USB_VENDOR_ID_SIGMATEL		0x066F
+#define USB_DEVICE_ID_SIGMATEL_STMP3780	0x3780
+
 #define USB_VENDOR_ID_SKYCABLE			0x1223
 #define	USB_DEVICE_ID_SKYCABLE_WIRELESS_PRESENTER	0x3F07
 
@@ -714,7 +719,6 @@
 
 #define USB_VENDOR_ID_STANTUM_STM		0x0483
 #define USB_DEVICE_ID_MTP_STM		0x3261
-#define USB_DEVICE_ID_SENSOR_HUB_7014	0x7014
 
 #define USB_VENDOR_ID_STANTUM_SITRONIX		0x1403
 #define USB_DEVICE_ID_MTP_SITRONIX		0x5001
@@ -762,6 +766,9 @@
 #define USB_VENDOR_ID_TOUCHPACK		0x1bfd
 #define USB_DEVICE_ID_TOUCHPACK_RTS	0x1688
 
+#define USB_VENDOR_ID_TPV		0x25aa
+#define USB_DEVICE_ID_TPV_OPTICAL_TOUCHSCREEN	0x8883
+
 #define USB_VENDOR_ID_TURBOX		0x062a
 #define USB_DEVICE_ID_TURBOX_KEYBOARD	0x0201
 #define USB_DEVICE_ID_TURBOX_TOUCHSCREEN_MOSART	0x7100
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
index d917c0d..21b196c 100644
--- a/drivers/hid/hid-input.c
+++ b/drivers/hid/hid-input.c
@@ -192,7 +192,6 @@
 	return -EINVAL;
 }
 
-
 /**
  * hidinput_calc_abs_res - calculate an absolute axis resolution
  * @field: the HID report field to calculate resolution for
@@ -208,7 +207,7 @@
  * Only exponent 1 length units are processed. Centimeters and inches are
  * converted to millimeters. Degrees are converted to radians.
  */
-static __s32 hidinput_calc_abs_res(const struct hid_field *field, __u16 code)
+__s32 hidinput_calc_abs_res(const struct hid_field *field, __u16 code)
 {
 	__s32 unit_exponent = field->unit_exponent;
 	__s32 logical_extents = field->logical_maximum -
@@ -229,17 +228,29 @@
 	case ABS_X:
 	case ABS_Y:
 	case ABS_Z:
-		if (field->unit == 0x11) {		/* If centimeters */
+	case ABS_MT_POSITION_X:
+	case ABS_MT_POSITION_Y:
+	case ABS_MT_TOOL_X:
+	case ABS_MT_TOOL_Y:
+	case ABS_MT_TOUCH_MAJOR:
+	case ABS_MT_TOUCH_MINOR:
+		if (field->unit & 0xffffff00)		/* Not a length */
+			return 0;
+		unit_exponent += hid_snto32(field->unit >> 4, 4) - 1;
+		switch (field->unit & 0xf) {
+		case 0x1:				/* If centimeters */
 			/* Convert to millimeters */
 			unit_exponent += 1;
-		} else if (field->unit == 0x13) {	/* If inches */
+			break;
+		case 0x3:				/* If inches */
 			/* Convert to millimeters */
 			prev = physical_extents;
 			physical_extents *= 254;
 			if (physical_extents < prev)
 				return 0;
 			unit_exponent -= 1;
-		} else {
+			break;
+		default:
 			return 0;
 		}
 		break;
@@ -281,8 +292,9 @@
 	}
 
 	/* Calculate resolution */
-	return logical_extents / physical_extents;
+	return DIV_ROUND_CLOSEST(logical_extents, physical_extents);
 }
+EXPORT_SYMBOL_GPL(hidinput_calc_abs_res);
 
 #ifdef CONFIG_HID_BATTERY_STRENGTH
 static enum power_supply_property hidinput_battery_props[] = {
@@ -299,6 +311,9 @@
 
 static const struct hid_device_id hid_battery_quirks[] = {
 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE,
+			USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO),
+	HID_BATTERY_QUIRK_PERCENT | HID_BATTERY_QUIRK_FEATURE },
+	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE,
 			       USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ANSI),
 	  HID_BATTERY_QUIRK_PERCENT | HID_BATTERY_QUIRK_FEATURE },
 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE,
@@ -502,9 +517,14 @@
 				if (code <= 0xf)
 					code += BTN_JOYSTICK;
 				else
-					code += BTN_TRIGGER_HAPPY;
+					code += BTN_TRIGGER_HAPPY - 0x10;
 				break;
-		case HID_GD_GAMEPAD:  code += BTN_GAMEPAD; break;
+		case HID_GD_GAMEPAD:
+				if (code <= 0xf)
+					code += BTN_GAMEPAD;
+				else
+					code += BTN_TRIGGER_HAPPY - 0x10;
+				break;
 		default:
 			switch (field->physical) {
 			case HID_GD_MOUSE:
@@ -1146,6 +1166,38 @@
 			}
 }
 
+static struct hid_input *hidinput_allocate(struct hid_device *hid)
+{
+	struct hid_input *hidinput = kzalloc(sizeof(*hidinput), GFP_KERNEL);
+	struct input_dev *input_dev = input_allocate_device();
+	if (!hidinput || !input_dev) {
+		kfree(hidinput);
+		input_free_device(input_dev);
+		hid_err(hid, "Out of memory during hid input probe\n");
+		return NULL;
+	}
+
+	input_set_drvdata(input_dev, hid);
+	input_dev->event = hid->ll_driver->hidinput_input_event;
+	input_dev->open = hidinput_open;
+	input_dev->close = hidinput_close;
+	input_dev->setkeycode = hidinput_setkeycode;
+	input_dev->getkeycode = hidinput_getkeycode;
+
+	input_dev->name = hid->name;
+	input_dev->phys = hid->phys;
+	input_dev->uniq = hid->uniq;
+	input_dev->id.bustype = hid->bus;
+	input_dev->id.vendor  = hid->vendor;
+	input_dev->id.product = hid->product;
+	input_dev->id.version = hid->version;
+	input_dev->dev.parent = hid->dev.parent;
+	hidinput->input = input_dev;
+	list_add_tail(&hidinput->list, &hid->inputs);
+
+	return hidinput;
+}
+
 /*
  * Register the input device; print a message.
  * Configure the input layer interface
@@ -1157,7 +1209,6 @@
 	struct hid_driver *drv = hid->driver;
 	struct hid_report *report;
 	struct hid_input *hidinput = NULL;
-	struct input_dev *input_dev;
 	int i, j, k;
 
 	INIT_LIST_HEAD(&hid->inputs);
@@ -1188,33 +1239,9 @@
 				continue;
 
 			if (!hidinput) {
-				hidinput = kzalloc(sizeof(*hidinput), GFP_KERNEL);
-				input_dev = input_allocate_device();
-				if (!hidinput || !input_dev) {
-					kfree(hidinput);
-					input_free_device(input_dev);
-					hid_err(hid, "Out of memory during hid input probe\n");
+				hidinput = hidinput_allocate(hid);
+				if (!hidinput)
 					goto out_unwind;
-				}
-
-				input_set_drvdata(input_dev, hid);
-				input_dev->event =
-					hid->ll_driver->hidinput_input_event;
-				input_dev->open = hidinput_open;
-				input_dev->close = hidinput_close;
-				input_dev->setkeycode = hidinput_setkeycode;
-				input_dev->getkeycode = hidinput_getkeycode;
-
-				input_dev->name = hid->name;
-				input_dev->phys = hid->phys;
-				input_dev->uniq = hid->uniq;
-				input_dev->id.bustype = hid->bus;
-				input_dev->id.vendor  = hid->vendor;
-				input_dev->id.product = hid->product;
-				input_dev->id.version = hid->version;
-				input_dev->dev.parent = hid->dev.parent;
-				hidinput->input = input_dev;
-				list_add_tail(&hidinput->list, &hid->inputs);
 			}
 
 			for (i = 0; i < report->maxfield; i++)
diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
index 7867d69..61543c0 100644
--- a/drivers/hid/hid-multitouch.c
+++ b/drivers/hid/hid-multitouch.c
@@ -52,11 +52,14 @@
 #define MT_QUIRK_VALID_IS_CONFIDENCE	(1 << 6)
 #define MT_QUIRK_SLOT_IS_CONTACTID_MINUS_ONE	(1 << 8)
 #define MT_QUIRK_NO_AREA		(1 << 9)
+#define MT_QUIRK_IGNORE_DUPLICATES	(1 << 10)
+#define MT_QUIRK_HOVERING		(1 << 11)
 
 struct mt_slot {
-	__s32 x, y, p, w, h;
+	__s32 x, y, cx, cy, p, w, h;
 	__s32 contactid;	/* the device ContactID assigned to this slot */
 	bool touch_state;	/* is the touch valid? */
+	bool inrange_state;	/* is the finger in proximity of the sensor? */
 };
 
 struct mt_class {
@@ -121,6 +124,7 @@
 #define MT_CLS_GENERALTOUCH_PWT_TENFINGERS	0x0109
 
 #define MT_DEFAULT_MAXCONTACT	10
+#define MT_MAX_MAXCONTACT	250
 
 #define MT_USB_DEVICE(v, p)	HID_DEVICE(BUS_USB, HID_GROUP_MULTITOUCH, v, p)
 #define MT_BT_DEVICE(v, p)	HID_DEVICE(BUS_BLUETOOTH, HID_GROUP_MULTITOUCH, v, p)
@@ -282,11 +286,26 @@
 	case HID_DG_CONTACTMAX:
 		td->maxcontact_report_id = field->report->id;
 		td->maxcontacts = field->value[0];
+		if (!td->maxcontacts &&
+		    field->logical_maximum <= MT_MAX_MAXCONTACT)
+			td->maxcontacts = field->logical_maximum;
 		if (td->mtclass.maxcontacts)
 			/* check if the maxcontacts is given by the class */
 			td->maxcontacts = td->mtclass.maxcontacts;
 
 		break;
+	case 0xff0000c5:
+		if (field->report_count == 256 && field->report_size == 8) {
+			/* Win 8 devices need special quirks */
+			__s32 *quirks = &td->mtclass.quirks;
+			*quirks |= MT_QUIRK_ALWAYS_VALID;
+			*quirks |= MT_QUIRK_IGNORE_DUPLICATES;
+			*quirks |= MT_QUIRK_HOVERING;
+			*quirks &= ~MT_QUIRK_NOT_SEEN_MEANS_UP;
+			*quirks &= ~MT_QUIRK_VALID_IS_INRANGE;
+			*quirks &= ~MT_QUIRK_VALID_IS_CONFIDENCE;
+		}
+		break;
 	}
 }
 
@@ -297,6 +316,7 @@
 	int fmax = field->logical_maximum;
 	int fuzz = snratio ? (fmax - fmin) / snratio : 0;
 	input_set_abs_params(input, code, fmin, fmax, fuzz, 0);
+	input_abs_set_res(input, code, hidinput_calc_abs_res(field, code));
 }
 
 static void mt_store_field(struct hid_usage *usage, struct mt_device *td,
@@ -317,6 +337,7 @@
 	struct mt_device *td = hid_get_drvdata(hdev);
 	struct mt_class *cls = &td->mtclass;
 	int code;
+	struct hid_usage *prev_usage = NULL;
 
 	/* Only map fields from TouchScreen or TouchPad collections.
 	* We need to ignore fields that belong to other collections
@@ -339,23 +360,42 @@
 	if (field->physical == HID_DG_STYLUS)
 		return -1;
 
+	if (usage->usage_index)
+		prev_usage = &field->usage[usage->usage_index - 1];
+
 	switch (usage->hid & HID_USAGE_PAGE) {
 
 	case HID_UP_GENDESK:
 		switch (usage->hid) {
 		case HID_GD_X:
-			hid_map_usage(hi, usage, bit, max,
+			if (prev_usage && (prev_usage->hid == usage->hid)) {
+				hid_map_usage(hi, usage, bit, max,
+					EV_ABS, ABS_MT_TOOL_X);
+				set_abs(hi->input, ABS_MT_TOOL_X, field,
+					cls->sn_move);
+			} else {
+				hid_map_usage(hi, usage, bit, max,
 					EV_ABS, ABS_MT_POSITION_X);
-			set_abs(hi->input, ABS_MT_POSITION_X, field,
-				cls->sn_move);
+				set_abs(hi->input, ABS_MT_POSITION_X, field,
+					cls->sn_move);
+			}
+
 			mt_store_field(usage, td, hi);
 			td->last_field_index = field->index;
 			return 1;
 		case HID_GD_Y:
-			hid_map_usage(hi, usage, bit, max,
+			if (prev_usage && (prev_usage->hid == usage->hid)) {
+				hid_map_usage(hi, usage, bit, max,
+					EV_ABS, ABS_MT_TOOL_Y);
+				set_abs(hi->input, ABS_MT_TOOL_Y, field,
+					cls->sn_move);
+			} else {
+				hid_map_usage(hi, usage, bit, max,
 					EV_ABS, ABS_MT_POSITION_Y);
-			set_abs(hi->input, ABS_MT_POSITION_Y, field,
-				cls->sn_move);
+				set_abs(hi->input, ABS_MT_POSITION_Y, field,
+					cls->sn_move);
+			}
+
 			mt_store_field(usage, td, hi);
 			td->last_field_index = field->index;
 			return 1;
@@ -365,6 +405,12 @@
 	case HID_UP_DIGITIZER:
 		switch (usage->hid) {
 		case HID_DG_INRANGE:
+			if (cls->quirks & MT_QUIRK_HOVERING) {
+				hid_map_usage(hi, usage, bit, max,
+					EV_ABS, ABS_MT_DISTANCE);
+				input_set_abs_params(hi->input,
+					ABS_MT_DISTANCE, 0, 1, 0, 0);
+			}
 			mt_store_field(usage, td, hi);
 			td->last_field_index = field->index;
 			return 1;
@@ -477,18 +523,26 @@
  */
 static void mt_complete_slot(struct mt_device *td, struct input_dev *input)
 {
-	if (td->curvalid) {
+	if (td->curvalid || (td->mtclass.quirks & MT_QUIRK_ALWAYS_VALID)) {
 		int slotnum = mt_compute_slot(td, input);
 		struct mt_slot *s = &td->curdata;
+		struct input_mt *mt = input->mt;
 
 		if (slotnum < 0 || slotnum >= td->maxcontacts)
 			return;
 
+		if ((td->mtclass.quirks & MT_QUIRK_IGNORE_DUPLICATES) && mt) {
+			struct input_mt_slot *slot = &mt->slots[slotnum];
+			if (input_mt_is_active(slot) &&
+			    input_mt_is_used(mt, slot))
+				return;
+		}
+
 		input_mt_slot(input, slotnum);
 		input_mt_report_slot_state(input, MT_TOOL_FINGER,
-			s->touch_state);
-		if (s->touch_state) {
-			/* this finger is on the screen */
+			s->touch_state || s->inrange_state);
+		if (s->touch_state || s->inrange_state) {
+			/* this finger is in proximity of the sensor */
 			int wide = (s->w > s->h);
 			/* divided by two to match visual scale of touch */
 			int major = max(s->w, s->h) >> 1;
@@ -496,6 +550,10 @@
 
 			input_event(input, EV_ABS, ABS_MT_POSITION_X, s->x);
 			input_event(input, EV_ABS, ABS_MT_POSITION_Y, s->y);
+			input_event(input, EV_ABS, ABS_MT_TOOL_X, s->cx);
+			input_event(input, EV_ABS, ABS_MT_TOOL_Y, s->cy);
+			input_event(input, EV_ABS, ABS_MT_DISTANCE,
+				!s->touch_state);
 			input_event(input, EV_ABS, ABS_MT_ORIENTATION, wide);
 			input_event(input, EV_ABS, ABS_MT_PRESSURE, s->p);
 			input_event(input, EV_ABS, ABS_MT_TOUCH_MAJOR, major);
@@ -526,10 +584,10 @@
 	if (hid->claimed & HID_CLAIMED_INPUT) {
 		switch (usage->hid) {
 		case HID_DG_INRANGE:
-			if (quirks & MT_QUIRK_ALWAYS_VALID)
-				td->curvalid = true;
-			else if (quirks & MT_QUIRK_VALID_IS_INRANGE)
+			if (quirks & MT_QUIRK_VALID_IS_INRANGE)
 				td->curvalid = value;
+			if (quirks & MT_QUIRK_HOVERING)
+				td->curdata.inrange_state = value;
 			break;
 		case HID_DG_TIPSWITCH:
 			if (quirks & MT_QUIRK_NOT_SEEN_MEANS_UP)
@@ -547,10 +605,16 @@
 			td->curdata.p = value;
 			break;
 		case HID_GD_X:
-			td->curdata.x = value;
+			if (usage->code == ABS_MT_TOOL_X)
+				td->curdata.cx = value;
+			else
+				td->curdata.x = value;
 			break;
 		case HID_GD_Y:
-			td->curdata.y = value;
+			if (usage->code == ABS_MT_TOOL_Y)
+				td->curdata.cy = value;
+			else
+				td->curdata.y = value;
 			break;
 		case HID_DG_WIDTH:
 			td->curdata.w = value;
@@ -575,12 +639,15 @@
 			return 0;
 		}
 
-		if (usage->hid == td->last_slot_field)
-			mt_complete_slot(td, field->hidinput->input);
+		if (usage->usage_index + 1 == field->report_count) {
+			/* we only take into account the last report. */
+			if (usage->hid == td->last_slot_field)
+				mt_complete_slot(td, field->hidinput->input);
 
-		if (field->index == td->last_field_index
-			&& td->num_received >= td->num_expected)
-			mt_sync_frame(td, field->hidinput->input);
+			if (field->index == td->last_field_index
+				&& td->num_received >= td->num_expected)
+				mt_sync_frame(td, field->hidinput->input);
+		}
 
 	}
 
diff --git a/drivers/hid/hid-roccat-isku.c b/drivers/hid/hid-roccat-isku.c
index 5669916..1219998 100644
--- a/drivers/hid/hid-roccat-isku.c
+++ b/drivers/hid/hid-roccat-isku.c
@@ -167,7 +167,7 @@
 		loff_t off, size_t count) \
 { \
 	return isku_sysfs_write(fp, kobj, buf, off, count, \
-			sizeof(struct isku_ ## thingy), ISKU_COMMAND_ ## THINGY); \
+			ISKU_SIZE_ ## THINGY, ISKU_COMMAND_ ## THINGY); \
 }
 
 #define ISKU_SYSFS_R(thingy, THINGY) \
@@ -176,32 +176,32 @@
 		loff_t off, size_t count) \
 { \
 	return isku_sysfs_read(fp, kobj, buf, off, count, \
-			sizeof(struct isku_ ## thingy), ISKU_COMMAND_ ## THINGY); \
+			ISKU_SIZE_ ## THINGY, ISKU_COMMAND_ ## THINGY); \
 }
 
 #define ISKU_SYSFS_RW(thingy, THINGY) \
 ISKU_SYSFS_R(thingy, THINGY) \
 ISKU_SYSFS_W(thingy, THINGY)
 
-#define ISKU_BIN_ATTR_RW(thingy) \
+#define ISKU_BIN_ATTR_RW(thingy, THINGY) \
 { \
 	.attr = { .name = #thingy, .mode = 0660 }, \
-	.size = sizeof(struct isku_ ## thingy), \
+	.size = ISKU_SIZE_ ## THINGY, \
 	.read = isku_sysfs_read_ ## thingy, \
 	.write = isku_sysfs_write_ ## thingy \
 }
 
-#define ISKU_BIN_ATTR_R(thingy) \
+#define ISKU_BIN_ATTR_R(thingy, THINGY) \
 { \
 	.attr = { .name = #thingy, .mode = 0440 }, \
-	.size = sizeof(struct isku_ ## thingy), \
+	.size = ISKU_SIZE_ ## THINGY, \
 	.read = isku_sysfs_read_ ## thingy, \
 }
 
-#define ISKU_BIN_ATTR_W(thingy) \
+#define ISKU_BIN_ATTR_W(thingy, THINGY) \
 { \
 	.attr = { .name = #thingy, .mode = 0220 }, \
-	.size = sizeof(struct isku_ ## thingy), \
+	.size = ISKU_SIZE_ ## THINGY, \
 	.write = isku_sysfs_write_ ## thingy \
 }
 
@@ -218,21 +218,23 @@
 ISKU_SYSFS_W(talk, TALK)
 ISKU_SYSFS_R(info, INFO)
 ISKU_SYSFS_W(control, CONTROL)
+ISKU_SYSFS_W(reset, RESET)
 
 static struct bin_attribute isku_bin_attributes[] = {
-	ISKU_BIN_ATTR_RW(macro),
-	ISKU_BIN_ATTR_RW(keys_function),
-	ISKU_BIN_ATTR_RW(keys_easyzone),
-	ISKU_BIN_ATTR_RW(keys_media),
-	ISKU_BIN_ATTR_RW(keys_thumbster),
-	ISKU_BIN_ATTR_RW(keys_macro),
-	ISKU_BIN_ATTR_RW(keys_capslock),
-	ISKU_BIN_ATTR_RW(light),
-	ISKU_BIN_ATTR_RW(key_mask),
-	ISKU_BIN_ATTR_RW(last_set),
-	ISKU_BIN_ATTR_W(talk),
-	ISKU_BIN_ATTR_R(info),
-	ISKU_BIN_ATTR_W(control),
+	ISKU_BIN_ATTR_RW(macro, MACRO),
+	ISKU_BIN_ATTR_RW(keys_function, KEYS_FUNCTION),
+	ISKU_BIN_ATTR_RW(keys_easyzone, KEYS_EASYZONE),
+	ISKU_BIN_ATTR_RW(keys_media, KEYS_MEDIA),
+	ISKU_BIN_ATTR_RW(keys_thumbster, KEYS_THUMBSTER),
+	ISKU_BIN_ATTR_RW(keys_macro, KEYS_MACRO),
+	ISKU_BIN_ATTR_RW(keys_capslock, KEYS_CAPSLOCK),
+	ISKU_BIN_ATTR_RW(light, LIGHT),
+	ISKU_BIN_ATTR_RW(key_mask, KEY_MASK),
+	ISKU_BIN_ATTR_RW(last_set, LAST_SET),
+	ISKU_BIN_ATTR_W(talk, TALK),
+	ISKU_BIN_ATTR_R(info, INFO),
+	ISKU_BIN_ATTR_W(control, CONTROL),
+	ISKU_BIN_ATTR_W(reset, RESET),
 	__ATTR_NULL
 };
 
diff --git a/drivers/hid/hid-roccat-isku.h b/drivers/hid/hid-roccat-isku.h
index 605b3ce..cf6896c 100644
--- a/drivers/hid/hid-roccat-isku.h
+++ b/drivers/hid/hid-roccat-isku.h
@@ -15,76 +15,33 @@
 #include <linux/types.h>
 
 enum {
+	ISKU_SIZE_CONTROL = 0x03,
+	ISKU_SIZE_INFO = 0x06,
+	ISKU_SIZE_KEY_MASK = 0x06,
+	ISKU_SIZE_KEYS_FUNCTION = 0x29,
+	ISKU_SIZE_KEYS_EASYZONE = 0x41,
+	ISKU_SIZE_KEYS_MEDIA = 0x1d,
+	ISKU_SIZE_KEYS_THUMBSTER = 0x17,
+	ISKU_SIZE_KEYS_MACRO = 0x23,
+	ISKU_SIZE_KEYS_CAPSLOCK = 0x06,
+	ISKU_SIZE_LAST_SET = 0x14,
+	ISKU_SIZE_LIGHT = 0x0a,
+	ISKU_SIZE_MACRO = 0x823,
+	ISKU_SIZE_RESET = 0x03,
+	ISKU_SIZE_TALK = 0x10,
+};
+
+enum {
 	ISKU_PROFILE_NUM = 5,
 	ISKU_USB_INTERFACE_PROTOCOL = 0,
 };
 
-struct isku_control {
-	uint8_t command; /* ISKU_COMMAND_CONTROL */
-	uint8_t value;
-	uint8_t request;
-} __packed;
-
 struct isku_actual_profile {
 	uint8_t command; /* ISKU_COMMAND_ACTUAL_PROFILE */
 	uint8_t size; /* always 3 */
 	uint8_t actual_profile;
 } __packed;
 
-struct isku_key_mask {
-	uint8_t command; /* ISKU_COMMAND_KEY_MASK */
-	uint8_t size; /* 6 */
-	uint8_t profile_number; /* 0-4 */
-	uint8_t mask;
-	uint16_t checksum;
-} __packed;
-
-struct isku_keys_function {
-	uint8_t data[0x29];
-} __packed;
-
-struct isku_keys_easyzone {
-	uint8_t data[0x41];
-} __packed;
-
-struct isku_keys_media {
-	uint8_t data[0x1d];
-} __packed;
-
-struct isku_keys_thumbster {
-	uint8_t data[0x17];
-} __packed;
-
-struct isku_keys_macro {
-	uint8_t data[0x23];
-} __packed;
-
-struct isku_keys_capslock {
-	uint8_t data[0x6];
-} __packed;
-
-struct isku_macro {
-	uint8_t data[0x823];
-} __packed;
-
-struct isku_light {
-	uint8_t data[0xa];
-} __packed;
-
-struct isku_info {
-	uint8_t data[2];
-	uint8_t firmware_version;
-	uint8_t unknown[3];
-} __packed;
-
-struct isku_talk {
-	uint8_t data[0x10];
-} __packed;
-
-struct isku_last_set {
-	uint8_t data[0x14];
-} __packed;
-
 enum isku_commands {
 	ISKU_COMMAND_CONTROL = 0x4,
 	ISKU_COMMAND_ACTUAL_PROFILE = 0x5,
@@ -97,6 +54,7 @@
 	ISKU_COMMAND_MACRO = 0xe,
 	ISKU_COMMAND_INFO = 0xf,
 	ISKU_COMMAND_LIGHT = 0x10,
+	ISKU_COMMAND_RESET = 0x11,
 	ISKU_COMMAND_KEYS_CAPSLOCK = 0x13,
 	ISKU_COMMAND_LAST_SET = 0x14,
 	ISKU_COMMAND_15 = 0x15,
diff --git a/drivers/hid/hid-roccat-koneplus.c b/drivers/hid/hid-roccat-koneplus.c
index f5602fe..6a48fa3 100644
--- a/drivers/hid/hid-roccat-koneplus.c
+++ b/drivers/hid/hid-roccat-koneplus.c
@@ -14,6 +14,7 @@
 /*
  * Roccat Kone[+] is an updated/improved version of the Kone with more memory
  * and functionality and without the non-standard behaviours the Kone had.
+ * KoneXTD has same capabilities but updated sensor.
  */
 
 #include <linux/device.h>
@@ -55,56 +56,6 @@
 			&control, sizeof(struct roccat_common2_control));
 }
 
-static int koneplus_get_info(struct usb_device *usb_dev,
-		struct koneplus_info *buf)
-{
-	return roccat_common2_receive(usb_dev, KONEPLUS_COMMAND_INFO,
-			buf, sizeof(struct koneplus_info));
-}
-
-static int koneplus_get_profile_settings(struct usb_device *usb_dev,
-		struct koneplus_profile_settings *buf, uint number)
-{
-	int retval;
-
-	retval = koneplus_send_control(usb_dev, number,
-			KONEPLUS_CONTROL_REQUEST_PROFILE_SETTINGS);
-	if (retval)
-		return retval;
-
-	return roccat_common2_receive(usb_dev, KONEPLUS_COMMAND_PROFILE_SETTINGS,
-			buf, sizeof(struct koneplus_profile_settings));
-}
-
-static int koneplus_set_profile_settings(struct usb_device *usb_dev,
-		struct koneplus_profile_settings const *settings)
-{
-	return roccat_common2_send_with_status(usb_dev,
-			KONEPLUS_COMMAND_PROFILE_SETTINGS,
-			settings, sizeof(struct koneplus_profile_settings));
-}
-
-static int koneplus_get_profile_buttons(struct usb_device *usb_dev,
-		struct koneplus_profile_buttons *buf, int number)
-{
-	int retval;
-
-	retval = koneplus_send_control(usb_dev, number,
-			KONEPLUS_CONTROL_REQUEST_PROFILE_BUTTONS);
-	if (retval)
-		return retval;
-
-	return roccat_common2_receive(usb_dev, KONEPLUS_COMMAND_PROFILE_BUTTONS,
-			buf, sizeof(struct koneplus_profile_buttons));
-}
-
-static int koneplus_set_profile_buttons(struct usb_device *usb_dev,
-		struct koneplus_profile_buttons const *buttons)
-{
-	return roccat_common2_send_with_status(usb_dev,
-			KONEPLUS_COMMAND_PROFILE_BUTTONS,
-			buttons, sizeof(struct koneplus_profile_buttons));
-}
 
 /* retval is 0-4 on success, < 0 on error */
 static int koneplus_get_actual_profile(struct usb_device *usb_dev)
@@ -113,7 +64,7 @@
 	int retval;
 
 	retval = roccat_common2_receive(usb_dev, KONEPLUS_COMMAND_ACTUAL_PROFILE,
-			&buf, sizeof(struct koneplus_actual_profile));
+			&buf, KONEPLUS_SIZE_ACTUAL_PROFILE);
 
 	return retval ? retval : buf.actual_profile;
 }
@@ -124,12 +75,12 @@
 	struct koneplus_actual_profile buf;
 
 	buf.command = KONEPLUS_COMMAND_ACTUAL_PROFILE;
-	buf.size = sizeof(struct koneplus_actual_profile);
+	buf.size = KONEPLUS_SIZE_ACTUAL_PROFILE;
 	buf.actual_profile = new_profile;
 
 	return roccat_common2_send_with_status(usb_dev,
 			KONEPLUS_COMMAND_ACTUAL_PROFILE,
-			&buf, sizeof(struct koneplus_actual_profile));
+			&buf, KONEPLUS_SIZE_ACTUAL_PROFILE);
 }
 
 static ssize_t koneplus_sysfs_read(struct file *fp, struct kobject *kobj,
@@ -182,53 +133,59 @@
 	return real_size;
 }
 
-static ssize_t koneplus_sysfs_write_talk(struct file *fp,
-		struct kobject *kobj, struct bin_attribute *attr, char *buf,
-		loff_t off, size_t count)
-{
-	return koneplus_sysfs_write(fp, kobj, buf, off, count,
-			sizeof(struct koneplus_talk), KONEPLUS_COMMAND_TALK);
+#define KONEPLUS_SYSFS_W(thingy, THINGY) \
+static ssize_t koneplus_sysfs_write_ ## thingy(struct file *fp, \
+		struct kobject *kobj, struct bin_attribute *attr, char *buf, \
+		loff_t off, size_t count) \
+{ \
+	return koneplus_sysfs_write(fp, kobj, buf, off, count, \
+			KONEPLUS_SIZE_ ## THINGY, KONEPLUS_COMMAND_ ## THINGY); \
 }
 
-static ssize_t koneplus_sysfs_write_macro(struct file *fp,
-		struct kobject *kobj, struct bin_attribute *attr, char *buf,
-		loff_t off, size_t count)
-{
-	return koneplus_sysfs_write(fp, kobj, buf, off, count,
-			sizeof(struct koneplus_macro), KONEPLUS_COMMAND_MACRO);
+#define KONEPLUS_SYSFS_R(thingy, THINGY) \
+static ssize_t koneplus_sysfs_read_ ## thingy(struct file *fp, \
+		struct kobject *kobj, struct bin_attribute *attr, char *buf, \
+		loff_t off, size_t count) \
+{ \
+	return koneplus_sysfs_read(fp, kobj, buf, off, count, \
+			KONEPLUS_SIZE_ ## THINGY, KONEPLUS_COMMAND_ ## THINGY); \
 }
 
-static ssize_t koneplus_sysfs_read_sensor(struct file *fp,
-		struct kobject *kobj, struct bin_attribute *attr, char *buf,
-		loff_t off, size_t count)
-{
-	return koneplus_sysfs_read(fp, kobj, buf, off, count,
-			sizeof(struct koneplus_sensor), KONEPLUS_COMMAND_SENSOR);
+#define KONEPLUS_SYSFS_RW(thingy, THINGY) \
+KONEPLUS_SYSFS_W(thingy, THINGY) \
+KONEPLUS_SYSFS_R(thingy, THINGY)
+
+#define KONEPLUS_BIN_ATTRIBUTE_RW(thingy, THINGY) \
+{ \
+	.attr = { .name = #thingy, .mode = 0660 }, \
+	.size = KONEPLUS_SIZE_ ## THINGY, \
+	.read = koneplus_sysfs_read_ ## thingy, \
+	.write = koneplus_sysfs_write_ ## thingy \
 }
 
-static ssize_t koneplus_sysfs_write_sensor(struct file *fp,
-		struct kobject *kobj, struct bin_attribute *attr, char *buf,
-		loff_t off, size_t count)
-{
-	return koneplus_sysfs_write(fp, kobj, buf, off, count,
-			sizeof(struct koneplus_sensor), KONEPLUS_COMMAND_SENSOR);
+#define KONEPLUS_BIN_ATTRIBUTE_R(thingy, THINGY) \
+{ \
+	.attr = { .name = #thingy, .mode = 0440 }, \
+	.size = KONEPLUS_SIZE_ ## THINGY, \
+	.read = koneplus_sysfs_read_ ## thingy, \
 }
 
-static ssize_t koneplus_sysfs_write_tcu(struct file *fp,
-		struct kobject *kobj, struct bin_attribute *attr, char *buf,
-		loff_t off, size_t count)
-{
-	return koneplus_sysfs_write(fp, kobj, buf, off, count,
-			sizeof(struct koneplus_tcu), KONEPLUS_COMMAND_TCU);
+#define KONEPLUS_BIN_ATTRIBUTE_W(thingy, THINGY) \
+{ \
+	.attr = { .name = #thingy, .mode = 0220 }, \
+	.size = KONEPLUS_SIZE_ ## THINGY, \
+	.write = koneplus_sysfs_write_ ## thingy \
 }
 
-static ssize_t koneplus_sysfs_read_tcu_image(struct file *fp,
-		struct kobject *kobj, struct bin_attribute *attr, char *buf,
-		loff_t off, size_t count)
-{
-	return koneplus_sysfs_read(fp, kobj, buf, off, count,
-			sizeof(struct koneplus_tcu_image), KONEPLUS_COMMAND_TCU);
-}
+KONEPLUS_SYSFS_W(control, CONTROL)
+KONEPLUS_SYSFS_RW(info, INFO)
+KONEPLUS_SYSFS_W(talk, TALK)
+KONEPLUS_SYSFS_W(macro, MACRO)
+KONEPLUS_SYSFS_RW(sensor, SENSOR)
+KONEPLUS_SYSFS_RW(tcu, TCU)
+KONEPLUS_SYSFS_R(tcu_image, TCU_IMAGE)
+KONEPLUS_SYSFS_RW(profile_settings, PROFILE_SETTINGS)
+KONEPLUS_SYSFS_RW(profile_buttons, PROFILE_BUTTONS)
 
 static ssize_t koneplus_sysfs_read_profilex_settings(struct file *fp,
 		struct kobject *kobj, struct bin_attribute *attr, char *buf,
@@ -236,57 +193,17 @@
 {
 	struct device *dev =
 			container_of(kobj, struct device, kobj)->parent->parent;
-	struct koneplus_device *koneplus = hid_get_drvdata(dev_get_drvdata(dev));
-
-	if (off >= sizeof(struct koneplus_profile_settings))
-		return 0;
-
-	if (off + count > sizeof(struct koneplus_profile_settings))
-		count = sizeof(struct koneplus_profile_settings) - off;
-
-	mutex_lock(&koneplus->koneplus_lock);
-	memcpy(buf, ((char const *)&koneplus->profile_settings[*(uint *)(attr->private)]) + off,
-			count);
-	mutex_unlock(&koneplus->koneplus_lock);
-
-	return count;
-}
-
-static ssize_t koneplus_sysfs_write_profile_settings(struct file *fp,
-		struct kobject *kobj, struct bin_attribute *attr, char *buf,
-		loff_t off, size_t count)
-{
-	struct device *dev =
-			container_of(kobj, struct device, kobj)->parent->parent;
-	struct koneplus_device *koneplus = hid_get_drvdata(dev_get_drvdata(dev));
 	struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
-	int retval = 0;
-	int difference;
-	int profile_number;
-	struct koneplus_profile_settings *profile_settings;
+	ssize_t retval;
 
-	if (off != 0 || count != sizeof(struct koneplus_profile_settings))
-		return -EINVAL;
-
-	profile_number = ((struct koneplus_profile_settings const *)buf)->number;
-	profile_settings = &koneplus->profile_settings[profile_number];
-
-	mutex_lock(&koneplus->koneplus_lock);
-	difference = memcmp(buf, profile_settings,
-			sizeof(struct koneplus_profile_settings));
-	if (difference) {
-		retval = koneplus_set_profile_settings(usb_dev,
-				(struct koneplus_profile_settings const *)buf);
-		if (!retval)
-			memcpy(profile_settings, buf,
-					sizeof(struct koneplus_profile_settings));
-	}
-	mutex_unlock(&koneplus->koneplus_lock);
-
+	retval = koneplus_send_control(usb_dev, *(uint *)(attr->private),
+			KONEPLUS_CONTROL_REQUEST_PROFILE_SETTINGS);
 	if (retval)
 		return retval;
 
-	return sizeof(struct koneplus_profile_settings);
+	return koneplus_sysfs_read(fp, kobj, buf, off, count,
+			KONEPLUS_SIZE_PROFILE_SETTINGS,
+			KONEPLUS_COMMAND_PROFILE_SETTINGS);
 }
 
 static ssize_t koneplus_sysfs_read_profilex_buttons(struct file *fp,
@@ -295,57 +212,17 @@
 {
 	struct device *dev =
 			container_of(kobj, struct device, kobj)->parent->parent;
-	struct koneplus_device *koneplus = hid_get_drvdata(dev_get_drvdata(dev));
-
-	if (off >= sizeof(struct koneplus_profile_buttons))
-		return 0;
-
-	if (off + count > sizeof(struct koneplus_profile_buttons))
-		count = sizeof(struct koneplus_profile_buttons) - off;
-
-	mutex_lock(&koneplus->koneplus_lock);
-	memcpy(buf, ((char const *)&koneplus->profile_buttons[*(uint *)(attr->private)]) + off,
-			count);
-	mutex_unlock(&koneplus->koneplus_lock);
-
-	return count;
-}
-
-static ssize_t koneplus_sysfs_write_profile_buttons(struct file *fp,
-		struct kobject *kobj, struct bin_attribute *attr, char *buf,
-		loff_t off, size_t count)
-{
-	struct device *dev =
-			container_of(kobj, struct device, kobj)->parent->parent;
-	struct koneplus_device *koneplus = hid_get_drvdata(dev_get_drvdata(dev));
 	struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
-	int retval = 0;
-	int difference;
-	uint profile_number;
-	struct koneplus_profile_buttons *profile_buttons;
+	ssize_t retval;
 
-	if (off != 0 || count != sizeof(struct koneplus_profile_buttons))
-		return -EINVAL;
-
-	profile_number = ((struct koneplus_profile_buttons const *)buf)->number;
-	profile_buttons = &koneplus->profile_buttons[profile_number];
-
-	mutex_lock(&koneplus->koneplus_lock);
-	difference = memcmp(buf, profile_buttons,
-			sizeof(struct koneplus_profile_buttons));
-	if (difference) {
-		retval = koneplus_set_profile_buttons(usb_dev,
-				(struct koneplus_profile_buttons const *)buf);
-		if (!retval)
-			memcpy(profile_buttons, buf,
-					sizeof(struct koneplus_profile_buttons));
-	}
-	mutex_unlock(&koneplus->koneplus_lock);
-
+	retval = koneplus_send_control(usb_dev, *(uint *)(attr->private),
+			KONEPLUS_CONTROL_REQUEST_PROFILE_BUTTONS);
 	if (retval)
 		return retval;
 
-	return sizeof(struct koneplus_profile_buttons);
+	return koneplus_sysfs_read(fp, kobj, buf, off, count,
+			KONEPLUS_SIZE_PROFILE_BUTTONS,
+			KONEPLUS_COMMAND_PROFILE_BUTTONS);
 }
 
 static ssize_t koneplus_sysfs_show_actual_profile(struct device *dev,
@@ -401,9 +278,20 @@
 static ssize_t koneplus_sysfs_show_firmware_version(struct device *dev,
 		struct device_attribute *attr, char *buf)
 {
-	struct koneplus_device *koneplus =
-			hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
-	return snprintf(buf, PAGE_SIZE, "%d\n", koneplus->info.firmware_version);
+	struct koneplus_device *koneplus;
+	struct usb_device *usb_dev;
+	struct koneplus_info info;
+
+	dev = dev->parent->parent;
+	koneplus = hid_get_drvdata(dev_get_drvdata(dev));
+	usb_dev = interface_to_usbdev(to_usb_interface(dev));
+
+	mutex_lock(&koneplus->koneplus_lock);
+	roccat_common2_receive(usb_dev, KONEPLUS_COMMAND_INFO,
+			&info, KONEPLUS_SIZE_INFO);
+	mutex_unlock(&koneplus->koneplus_lock);
+
+	return snprintf(buf, PAGE_SIZE, "%d\n", info.firmware_version);
 }
 
 static struct device_attribute koneplus_attributes[] = {
@@ -419,132 +307,85 @@
 };
 
 static struct bin_attribute koneplus_bin_attributes[] = {
-	{
-		.attr = { .name = "sensor", .mode = 0660 },
-		.size = sizeof(struct koneplus_sensor),
-		.read = koneplus_sysfs_read_sensor,
-		.write = koneplus_sysfs_write_sensor
-	},
-	{
-		.attr = { .name = "tcu", .mode = 0220 },
-		.size = sizeof(struct koneplus_tcu),
-		.write = koneplus_sysfs_write_tcu
-	},
-	{
-		.attr = { .name = "tcu_image", .mode = 0440 },
-		.size = sizeof(struct koneplus_tcu_image),
-		.read = koneplus_sysfs_read_tcu_image
-	},
-	{
-		.attr = { .name = "profile_settings", .mode = 0220 },
-		.size = sizeof(struct koneplus_profile_settings),
-		.write = koneplus_sysfs_write_profile_settings
-	},
+	KONEPLUS_BIN_ATTRIBUTE_W(control, CONTROL),
+	KONEPLUS_BIN_ATTRIBUTE_RW(info, INFO),
+	KONEPLUS_BIN_ATTRIBUTE_W(talk, TALK),
+	KONEPLUS_BIN_ATTRIBUTE_W(macro, MACRO),
+	KONEPLUS_BIN_ATTRIBUTE_RW(sensor, SENSOR),
+	KONEPLUS_BIN_ATTRIBUTE_RW(tcu, TCU),
+	KONEPLUS_BIN_ATTRIBUTE_R(tcu_image, TCU_IMAGE),
+	KONEPLUS_BIN_ATTRIBUTE_RW(profile_settings, PROFILE_SETTINGS),
+	KONEPLUS_BIN_ATTRIBUTE_RW(profile_buttons, PROFILE_BUTTONS),
 	{
 		.attr = { .name = "profile1_settings", .mode = 0440 },
-		.size = sizeof(struct koneplus_profile_settings),
+		.size = KONEPLUS_SIZE_PROFILE_SETTINGS,
 		.read = koneplus_sysfs_read_profilex_settings,
 		.private = &profile_numbers[0]
 	},
 	{
 		.attr = { .name = "profile2_settings", .mode = 0440 },
-		.size = sizeof(struct koneplus_profile_settings),
+		.size = KONEPLUS_SIZE_PROFILE_SETTINGS,
 		.read = koneplus_sysfs_read_profilex_settings,
 		.private = &profile_numbers[1]
 	},
 	{
 		.attr = { .name = "profile3_settings", .mode = 0440 },
-		.size = sizeof(struct koneplus_profile_settings),
+		.size = KONEPLUS_SIZE_PROFILE_SETTINGS,
 		.read = koneplus_sysfs_read_profilex_settings,
 		.private = &profile_numbers[2]
 	},
 	{
 		.attr = { .name = "profile4_settings", .mode = 0440 },
-		.size = sizeof(struct koneplus_profile_settings),
+		.size = KONEPLUS_SIZE_PROFILE_SETTINGS,
 		.read = koneplus_sysfs_read_profilex_settings,
 		.private = &profile_numbers[3]
 	},
 	{
 		.attr = { .name = "profile5_settings", .mode = 0440 },
-		.size = sizeof(struct koneplus_profile_settings),
+		.size = KONEPLUS_SIZE_PROFILE_SETTINGS,
 		.read = koneplus_sysfs_read_profilex_settings,
 		.private = &profile_numbers[4]
 	},
 	{
-		.attr = { .name = "profile_buttons", .mode = 0220 },
-		.size = sizeof(struct koneplus_profile_buttons),
-		.write = koneplus_sysfs_write_profile_buttons
-	},
-	{
 		.attr = { .name = "profile1_buttons", .mode = 0440 },
-		.size = sizeof(struct koneplus_profile_buttons),
+		.size = KONEPLUS_SIZE_PROFILE_BUTTONS,
 		.read = koneplus_sysfs_read_profilex_buttons,
 		.private = &profile_numbers[0]
 	},
 	{
 		.attr = { .name = "profile2_buttons", .mode = 0440 },
-		.size = sizeof(struct koneplus_profile_buttons),
+		.size = KONEPLUS_SIZE_PROFILE_BUTTONS,
 		.read = koneplus_sysfs_read_profilex_buttons,
 		.private = &profile_numbers[1]
 	},
 	{
 		.attr = { .name = "profile3_buttons", .mode = 0440 },
-		.size = sizeof(struct koneplus_profile_buttons),
+		.size = KONEPLUS_SIZE_PROFILE_BUTTONS,
 		.read = koneplus_sysfs_read_profilex_buttons,
 		.private = &profile_numbers[2]
 	},
 	{
 		.attr = { .name = "profile4_buttons", .mode = 0440 },
-		.size = sizeof(struct koneplus_profile_buttons),
+		.size = KONEPLUS_SIZE_PROFILE_BUTTONS,
 		.read = koneplus_sysfs_read_profilex_buttons,
 		.private = &profile_numbers[3]
 	},
 	{
 		.attr = { .name = "profile5_buttons", .mode = 0440 },
-		.size = sizeof(struct koneplus_profile_buttons),
+		.size = KONEPLUS_SIZE_PROFILE_BUTTONS,
 		.read = koneplus_sysfs_read_profilex_buttons,
 		.private = &profile_numbers[4]
 	},
-	{
-		.attr = { .name = "macro", .mode = 0220 },
-		.size = sizeof(struct koneplus_macro),
-		.write = koneplus_sysfs_write_macro
-	},
-	{
-		.attr = { .name = "talk", .mode = 0220 },
-		.size = sizeof(struct koneplus_talk),
-		.write = koneplus_sysfs_write_talk
-	},
 	__ATTR_NULL
 };
 
 static int koneplus_init_koneplus_device_struct(struct usb_device *usb_dev,
 		struct koneplus_device *koneplus)
 {
-	int retval, i;
-	static uint wait = 200;
+	int retval;
 
 	mutex_init(&koneplus->koneplus_lock);
 
-	retval = koneplus_get_info(usb_dev, &koneplus->info);
-	if (retval)
-		return retval;
-
-	for (i = 0; i < 5; ++i) {
-		msleep(wait);
-		retval = koneplus_get_profile_settings(usb_dev,
-				&koneplus->profile_settings[i], i);
-		if (retval)
-			return retval;
-
-		msleep(wait);
-		retval = koneplus_get_profile_buttons(usb_dev,
-				&koneplus->profile_buttons[i], i);
-		if (retval)
-			return retval;
-	}
-
-	msleep(wait);
 	retval = koneplus_get_actual_profile(usb_dev);
 	if (retval < 0)
 		return retval;
@@ -709,6 +550,7 @@
 
 static const struct hid_device_id koneplus_devices[] = {
 	{ HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KONEPLUS) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KONEXTD) },
 	{ }
 };
 
@@ -749,5 +591,5 @@
 module_exit(koneplus_exit);
 
 MODULE_AUTHOR("Stefan Achatz");
-MODULE_DESCRIPTION("USB Roccat Kone[+] driver");
+MODULE_DESCRIPTION("USB Roccat Kone[+]/XTD driver");
 MODULE_LICENSE("GPL v2");
diff --git a/drivers/hid/hid-roccat-koneplus.h b/drivers/hid/hid-roccat-koneplus.h
index 7074b2a..af7f57e 100644
--- a/drivers/hid/hid-roccat-koneplus.h
+++ b/drivers/hid/hid-roccat-koneplus.h
@@ -14,11 +14,19 @@
 
 #include <linux/types.h>
 
-struct koneplus_talk {
-	uint8_t command; /* KONEPLUS_COMMAND_TALK */
-	uint8_t size; /* always 0x10 */
-	uint8_t data[14];
-} __packed;
+enum {
+	KONEPLUS_SIZE_ACTUAL_PROFILE = 0x03,
+	KONEPLUS_SIZE_CONTROL = 0x03,
+	KONEPLUS_SIZE_FIRMWARE_WRITE = 0x0402,
+	KONEPLUS_SIZE_INFO = 0x06,
+	KONEPLUS_SIZE_MACRO = 0x0822,
+	KONEPLUS_SIZE_PROFILE_SETTINGS = 0x2b,
+	KONEPLUS_SIZE_PROFILE_BUTTONS = 0x4d,
+	KONEPLUS_SIZE_SENSOR = 0x06,
+	KONEPLUS_SIZE_TALK = 0x10,
+	KONEPLUS_SIZE_TCU = 0x04,
+	KONEPLUS_SIZE_TCU_IMAGE = 0x0404,
+};
 
 enum koneplus_control_requests {
 	KONEPLUS_CONTROL_REQUEST_PROFILE_SETTINGS = 0x80,
@@ -31,45 +39,6 @@
 	uint8_t actual_profile; /* Range 0-4! */
 } __attribute__ ((__packed__));
 
-struct koneplus_profile_settings {
-	uint8_t command; /* KONEPLUS_COMMAND_PROFILE_SETTINGS */
-	uint8_t size; /* always 43 */
-	uint8_t number; /* range 0-4 */
-	uint8_t advanced_sensitivity;
-	uint8_t sensitivity_x;
-	uint8_t sensitivity_y;
-	uint8_t cpi_levels_enabled;
-	uint8_t cpi_levels_x[5];
-	uint8_t cpi_startup_level; /* range 0-4 */
-	uint8_t cpi_levels_y[5]; /* range 1-60 means 100-6000 cpi */
-	uint8_t unknown1;
-	uint8_t polling_rate;
-	uint8_t lights_enabled;
-	uint8_t light_effect_mode;
-	uint8_t color_flow_effect;
-	uint8_t light_effect_type;
-	uint8_t light_effect_speed;
-	uint8_t lights[16];
-	uint16_t checksum;
-} __attribute__ ((__packed__));
-
-struct koneplus_profile_buttons {
-	uint8_t command; /* KONEPLUS_COMMAND_PROFILE_BUTTONS */
-	uint8_t size; /* always 77 */
-	uint8_t number; /* range 0-4 */
-	uint8_t data[72];
-	uint16_t checksum;
-} __attribute__ ((__packed__));
-
-struct koneplus_macro {
-	uint8_t command; /* KONEPLUS_COMMAND_MACRO */
-	uint16_t size; /* always 0x822 little endian */
-	uint8_t profile; /* range 0-4 */
-	uint8_t button; /* range 0-23 */
-	uint8_t data[2075];
-	uint16_t checksum;
-} __attribute__ ((__packed__));
-
 struct koneplus_info {
 	uint8_t command; /* KONEPLUS_COMMAND_INFO */
 	uint8_t size; /* always 6 */
@@ -77,51 +46,15 @@
 	uint8_t unknown[3];
 } __attribute__ ((__packed__));
 
-struct koneplus_e {
-	uint8_t command; /* KONEPLUS_COMMAND_E */
-	uint8_t size; /* always 3 */
-	uint8_t unknown; /* TODO 1; 0 before firmware update */
-} __attribute__ ((__packed__));
-
-struct koneplus_sensor {
-	uint8_t command;  /* KONEPLUS_COMMAND_SENSOR */
-	uint8_t size; /* always 6 */
-	uint8_t data[4];
-} __attribute__ ((__packed__));
-
-struct koneplus_firmware_write {
-	uint8_t command; /* KONEPLUS_COMMAND_FIRMWARE_WRITE */
-	uint8_t unknown[1025];
-} __attribute__ ((__packed__));
-
-struct koneplus_firmware_write_control {
-	uint8_t command; /* KONEPLUS_COMMAND_FIRMWARE_WRITE_CONTROL */
-	/*
-	 * value is 1 on success
-	 * 3 means "not finished yet"
-	 */
-	uint8_t value;
-	uint8_t unknown; /* always 0x75 */
-} __attribute__ ((__packed__));
-
-struct koneplus_tcu {
-	uint16_t usb_command; /* KONEPLUS_USB_COMMAND_TCU */
-	uint8_t data[2];
-} __attribute__ ((__packed__));
-
-struct koneplus_tcu_image {
-	uint16_t usb_command; /* KONEPLUS_USB_COMMAND_TCU */
-	uint8_t data[1024];
-	uint16_t checksum;
-} __attribute__ ((__packed__));
-
 enum koneplus_commands {
 	KONEPLUS_COMMAND_ACTUAL_PROFILE = 0x5,
+	KONEPLUS_COMMAND_CONTROL = 0x4,
 	KONEPLUS_COMMAND_PROFILE_SETTINGS = 0x6,
 	KONEPLUS_COMMAND_PROFILE_BUTTONS = 0x7,
 	KONEPLUS_COMMAND_MACRO = 0x8,
 	KONEPLUS_COMMAND_INFO = 0x9,
 	KONEPLUS_COMMAND_TCU = 0xc,
+	KONEPLUS_COMMAND_TCU_IMAGE = 0xc,
 	KONEPLUS_COMMAND_E = 0xe,
 	KONEPLUS_COMMAND_SENSOR = 0xf,
 	KONEPLUS_COMMAND_TALK = 0x10,
@@ -187,10 +120,6 @@
 	int chrdev_minor;
 
 	struct mutex koneplus_lock;
-
-	struct koneplus_info info;
-	struct koneplus_profile_settings profile_settings[5];
-	struct koneplus_profile_buttons profile_buttons[5];
 };
 
 #endif
diff --git a/drivers/hid/hid-roccat-kovaplus.c b/drivers/hid/hid-roccat-kovaplus.c
index ca6527a..b8b3778 100644
--- a/drivers/hid/hid-roccat-kovaplus.c
+++ b/drivers/hid/hid-roccat-kovaplus.c
@@ -70,13 +70,6 @@
 	return kovaplus_send_control(usb_dev, number, request);
 }
 
-static int kovaplus_get_info(struct usb_device *usb_dev,
-		struct kovaplus_info *buf)
-{
-	return roccat_common2_receive(usb_dev, KOVAPLUS_COMMAND_INFO,
-			buf, sizeof(struct kovaplus_info));
-}
-
 static int kovaplus_get_profile_settings(struct usb_device *usb_dev,
 		struct kovaplus_profile_settings *buf, uint number)
 {
@@ -88,15 +81,7 @@
 		return retval;
 
 	return roccat_common2_receive(usb_dev, KOVAPLUS_COMMAND_PROFILE_SETTINGS,
-			buf, sizeof(struct kovaplus_profile_settings));
-}
-
-static int kovaplus_set_profile_settings(struct usb_device *usb_dev,
-		struct kovaplus_profile_settings const *settings)
-{
-	return roccat_common2_send_with_status(usb_dev,
-			KOVAPLUS_COMMAND_PROFILE_SETTINGS,
-			settings, sizeof(struct kovaplus_profile_settings));
+			buf, KOVAPLUS_SIZE_PROFILE_SETTINGS);
 }
 
 static int kovaplus_get_profile_buttons(struct usb_device *usb_dev,
@@ -110,15 +95,7 @@
 		return retval;
 
 	return roccat_common2_receive(usb_dev, KOVAPLUS_COMMAND_PROFILE_BUTTONS,
-			buf, sizeof(struct kovaplus_profile_buttons));
-}
-
-static int kovaplus_set_profile_buttons(struct usb_device *usb_dev,
-		struct kovaplus_profile_buttons const *buttons)
-{
-	return roccat_common2_send_with_status(usb_dev,
-			KOVAPLUS_COMMAND_PROFILE_BUTTONS,
-			buttons, sizeof(struct kovaplus_profile_buttons));
+			buf, KOVAPLUS_SIZE_PROFILE_BUTTONS);
 }
 
 /* retval is 0-4 on success, < 0 on error */
@@ -147,63 +124,122 @@
 			&buf, sizeof(struct kovaplus_actual_profile));
 }
 
+static ssize_t kovaplus_sysfs_read(struct file *fp, struct kobject *kobj,
+		char *buf, loff_t off, size_t count,
+		size_t real_size, uint command)
+{
+	struct device *dev =
+			container_of(kobj, struct device, kobj)->parent->parent;
+	struct kovaplus_device *kovaplus = hid_get_drvdata(dev_get_drvdata(dev));
+	struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
+	int retval;
+
+	if (off >= real_size)
+		return 0;
+
+	if (off != 0 || count != real_size)
+		return -EINVAL;
+
+	mutex_lock(&kovaplus->kovaplus_lock);
+	retval = roccat_common2_receive(usb_dev, command, buf, real_size);
+	mutex_unlock(&kovaplus->kovaplus_lock);
+
+	if (retval)
+		return retval;
+
+	return real_size;
+}
+
+static ssize_t kovaplus_sysfs_write(struct file *fp, struct kobject *kobj,
+		void const *buf, loff_t off, size_t count,
+		size_t real_size, uint command)
+{
+	struct device *dev =
+			container_of(kobj, struct device, kobj)->parent->parent;
+	struct kovaplus_device *kovaplus = hid_get_drvdata(dev_get_drvdata(dev));
+	struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
+	int retval;
+
+	if (off != 0 || count != real_size)
+		return -EINVAL;
+
+	mutex_lock(&kovaplus->kovaplus_lock);
+	retval = roccat_common2_send_with_status(usb_dev, command,
+			buf, real_size);
+	mutex_unlock(&kovaplus->kovaplus_lock);
+
+	if (retval)
+		return retval;
+
+	return real_size;
+}
+
+#define KOVAPLUS_SYSFS_W(thingy, THINGY) \
+static ssize_t kovaplus_sysfs_write_ ## thingy(struct file *fp, \
+		struct kobject *kobj, struct bin_attribute *attr, char *buf, \
+		loff_t off, size_t count) \
+{ \
+	return kovaplus_sysfs_write(fp, kobj, buf, off, count, \
+			KOVAPLUS_SIZE_ ## THINGY, KOVAPLUS_COMMAND_ ## THINGY); \
+}
+
+#define KOVAPLUS_SYSFS_R(thingy, THINGY) \
+static ssize_t kovaplus_sysfs_read_ ## thingy(struct file *fp, \
+		struct kobject *kobj, struct bin_attribute *attr, char *buf, \
+		loff_t off, size_t count) \
+{ \
+	return kovaplus_sysfs_read(fp, kobj, buf, off, count, \
+			KOVAPLUS_SIZE_ ## THINGY, KOVAPLUS_COMMAND_ ## THINGY); \
+}
+
+#define KOVAPLUS_SYSFS_RW(thingy, THINGY) \
+KOVAPLUS_SYSFS_W(thingy, THINGY) \
+KOVAPLUS_SYSFS_R(thingy, THINGY)
+
+#define KOVAPLUS_BIN_ATTRIBUTE_RW(thingy, THINGY) \
+{ \
+	.attr = { .name = #thingy, .mode = 0660 }, \
+	.size = KOVAPLUS_SIZE_ ## THINGY, \
+	.read = kovaplus_sysfs_read_ ## thingy, \
+	.write = kovaplus_sysfs_write_ ## thingy \
+}
+
+#define KOVAPLUS_BIN_ATTRIBUTE_R(thingy, THINGY) \
+{ \
+	.attr = { .name = #thingy, .mode = 0440 }, \
+	.size = KOVAPLUS_SIZE_ ## THINGY, \
+	.read = kovaplus_sysfs_read_ ## thingy, \
+}
+
+#define KOVAPLUS_BIN_ATTRIBUTE_W(thingy, THINGY) \
+{ \
+	.attr = { .name = #thingy, .mode = 0220 }, \
+	.size = KOVAPLUS_SIZE_ ## THINGY, \
+	.write = kovaplus_sysfs_write_ ## thingy \
+}
+
+KOVAPLUS_SYSFS_W(control, CONTROL)
+KOVAPLUS_SYSFS_RW(info, INFO)
+KOVAPLUS_SYSFS_RW(profile_settings, PROFILE_SETTINGS)
+KOVAPLUS_SYSFS_RW(profile_buttons, PROFILE_BUTTONS)
+
 static ssize_t kovaplus_sysfs_read_profilex_settings(struct file *fp,
 		struct kobject *kobj, struct bin_attribute *attr, char *buf,
 		loff_t off, size_t count)
 {
 	struct device *dev =
 			container_of(kobj, struct device, kobj)->parent->parent;
-	struct kovaplus_device *kovaplus = hid_get_drvdata(dev_get_drvdata(dev));
-
-	if (off >= sizeof(struct kovaplus_profile_settings))
-		return 0;
-
-	if (off + count > sizeof(struct kovaplus_profile_settings))
-		count = sizeof(struct kovaplus_profile_settings) - off;
-
-	mutex_lock(&kovaplus->kovaplus_lock);
-	memcpy(buf, ((char const *)&kovaplus->profile_settings[*(uint *)(attr->private)]) + off,
-			count);
-	mutex_unlock(&kovaplus->kovaplus_lock);
-
-	return count;
-}
-
-static ssize_t kovaplus_sysfs_write_profile_settings(struct file *fp,
-		struct kobject *kobj, struct bin_attribute *attr, char *buf,
-		loff_t off, size_t count)
-{
-	struct device *dev =
-			container_of(kobj, struct device, kobj)->parent->parent;
-	struct kovaplus_device *kovaplus = hid_get_drvdata(dev_get_drvdata(dev));
 	struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
-	int retval = 0;
-	int difference;
-	int profile_index;
-	struct kovaplus_profile_settings *profile_settings;
+	ssize_t retval;
 
-	if (off != 0 || count != sizeof(struct kovaplus_profile_settings))
-		return -EINVAL;
-
-	profile_index = ((struct kovaplus_profile_settings const *)buf)->profile_index;
-	profile_settings = &kovaplus->profile_settings[profile_index];
-
-	mutex_lock(&kovaplus->kovaplus_lock);
-	difference = memcmp(buf, profile_settings,
-			sizeof(struct kovaplus_profile_settings));
-	if (difference) {
-		retval = kovaplus_set_profile_settings(usb_dev,
-				(struct kovaplus_profile_settings const *)buf);
-		if (!retval)
-			memcpy(profile_settings, buf,
-					sizeof(struct kovaplus_profile_settings));
-	}
-	mutex_unlock(&kovaplus->kovaplus_lock);
-
+	retval = kovaplus_select_profile(usb_dev, *(uint *)(attr->private),
+			KOVAPLUS_CONTROL_REQUEST_PROFILE_SETTINGS);
 	if (retval)
 		return retval;
 
-	return sizeof(struct kovaplus_profile_settings);
+	return kovaplus_sysfs_read(fp, kobj, buf, off, count,
+			KOVAPLUS_SIZE_PROFILE_SETTINGS,
+			KOVAPLUS_COMMAND_PROFILE_SETTINGS);
 }
 
 static ssize_t kovaplus_sysfs_read_profilex_buttons(struct file *fp,
@@ -212,57 +248,17 @@
 {
 	struct device *dev =
 			container_of(kobj, struct device, kobj)->parent->parent;
-	struct kovaplus_device *kovaplus = hid_get_drvdata(dev_get_drvdata(dev));
-
-	if (off >= sizeof(struct kovaplus_profile_buttons))
-		return 0;
-
-	if (off + count > sizeof(struct kovaplus_profile_buttons))
-		count = sizeof(struct kovaplus_profile_buttons) - off;
-
-	mutex_lock(&kovaplus->kovaplus_lock);
-	memcpy(buf, ((char const *)&kovaplus->profile_buttons[*(uint *)(attr->private)]) + off,
-			count);
-	mutex_unlock(&kovaplus->kovaplus_lock);
-
-	return count;
-}
-
-static ssize_t kovaplus_sysfs_write_profile_buttons(struct file *fp,
-		struct kobject *kobj, struct bin_attribute *attr, char *buf,
-		loff_t off, size_t count)
-{
-	struct device *dev =
-			container_of(kobj, struct device, kobj)->parent->parent;
-	struct kovaplus_device *kovaplus = hid_get_drvdata(dev_get_drvdata(dev));
 	struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
-	int retval = 0;
-	int difference;
-	uint profile_index;
-	struct kovaplus_profile_buttons *profile_buttons;
+	ssize_t retval;
 
-	if (off != 0 || count != sizeof(struct kovaplus_profile_buttons))
-		return -EINVAL;
-
-	profile_index = ((struct kovaplus_profile_buttons const *)buf)->profile_index;
-	profile_buttons = &kovaplus->profile_buttons[profile_index];
-
-	mutex_lock(&kovaplus->kovaplus_lock);
-	difference = memcmp(buf, profile_buttons,
-			sizeof(struct kovaplus_profile_buttons));
-	if (difference) {
-		retval = kovaplus_set_profile_buttons(usb_dev,
-				(struct kovaplus_profile_buttons const *)buf);
-		if (!retval)
-			memcpy(profile_buttons, buf,
-					sizeof(struct kovaplus_profile_buttons));
-	}
-	mutex_unlock(&kovaplus->kovaplus_lock);
-
+	retval = kovaplus_select_profile(usb_dev, *(uint *)(attr->private),
+			KOVAPLUS_CONTROL_REQUEST_PROFILE_BUTTONS);
 	if (retval)
 		return retval;
 
-	return sizeof(struct kovaplus_profile_buttons);
+	return kovaplus_sysfs_read(fp, kobj, buf, off, count,
+			KOVAPLUS_SIZE_PROFILE_BUTTONS,
+			KOVAPLUS_COMMAND_PROFILE_BUTTONS);
 }
 
 static ssize_t kovaplus_sysfs_show_actual_profile(struct device *dev,
@@ -342,9 +338,20 @@
 static ssize_t kovaplus_sysfs_show_firmware_version(struct device *dev,
 		struct device_attribute *attr, char *buf)
 {
-	struct kovaplus_device *kovaplus =
-			hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
-	return snprintf(buf, PAGE_SIZE, "%d\n", kovaplus->info.firmware_version);
+	struct kovaplus_device *kovaplus;
+	struct usb_device *usb_dev;
+	struct kovaplus_info info;
+
+	dev = dev->parent->parent;
+	kovaplus = hid_get_drvdata(dev_get_drvdata(dev));
+	usb_dev = interface_to_usbdev(to_usb_interface(dev));
+
+	mutex_lock(&kovaplus->kovaplus_lock);
+	roccat_common2_receive(usb_dev, KOVAPLUS_COMMAND_INFO,
+			&info, KOVAPLUS_SIZE_INFO);
+	mutex_unlock(&kovaplus->kovaplus_lock);
+
+	return snprintf(buf, PAGE_SIZE, "%d\n", info.firmware_version);
 }
 
 static struct device_attribute kovaplus_attributes[] = {
@@ -363,73 +370,67 @@
 };
 
 static struct bin_attribute kovaplus_bin_attributes[] = {
-	{
-		.attr = { .name = "profile_settings", .mode = 0220 },
-		.size = sizeof(struct kovaplus_profile_settings),
-		.write = kovaplus_sysfs_write_profile_settings
-	},
+	KOVAPLUS_BIN_ATTRIBUTE_W(control, CONTROL),
+	KOVAPLUS_BIN_ATTRIBUTE_RW(info, INFO),
+	KOVAPLUS_BIN_ATTRIBUTE_RW(profile_settings, PROFILE_SETTINGS),
+	KOVAPLUS_BIN_ATTRIBUTE_RW(profile_buttons, PROFILE_BUTTONS),
 	{
 		.attr = { .name = "profile1_settings", .mode = 0440 },
-		.size = sizeof(struct kovaplus_profile_settings),
+		.size = KOVAPLUS_SIZE_PROFILE_SETTINGS,
 		.read = kovaplus_sysfs_read_profilex_settings,
 		.private = &profile_numbers[0]
 	},
 	{
 		.attr = { .name = "profile2_settings", .mode = 0440 },
-		.size = sizeof(struct kovaplus_profile_settings),
+		.size = KOVAPLUS_SIZE_PROFILE_SETTINGS,
 		.read = kovaplus_sysfs_read_profilex_settings,
 		.private = &profile_numbers[1]
 	},
 	{
 		.attr = { .name = "profile3_settings", .mode = 0440 },
-		.size = sizeof(struct kovaplus_profile_settings),
+		.size = KOVAPLUS_SIZE_PROFILE_SETTINGS,
 		.read = kovaplus_sysfs_read_profilex_settings,
 		.private = &profile_numbers[2]
 	},
 	{
 		.attr = { .name = "profile4_settings", .mode = 0440 },
-		.size = sizeof(struct kovaplus_profile_settings),
+		.size = KOVAPLUS_SIZE_PROFILE_SETTINGS,
 		.read = kovaplus_sysfs_read_profilex_settings,
 		.private = &profile_numbers[3]
 	},
 	{
 		.attr = { .name = "profile5_settings", .mode = 0440 },
-		.size = sizeof(struct kovaplus_profile_settings),
+		.size = KOVAPLUS_SIZE_PROFILE_SETTINGS,
 		.read = kovaplus_sysfs_read_profilex_settings,
 		.private = &profile_numbers[4]
 	},
 	{
-		.attr = { .name = "profile_buttons", .mode = 0220 },
-		.size = sizeof(struct kovaplus_profile_buttons),
-		.write = kovaplus_sysfs_write_profile_buttons
-	},
-	{
 		.attr = { .name = "profile1_buttons", .mode = 0440 },
-		.size = sizeof(struct kovaplus_profile_buttons),
+		.size = KOVAPLUS_SIZE_PROFILE_BUTTONS,
 		.read = kovaplus_sysfs_read_profilex_buttons,
 		.private = &profile_numbers[0]
 	},
 	{
 		.attr = { .name = "profile2_buttons", .mode = 0440 },
-		.size = sizeof(struct kovaplus_profile_buttons),
+		.size = KOVAPLUS_SIZE_PROFILE_BUTTONS,
 		.read = kovaplus_sysfs_read_profilex_buttons,
 		.private = &profile_numbers[1]
 	},
 	{
 		.attr = { .name = "profile3_buttons", .mode = 0440 },
-		.size = sizeof(struct kovaplus_profile_buttons),
+		.size = KOVAPLUS_SIZE_PROFILE_BUTTONS,
 		.read = kovaplus_sysfs_read_profilex_buttons,
 		.private = &profile_numbers[2]
 	},
 	{
 		.attr = { .name = "profile4_buttons", .mode = 0440 },
-		.size = sizeof(struct kovaplus_profile_buttons),
+		.size = KOVAPLUS_SIZE_PROFILE_BUTTONS,
 		.read = kovaplus_sysfs_read_profilex_buttons,
 		.private = &profile_numbers[3]
 	},
 	{
 		.attr = { .name = "profile5_buttons", .mode = 0440 },
-		.size = sizeof(struct kovaplus_profile_buttons),
+		.size = KOVAPLUS_SIZE_PROFILE_BUTTONS,
 		.read = kovaplus_sysfs_read_profilex_buttons,
 		.private = &profile_numbers[4]
 	},
@@ -444,10 +445,6 @@
 
 	mutex_init(&kovaplus->kovaplus_lock);
 
-	retval = kovaplus_get_info(usb_dev, &kovaplus->info);
-	if (retval)
-		return retval;
-
 	for (i = 0; i < 5; ++i) {
 		msleep(wait);
 		retval = kovaplus_get_profile_settings(usb_dev,
diff --git a/drivers/hid/hid-roccat-kovaplus.h b/drivers/hid/hid-roccat-kovaplus.h
index f82daa1..fbb7a16 100644
--- a/drivers/hid/hid-roccat-kovaplus.h
+++ b/drivers/hid/hid-roccat-kovaplus.h
@@ -14,6 +14,13 @@
 
 #include <linux/types.h>
 
+enum {
+	KOVAPLUS_SIZE_CONTROL = 0x03,
+	KOVAPLUS_SIZE_INFO = 0x06,
+	KOVAPLUS_SIZE_PROFILE_SETTINGS = 0x10,
+	KOVAPLUS_SIZE_PROFILE_BUTTONS = 0x17,
+};
+
 enum kovaplus_control_requests {
 	/* write; value = profile number range 0-4 */
 	KOVAPLUS_CONTROL_REQUEST_PROFILE_SETTINGS = 0x10,
@@ -53,15 +60,9 @@
 	uint8_t unknown[3];
 } __packed;
 
-/* writes 1 on plugin */
-struct kovaplus_a {
-	uint8_t command; /* KOVAPLUS_COMMAND_A */
-	uint8_t size; /* 3 */
-	uint8_t unknown;
-} __packed;
-
 enum kovaplus_commands {
 	KOVAPLUS_COMMAND_ACTUAL_PROFILE = 0x5,
+	KOVAPLUS_COMMAND_CONTROL = 0x4,
 	KOVAPLUS_COMMAND_PROFILE_SETTINGS = 0x6,
 	KOVAPLUS_COMMAND_PROFILE_BUTTONS = 0x7,
 	KOVAPLUS_COMMAND_INFO = 0x9,
@@ -125,7 +126,6 @@
 	int roccat_claimed;
 	int chrdev_minor;
 	struct mutex kovaplus_lock;
-	struct kovaplus_info info;
 	struct kovaplus_profile_settings profile_settings[5];
 	struct kovaplus_profile_buttons profile_buttons[5];
 };
diff --git a/drivers/hid/hid-roccat-lua.c b/drivers/hid/hid-roccat-lua.c
new file mode 100644
index 0000000..5084fb4
--- /dev/null
+++ b/drivers/hid/hid-roccat-lua.c
@@ -0,0 +1,227 @@
+/*
+ * Roccat Lua driver for Linux
+ *
+ * Copyright (c) 2012 Stefan Achatz <erazor_de@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.
+ */
+
+/*
+ * Roccat Lua is a gamer mouse which cpi, button and light settings can be
+ * configured.
+ */
+
+#include <linux/device.h>
+#include <linux/input.h>
+#include <linux/hid.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/hid-roccat.h>
+#include "hid-ids.h"
+#include "hid-roccat-common.h"
+#include "hid-roccat-lua.h"
+
+static ssize_t lua_sysfs_read(struct file *fp, struct kobject *kobj,
+		char *buf, loff_t off, size_t count,
+		size_t real_size, uint command)
+{
+	struct device *dev = container_of(kobj, struct device, kobj);
+	struct lua_device *lua = hid_get_drvdata(dev_get_drvdata(dev));
+	struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
+	int retval;
+
+	if (off >= real_size)
+		return 0;
+
+	if (off != 0 || count != real_size)
+		return -EINVAL;
+
+	mutex_lock(&lua->lua_lock);
+	retval = roccat_common2_receive(usb_dev, command, buf, real_size);
+	mutex_unlock(&lua->lua_lock);
+
+	return retval ? retval : real_size;
+}
+
+static ssize_t lua_sysfs_write(struct file *fp, struct kobject *kobj,
+		void const *buf, loff_t off, size_t count,
+		size_t real_size, uint command)
+{
+	struct device *dev = container_of(kobj, struct device, kobj);
+	struct lua_device *lua = hid_get_drvdata(dev_get_drvdata(dev));
+	struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
+	int retval;
+
+	if (off != 0 || count != real_size)
+		return -EINVAL;
+
+	mutex_lock(&lua->lua_lock);
+	retval = roccat_common2_send(usb_dev, command, (void *)buf, real_size);
+	mutex_unlock(&lua->lua_lock);
+
+	return retval ? retval : real_size;
+}
+
+#define LUA_SYSFS_W(thingy, THINGY) \
+static ssize_t lua_sysfs_write_ ## thingy(struct file *fp, \
+		struct kobject *kobj, struct bin_attribute *attr, \
+		char *buf, loff_t off, size_t count) \
+{ \
+	return lua_sysfs_write(fp, kobj, buf, off, count, \
+			LUA_SIZE_ ## THINGY, LUA_COMMAND_ ## THINGY); \
+}
+
+#define LUA_SYSFS_R(thingy, THINGY) \
+static ssize_t lua_sysfs_read_ ## thingy(struct file *fp, \
+		struct kobject *kobj, struct bin_attribute *attr, \
+		char *buf, loff_t off, size_t count) \
+{ \
+	return lua_sysfs_read(fp, kobj, buf, off, count, \
+			LUA_SIZE_ ## THINGY, LUA_COMMAND_ ## THINGY); \
+}
+
+#define LUA_BIN_ATTRIBUTE_RW(thingy, THINGY) \
+LUA_SYSFS_W(thingy, THINGY) \
+LUA_SYSFS_R(thingy, THINGY) \
+static struct bin_attribute lua_ ## thingy ## _attr = { \
+	.attr = { .name = #thingy, .mode = 0660 }, \
+	.size = LUA_SIZE_ ## THINGY, \
+	.read = lua_sysfs_read_ ## thingy, \
+	.write = lua_sysfs_write_ ## thingy \
+};
+
+LUA_BIN_ATTRIBUTE_RW(control, CONTROL)
+
+static int lua_create_sysfs_attributes(struct usb_interface *intf)
+{
+	return sysfs_create_bin_file(&intf->dev.kobj, &lua_control_attr);
+}
+
+static void lua_remove_sysfs_attributes(struct usb_interface *intf)
+{
+	sysfs_remove_bin_file(&intf->dev.kobj, &lua_control_attr);
+}
+
+static int lua_init_lua_device_struct(struct usb_device *usb_dev,
+		struct lua_device *lua)
+{
+	mutex_init(&lua->lua_lock);
+
+	return 0;
+}
+
+static int lua_init_specials(struct hid_device *hdev)
+{
+	struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
+	struct usb_device *usb_dev = interface_to_usbdev(intf);
+	struct lua_device *lua;
+	int retval;
+
+	lua = kzalloc(sizeof(*lua), GFP_KERNEL);
+	if (!lua) {
+		hid_err(hdev, "can't alloc device descriptor\n");
+		return -ENOMEM;
+	}
+	hid_set_drvdata(hdev, lua);
+
+	retval = lua_init_lua_device_struct(usb_dev, lua);
+	if (retval) {
+		hid_err(hdev, "couldn't init struct lua_device\n");
+		goto exit;
+	}
+
+	retval = lua_create_sysfs_attributes(intf);
+	if (retval) {
+		hid_err(hdev, "cannot create sysfs files\n");
+		goto exit;
+	}
+
+	return 0;
+exit:
+	kfree(lua);
+	return retval;
+}
+
+static void lua_remove_specials(struct hid_device *hdev)
+{
+	struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
+	struct lua_device *lua;
+
+	lua_remove_sysfs_attributes(intf);
+
+	lua = hid_get_drvdata(hdev);
+	kfree(lua);
+}
+
+static int lua_probe(struct hid_device *hdev,
+		const struct hid_device_id *id)
+{
+	int retval;
+
+	retval = hid_parse(hdev);
+	if (retval) {
+		hid_err(hdev, "parse failed\n");
+		goto exit;
+	}
+
+	retval = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
+	if (retval) {
+		hid_err(hdev, "hw start failed\n");
+		goto exit;
+	}
+
+	retval = lua_init_specials(hdev);
+	if (retval) {
+		hid_err(hdev, "couldn't install mouse\n");
+		goto exit_stop;
+	}
+
+	return 0;
+
+exit_stop:
+	hid_hw_stop(hdev);
+exit:
+	return retval;
+}
+
+static void lua_remove(struct hid_device *hdev)
+{
+	lua_remove_specials(hdev);
+	hid_hw_stop(hdev);
+}
+
+static const struct hid_device_id lua_devices[] = {
+	{ HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_LUA) },
+	{ }
+};
+
+MODULE_DEVICE_TABLE(hid, lua_devices);
+
+static struct hid_driver lua_driver = {
+		.name = "lua",
+		.id_table = lua_devices,
+		.probe = lua_probe,
+		.remove = lua_remove
+};
+
+static int __init lua_init(void)
+{
+	return hid_register_driver(&lua_driver);
+}
+
+static void __exit lua_exit(void)
+{
+	hid_unregister_driver(&lua_driver);
+}
+
+module_init(lua_init);
+module_exit(lua_exit);
+
+MODULE_AUTHOR("Stefan Achatz");
+MODULE_DESCRIPTION("USB Roccat Lua driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/hid/hid-roccat-lua.h b/drivers/hid/hid-roccat-lua.h
new file mode 100644
index 0000000..547d77a3
--- /dev/null
+++ b/drivers/hid/hid-roccat-lua.h
@@ -0,0 +1,29 @@
+#ifndef __HID_ROCCAT_LUA_H
+#define __HID_ROCCAT_LUA_H
+
+/*
+ * Copyright (c) 2012 Stefan Achatz <erazor_de@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.
+ */
+
+#include <linux/types.h>
+
+enum {
+	LUA_SIZE_CONTROL = 8,
+};
+
+enum lua_commands {
+	LUA_COMMAND_CONTROL = 3,
+};
+
+struct lua_device {
+	struct mutex lua_lock;
+};
+
+#endif
diff --git a/drivers/hid/hid-roccat-pyra.c b/drivers/hid/hid-roccat-pyra.c
index 1317c17..d4f1e3b 100644
--- a/drivers/hid/hid-roccat-pyra.c
+++ b/drivers/hid/hid-roccat-pyra.c
@@ -66,48 +66,14 @@
 	if (retval)
 		return retval;
 	return roccat_common2_receive(usb_dev, PYRA_COMMAND_PROFILE_SETTINGS,
-			buf, sizeof(struct pyra_profile_settings));
-}
-
-static int pyra_get_profile_buttons(struct usb_device *usb_dev,
-		struct pyra_profile_buttons *buf, int number)
-{
-	int retval;
-	retval = pyra_send_control(usb_dev, number,
-			PYRA_CONTROL_REQUEST_PROFILE_BUTTONS);
-	if (retval)
-		return retval;
-	return roccat_common2_receive(usb_dev, PYRA_COMMAND_PROFILE_BUTTONS,
-			buf, sizeof(struct pyra_profile_buttons));
+			buf, PYRA_SIZE_PROFILE_SETTINGS);
 }
 
 static int pyra_get_settings(struct usb_device *usb_dev,
 		struct pyra_settings *buf)
 {
 	return roccat_common2_receive(usb_dev, PYRA_COMMAND_SETTINGS,
-			buf, sizeof(struct pyra_settings));
-}
-
-static int pyra_get_info(struct usb_device *usb_dev, struct pyra_info *buf)
-{
-	return roccat_common2_receive(usb_dev, PYRA_COMMAND_INFO,
-			buf, sizeof(struct pyra_info));
-}
-
-static int pyra_set_profile_settings(struct usb_device *usb_dev,
-		struct pyra_profile_settings const *settings)
-{
-	return roccat_common2_send_with_status(usb_dev,
-			PYRA_COMMAND_PROFILE_SETTINGS, settings,
-			sizeof(struct pyra_profile_settings));
-}
-
-static int pyra_set_profile_buttons(struct usb_device *usb_dev,
-		struct pyra_profile_buttons const *buttons)
-{
-	return roccat_common2_send_with_status(usb_dev,
-			PYRA_COMMAND_PROFILE_BUTTONS, buttons,
-			sizeof(struct pyra_profile_buttons));
+			buf, PYRA_SIZE_SETTINGS);
 }
 
 static int pyra_set_settings(struct usb_device *usb_dev,
@@ -115,29 +81,125 @@
 {
 	return roccat_common2_send_with_status(usb_dev,
 			PYRA_COMMAND_SETTINGS, settings,
-			sizeof(struct pyra_settings));
+			PYRA_SIZE_SETTINGS);
 }
 
+static ssize_t pyra_sysfs_read(struct file *fp, struct kobject *kobj,
+		char *buf, loff_t off, size_t count,
+		size_t real_size, uint command)
+{
+	struct device *dev =
+			container_of(kobj, struct device, kobj)->parent->parent;
+	struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev));
+	struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
+	int retval;
+
+	if (off >= real_size)
+		return 0;
+
+	if (off != 0 || count != real_size)
+		return -EINVAL;
+
+	mutex_lock(&pyra->pyra_lock);
+	retval = roccat_common2_receive(usb_dev, command, buf, real_size);
+	mutex_unlock(&pyra->pyra_lock);
+
+	if (retval)
+		return retval;
+
+	return real_size;
+}
+
+static ssize_t pyra_sysfs_write(struct file *fp, struct kobject *kobj,
+		void const *buf, loff_t off, size_t count,
+		size_t real_size, uint command)
+{
+	struct device *dev =
+			container_of(kobj, struct device, kobj)->parent->parent;
+	struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev));
+	struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
+	int retval;
+
+	if (off != 0 || count != real_size)
+		return -EINVAL;
+
+	mutex_lock(&pyra->pyra_lock);
+	retval = roccat_common2_send_with_status(usb_dev, command, (void *)buf, real_size);
+	mutex_unlock(&pyra->pyra_lock);
+
+	if (retval)
+		return retval;
+
+	return real_size;
+}
+
+#define PYRA_SYSFS_W(thingy, THINGY) \
+static ssize_t pyra_sysfs_write_ ## thingy(struct file *fp, \
+		struct kobject *kobj, struct bin_attribute *attr, char *buf, \
+		loff_t off, size_t count) \
+{ \
+	return pyra_sysfs_write(fp, kobj, buf, off, count, \
+			PYRA_SIZE_ ## THINGY, PYRA_COMMAND_ ## THINGY); \
+}
+
+#define PYRA_SYSFS_R(thingy, THINGY) \
+static ssize_t pyra_sysfs_read_ ## thingy(struct file *fp, \
+		struct kobject *kobj, struct bin_attribute *attr, char *buf, \
+		loff_t off, size_t count) \
+{ \
+	return pyra_sysfs_read(fp, kobj, buf, off, count, \
+			PYRA_SIZE_ ## THINGY, PYRA_COMMAND_ ## THINGY); \
+}
+
+#define PYRA_SYSFS_RW(thingy, THINGY) \
+PYRA_SYSFS_W(thingy, THINGY) \
+PYRA_SYSFS_R(thingy, THINGY)
+
+#define PYRA_BIN_ATTRIBUTE_RW(thingy, THINGY) \
+{ \
+	.attr = { .name = #thingy, .mode = 0660 }, \
+	.size = PYRA_SIZE_ ## THINGY, \
+	.read = pyra_sysfs_read_ ## thingy, \
+	.write = pyra_sysfs_write_ ## thingy \
+}
+
+#define PYRA_BIN_ATTRIBUTE_R(thingy, THINGY) \
+{ \
+	.attr = { .name = #thingy, .mode = 0440 }, \
+	.size = PYRA_SIZE_ ## THINGY, \
+	.read = pyra_sysfs_read_ ## thingy, \
+}
+
+#define PYRA_BIN_ATTRIBUTE_W(thingy, THINGY) \
+{ \
+	.attr = { .name = #thingy, .mode = 0220 }, \
+	.size = PYRA_SIZE_ ## THINGY, \
+	.write = pyra_sysfs_write_ ## thingy \
+}
+
+PYRA_SYSFS_W(control, CONTROL)
+PYRA_SYSFS_RW(info, INFO)
+PYRA_SYSFS_RW(profile_settings, PROFILE_SETTINGS)
+PYRA_SYSFS_RW(profile_buttons, PROFILE_BUTTONS)
+PYRA_SYSFS_R(settings, SETTINGS)
+
 static ssize_t pyra_sysfs_read_profilex_settings(struct file *fp,
 		struct kobject *kobj, struct bin_attribute *attr, char *buf,
 		loff_t off, size_t count)
 {
 	struct device *dev =
 			container_of(kobj, struct device, kobj)->parent->parent;
-	struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev));
+	struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
+	ssize_t retval;
 
-	if (off >= sizeof(struct pyra_profile_settings))
-		return 0;
+	retval = pyra_send_control(usb_dev, *(uint *)(attr->private),
+			PYRA_CONTROL_REQUEST_PROFILE_SETTINGS);
+	if (retval)
+		return retval;
 
-	if (off + count > sizeof(struct pyra_profile_settings))
-		count = sizeof(struct pyra_profile_settings) - off;
-
-	mutex_lock(&pyra->pyra_lock);
-	memcpy(buf, ((char const *)&pyra->profile_settings[*(uint *)(attr->private)]) + off,
-			count);
-	mutex_unlock(&pyra->pyra_lock);
-
-	return count;
+	return pyra_sysfs_read(fp, kobj, buf, off, count,
+			PYRA_SIZE_PROFILE_SETTINGS,
+			PYRA_COMMAND_PROFILE_SETTINGS);
 }
 
 static ssize_t pyra_sysfs_read_profilex_buttons(struct file *fp,
@@ -146,115 +208,17 @@
 {
 	struct device *dev =
 			container_of(kobj, struct device, kobj)->parent->parent;
-	struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev));
-
-	if (off >= sizeof(struct pyra_profile_buttons))
-		return 0;
-
-	if (off + count > sizeof(struct pyra_profile_buttons))
-		count = sizeof(struct pyra_profile_buttons) - off;
-
-	mutex_lock(&pyra->pyra_lock);
-	memcpy(buf, ((char const *)&pyra->profile_buttons[*(uint *)(attr->private)]) + off,
-			count);
-	mutex_unlock(&pyra->pyra_lock);
-
-	return count;
-}
-
-static ssize_t pyra_sysfs_write_profile_settings(struct file *fp,
-		struct kobject *kobj, struct bin_attribute *attr, char *buf,
-		loff_t off, size_t count)
-{
-	struct device *dev =
-			container_of(kobj, struct device, kobj)->parent->parent;
-	struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev));
 	struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
-	int retval = 0;
-	int difference;
-	int profile_number;
-	struct pyra_profile_settings *profile_settings;
+	ssize_t retval;
 
-	if (off != 0 || count != sizeof(struct pyra_profile_settings))
-		return -EINVAL;
-
-	profile_number = ((struct pyra_profile_settings const *)buf)->number;
-	profile_settings = &pyra->profile_settings[profile_number];
-
-	mutex_lock(&pyra->pyra_lock);
-	difference = memcmp(buf, profile_settings,
-			sizeof(struct pyra_profile_settings));
-	if (difference) {
-		retval = pyra_set_profile_settings(usb_dev,
-				(struct pyra_profile_settings const *)buf);
-		if (!retval)
-			memcpy(profile_settings, buf,
-					sizeof(struct pyra_profile_settings));
-	}
-	mutex_unlock(&pyra->pyra_lock);
-
+	retval = pyra_send_control(usb_dev, *(uint *)(attr->private),
+			PYRA_CONTROL_REQUEST_PROFILE_BUTTONS);
 	if (retval)
 		return retval;
 
-	return sizeof(struct pyra_profile_settings);
-}
-
-static ssize_t pyra_sysfs_write_profile_buttons(struct file *fp,
-		struct kobject *kobj, struct bin_attribute *attr, char *buf,
-		loff_t off, size_t count)
-{
-	struct device *dev =
-			container_of(kobj, struct device, kobj)->parent->parent;
-	struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev));
-	struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
-	int retval = 0;
-	int difference;
-	int profile_number;
-	struct pyra_profile_buttons *profile_buttons;
-
-	if (off != 0 || count != sizeof(struct pyra_profile_buttons))
-		return -EINVAL;
-
-	profile_number = ((struct pyra_profile_buttons const *)buf)->number;
-	profile_buttons = &pyra->profile_buttons[profile_number];
-
-	mutex_lock(&pyra->pyra_lock);
-	difference = memcmp(buf, profile_buttons,
-			sizeof(struct pyra_profile_buttons));
-	if (difference) {
-		retval = pyra_set_profile_buttons(usb_dev,
-				(struct pyra_profile_buttons const *)buf);
-		if (!retval)
-			memcpy(profile_buttons, buf,
-					sizeof(struct pyra_profile_buttons));
-	}
-	mutex_unlock(&pyra->pyra_lock);
-
-	if (retval)
-		return retval;
-
-	return sizeof(struct pyra_profile_buttons);
-}
-
-static ssize_t pyra_sysfs_read_settings(struct file *fp,
-		struct kobject *kobj, struct bin_attribute *attr, char *buf,
-		loff_t off, size_t count)
-{
-	struct device *dev =
-			container_of(kobj, struct device, kobj)->parent->parent;
-	struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev));
-
-	if (off >= sizeof(struct pyra_settings))
-		return 0;
-
-	if (off + count > sizeof(struct pyra_settings))
-		count = sizeof(struct pyra_settings) - off;
-
-	mutex_lock(&pyra->pyra_lock);
-	memcpy(buf, ((char const *)&pyra->settings) + off, count);
-	mutex_unlock(&pyra->pyra_lock);
-
-	return count;
+	return pyra_sysfs_read(fp, kobj, buf, off, count,
+			PYRA_SIZE_PROFILE_BUTTONS,
+			PYRA_COMMAND_PROFILE_BUTTONS);
 }
 
 static ssize_t pyra_sysfs_write_settings(struct file *fp,
@@ -266,35 +230,32 @@
 	struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev));
 	struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
 	int retval = 0;
-	int difference;
 	struct pyra_roccat_report roccat_report;
+	struct pyra_settings const *settings;
 
-	if (off != 0 || count != sizeof(struct pyra_settings))
+	if (off != 0 || count != PYRA_SIZE_SETTINGS)
 		return -EINVAL;
 
 	mutex_lock(&pyra->pyra_lock);
-	difference = memcmp(buf, &pyra->settings, sizeof(struct pyra_settings));
-	if (difference) {
-		retval = pyra_set_settings(usb_dev,
-				(struct pyra_settings const *)buf);
-		if (retval) {
-			mutex_unlock(&pyra->pyra_lock);
-			return retval;
-		}
 
-		memcpy(&pyra->settings, buf,
-				sizeof(struct pyra_settings));
+	settings = (struct pyra_settings const *)buf;
 
-		profile_activated(pyra, pyra->settings.startup_profile);
-
-		roccat_report.type = PYRA_MOUSE_EVENT_BUTTON_TYPE_PROFILE_2;
-		roccat_report.value = pyra->settings.startup_profile + 1;
-		roccat_report.key = 0;
-		roccat_report_event(pyra->chrdev_minor,
-				(uint8_t const *)&roccat_report);
+	retval = pyra_set_settings(usb_dev, settings);
+	if (retval) {
+		mutex_unlock(&pyra->pyra_lock);
+		return retval;
 	}
+
+	profile_activated(pyra, settings->startup_profile);
+
+	roccat_report.type = PYRA_MOUSE_EVENT_BUTTON_TYPE_PROFILE_2;
+	roccat_report.value = settings->startup_profile + 1;
+	roccat_report.key = 0;
+	roccat_report_event(pyra->chrdev_minor,
+			(uint8_t const *)&roccat_report);
+
 	mutex_unlock(&pyra->pyra_lock);
-	return sizeof(struct pyra_settings);
+	return PYRA_SIZE_SETTINGS;
 }
 
 
@@ -311,23 +272,34 @@
 {
 	struct pyra_device *pyra =
 			hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
-	return snprintf(buf, PAGE_SIZE, "%d\n", pyra->actual_profile);
+	struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
+	struct pyra_settings settings;
+
+	mutex_lock(&pyra->pyra_lock);
+	roccat_common2_receive(usb_dev, PYRA_COMMAND_SETTINGS,
+			&settings, PYRA_SIZE_SETTINGS);
+	mutex_unlock(&pyra->pyra_lock);
+
+	return snprintf(buf, PAGE_SIZE, "%d\n", settings.startup_profile);
 }
 
 static ssize_t pyra_sysfs_show_firmware_version(struct device *dev,
 		struct device_attribute *attr, char *buf)
 {
-	struct pyra_device *pyra =
-			hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
-	return snprintf(buf, PAGE_SIZE, "%d\n", pyra->firmware_version);
-}
+	struct pyra_device *pyra;
+	struct usb_device *usb_dev;
+	struct pyra_info info;
 
-static ssize_t pyra_sysfs_show_startup_profile(struct device *dev,
-		struct device_attribute *attr, char *buf)
-{
-	struct pyra_device *pyra =
-			hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
-	return snprintf(buf, PAGE_SIZE, "%d\n", pyra->settings.startup_profile);
+	dev = dev->parent->parent;
+	pyra = hid_get_drvdata(dev_get_drvdata(dev));
+	usb_dev = interface_to_usbdev(to_usb_interface(dev));
+
+	mutex_lock(&pyra->pyra_lock);
+	roccat_common2_receive(usb_dev, PYRA_COMMAND_INFO,
+			&info, PYRA_SIZE_INFO);
+	mutex_unlock(&pyra->pyra_lock);
+
+	return snprintf(buf, PAGE_SIZE, "%d\n", info.firmware_version);
 }
 
 static struct device_attribute pyra_attributes[] = {
@@ -336,105 +308,88 @@
 	__ATTR(firmware_version, 0440,
 			pyra_sysfs_show_firmware_version, NULL),
 	__ATTR(startup_profile, 0440,
-			pyra_sysfs_show_startup_profile, NULL),
+			pyra_sysfs_show_actual_profile, NULL),
 	__ATTR_NULL
 };
 
 static struct bin_attribute pyra_bin_attributes[] = {
-	{
-		.attr = { .name = "profile_settings", .mode = 0220 },
-		.size = sizeof(struct pyra_profile_settings),
-		.write = pyra_sysfs_write_profile_settings
-	},
+	PYRA_BIN_ATTRIBUTE_W(control, CONTROL),
+	PYRA_BIN_ATTRIBUTE_RW(info, INFO),
+	PYRA_BIN_ATTRIBUTE_RW(profile_settings, PROFILE_SETTINGS),
+	PYRA_BIN_ATTRIBUTE_RW(profile_buttons, PROFILE_BUTTONS),
+	PYRA_BIN_ATTRIBUTE_RW(settings, SETTINGS),
 	{
 		.attr = { .name = "profile1_settings", .mode = 0440 },
-		.size = sizeof(struct pyra_profile_settings),
+		.size = PYRA_SIZE_PROFILE_SETTINGS,
 		.read = pyra_sysfs_read_profilex_settings,
 		.private = &profile_numbers[0]
 	},
 	{
 		.attr = { .name = "profile2_settings", .mode = 0440 },
-		.size = sizeof(struct pyra_profile_settings),
+		.size = PYRA_SIZE_PROFILE_SETTINGS,
 		.read = pyra_sysfs_read_profilex_settings,
 		.private = &profile_numbers[1]
 	},
 	{
 		.attr = { .name = "profile3_settings", .mode = 0440 },
-		.size = sizeof(struct pyra_profile_settings),
+		.size = PYRA_SIZE_PROFILE_SETTINGS,
 		.read = pyra_sysfs_read_profilex_settings,
 		.private = &profile_numbers[2]
 	},
 	{
 		.attr = { .name = "profile4_settings", .mode = 0440 },
-		.size = sizeof(struct pyra_profile_settings),
+		.size = PYRA_SIZE_PROFILE_SETTINGS,
 		.read = pyra_sysfs_read_profilex_settings,
 		.private = &profile_numbers[3]
 	},
 	{
 		.attr = { .name = "profile5_settings", .mode = 0440 },
-		.size = sizeof(struct pyra_profile_settings),
+		.size = PYRA_SIZE_PROFILE_SETTINGS,
 		.read = pyra_sysfs_read_profilex_settings,
 		.private = &profile_numbers[4]
 	},
 	{
-		.attr = { .name = "profile_buttons", .mode = 0220 },
-		.size = sizeof(struct pyra_profile_buttons),
-		.write = pyra_sysfs_write_profile_buttons
-	},
-	{
 		.attr = { .name = "profile1_buttons", .mode = 0440 },
-		.size = sizeof(struct pyra_profile_buttons),
+		.size = PYRA_SIZE_PROFILE_BUTTONS,
 		.read = pyra_sysfs_read_profilex_buttons,
 		.private = &profile_numbers[0]
 	},
 	{
 		.attr = { .name = "profile2_buttons", .mode = 0440 },
-		.size = sizeof(struct pyra_profile_buttons),
+		.size = PYRA_SIZE_PROFILE_BUTTONS,
 		.read = pyra_sysfs_read_profilex_buttons,
 		.private = &profile_numbers[1]
 	},
 	{
 		.attr = { .name = "profile3_buttons", .mode = 0440 },
-		.size = sizeof(struct pyra_profile_buttons),
+		.size = PYRA_SIZE_PROFILE_BUTTONS,
 		.read = pyra_sysfs_read_profilex_buttons,
 		.private = &profile_numbers[2]
 	},
 	{
 		.attr = { .name = "profile4_buttons", .mode = 0440 },
-		.size = sizeof(struct pyra_profile_buttons),
+		.size = PYRA_SIZE_PROFILE_BUTTONS,
 		.read = pyra_sysfs_read_profilex_buttons,
 		.private = &profile_numbers[3]
 	},
 	{
 		.attr = { .name = "profile5_buttons", .mode = 0440 },
-		.size = sizeof(struct pyra_profile_buttons),
+		.size = PYRA_SIZE_PROFILE_BUTTONS,
 		.read = pyra_sysfs_read_profilex_buttons,
 		.private = &profile_numbers[4]
 	},
-	{
-		.attr = { .name = "settings", .mode = 0660 },
-		.size = sizeof(struct pyra_settings),
-		.read = pyra_sysfs_read_settings,
-		.write = pyra_sysfs_write_settings
-	},
 	__ATTR_NULL
 };
 
 static int pyra_init_pyra_device_struct(struct usb_device *usb_dev,
 		struct pyra_device *pyra)
 {
-	struct pyra_info info;
+	struct pyra_settings settings;
 	int retval, i;
 
 	mutex_init(&pyra->pyra_lock);
 
-	retval = pyra_get_info(usb_dev, &info);
-	if (retval)
-		return retval;
-
-	pyra->firmware_version = info.firmware_version;
-
-	retval = pyra_get_settings(usb_dev, &pyra->settings);
+	retval = pyra_get_settings(usb_dev, &settings);
 	if (retval)
 		return retval;
 
@@ -443,14 +398,9 @@
 				&pyra->profile_settings[i], i);
 		if (retval)
 			return retval;
-
-		retval = pyra_get_profile_buttons(usb_dev,
-				&pyra->profile_buttons[i], i);
-		if (retval)
-			return retval;
 	}
 
-	profile_activated(pyra, pyra->settings.startup_profile);
+	profile_activated(pyra, settings.startup_profile);
 
 	return 0;
 }
diff --git a/drivers/hid/hid-roccat-pyra.h b/drivers/hid/hid-roccat-pyra.h
index eada783..beedcf0 100644
--- a/drivers/hid/hid-roccat-pyra.h
+++ b/drivers/hid/hid-roccat-pyra.h
@@ -14,11 +14,13 @@
 
 #include <linux/types.h>
 
-struct pyra_b {
-	uint8_t command; /* PYRA_COMMAND_B */
-	uint8_t size; /* always 3 */
-	uint8_t unknown; /* 1 */
-} __attribute__ ((__packed__));
+enum {
+	PYRA_SIZE_CONTROL = 0x03,
+	PYRA_SIZE_INFO = 0x06,
+	PYRA_SIZE_PROFILE_SETTINGS = 0x0d,
+	PYRA_SIZE_PROFILE_BUTTONS = 0x13,
+	PYRA_SIZE_SETTINGS = 0x03,
+};
 
 enum pyra_control_requests {
 	PYRA_CONTROL_REQUEST_PROFILE_SETTINGS = 0x10,
@@ -46,14 +48,6 @@
 	uint16_t checksum; /* byte sum */
 } __attribute__ ((__packed__));
 
-struct pyra_profile_buttons {
-	uint8_t command; /* PYRA_COMMAND_PROFILE_BUTTONS */
-	uint8_t size; /* always 0x13 */
-	uint8_t number; /* Range 0-4 */
-	uint8_t buttons[14];
-	uint16_t checksum; /* byte sum */
-} __attribute__ ((__packed__));
-
 struct pyra_info {
 	uint8_t command; /* PYRA_COMMAND_INFO */
 	uint8_t size; /* always 6 */
@@ -64,6 +58,7 @@
 } __attribute__ ((__packed__));
 
 enum pyra_commands {
+	PYRA_COMMAND_CONTROL = 0x4,
 	PYRA_COMMAND_SETTINGS = 0x5,
 	PYRA_COMMAND_PROFILE_SETTINGS = 0x6,
 	PYRA_COMMAND_PROFILE_BUTTONS = 0x7,
@@ -148,13 +143,10 @@
 struct pyra_device {
 	int actual_profile;
 	int actual_cpi;
-	int firmware_version;
 	int roccat_claimed;
 	int chrdev_minor;
 	struct mutex pyra_lock;
-	struct pyra_settings settings;
 	struct pyra_profile_settings profile_settings[5];
-	struct pyra_profile_buttons profile_buttons[5];
 };
 
 #endif
diff --git a/drivers/hid/hid-roccat-savu.c b/drivers/hid/hid-roccat-savu.c
index 014afba..31747a2 100644
--- a/drivers/hid/hid-roccat-savu.c
+++ b/drivers/hid/hid-roccat-savu.c
@@ -120,7 +120,7 @@
 SAVU_SYSFS_RW(general, GENERAL)
 SAVU_SYSFS_RW(buttons, BUTTONS)
 SAVU_SYSFS_RW(macro, MACRO)
-SAVU_SYSFS_R(info, INFO)
+SAVU_SYSFS_RW(info, INFO)
 SAVU_SYSFS_RW(sensor, SENSOR)
 
 static struct bin_attribute savu_bin_attributes[] = {
@@ -129,7 +129,7 @@
 	SAVU_BIN_ATTRIBUTE_RW(general, GENERAL),
 	SAVU_BIN_ATTRIBUTE_RW(buttons, BUTTONS),
 	SAVU_BIN_ATTRIBUTE_RW(macro, MACRO),
-	SAVU_BIN_ATTRIBUTE_R(info, INFO),
+	SAVU_BIN_ATTRIBUTE_RW(info, INFO),
 	SAVU_BIN_ATTRIBUTE_RW(sensor, SENSOR),
 	__ATTR_NULL
 };
diff --git a/drivers/hid/hid-sensor-hub.c b/drivers/hid/hid-sensor-hub.c
index d9d73e9..0bc58bd 100644
--- a/drivers/hid/hid-sensor-hub.c
+++ b/drivers/hid/hid-sensor-hub.c
@@ -82,23 +82,6 @@
 	void *priv;
 };
 
-static int sensor_hub_check_for_sensor_page(struct hid_device *hdev)
-{
-	int i;
-	int ret = -EINVAL;
-
-	for (i = 0; i < hdev->maxcollection; i++) {
-		struct hid_collection *col = &hdev->collection[i];
-		if (col->type == HID_COLLECTION_PHYSICAL &&
-		   (col->usage & HID_USAGE_PAGE) == HID_UP_SENSOR) {
-			ret = 0;
-			break;
-		}
-	}
-
-	return ret;
-}
-
 static struct hid_report *sensor_hub_report(int id, struct hid_device *hdev,
 						int dir)
 {
@@ -437,9 +420,6 @@
 	ptr = raw_data;
 	ptr++; /*Skip report id*/
 
-	if (!report)
-		goto err_report;
-
 	spin_lock_irqsave(&pdata->lock, flags);
 
 	for (i = 0; i < report->maxfield; ++i) {
@@ -485,7 +465,6 @@
 				callback->pdev);
 	spin_unlock_irqrestore(&pdata->lock, flags);
 
-err_report:
 	return 1;
 }
 
@@ -524,10 +503,6 @@
 		hid_err(hdev, "parse failed\n");
 		goto err_free;
 	}
-	if (sensor_hub_check_for_sensor_page(hdev) < 0) {
-		hid_err(hdev, "sensor page not found\n");
-		goto err_free;
-	}
 	INIT_LIST_HEAD(&hdev->inputs);
 
 	ret = hid_hw_start(hdev, 0);
@@ -630,16 +605,7 @@
 }
 
 static const struct hid_device_id sensor_hub_devices[] = {
-	{ HID_USB_DEVICE(USB_VENDOR_ID_INTEL_8086,
-			USB_DEVICE_ID_SENSOR_HUB_1020) },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_INTEL_8087,
-			USB_DEVICE_ID_SENSOR_HUB_1020) },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_INTEL_8086,
-			USB_DEVICE_ID_SENSOR_HUB_09FA) },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_INTEL_8087,
-			USB_DEVICE_ID_SENSOR_HUB_09FA) },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_STANTUM_STM,
-			USB_DEVICE_ID_SENSOR_HUB_7014) },
+	{ HID_DEVICE(BUS_USB, HID_GROUP_SENSOR_HUB, HID_ANY_ID, HID_ANY_ID) },
 	{ }
 };
 MODULE_DEVICE_TABLE(hid, sensor_hub_devices);
diff --git a/drivers/hid/hidraw.c b/drivers/hid/hidraw.c
index 7c47fc3..413a731 100644
--- a/drivers/hid/hidraw.c
+++ b/drivers/hid/hidraw.c
@@ -57,10 +57,6 @@
 			set_current_state(TASK_INTERRUPTIBLE);
 
 			while (list->head == list->tail) {
-				if (file->f_flags & O_NONBLOCK) {
-					ret = -EAGAIN;
-					break;
-				}
 				if (signal_pending(current)) {
 					ret = -ERESTARTSYS;
 					break;
@@ -69,6 +65,10 @@
 					ret = -EIO;
 					break;
 				}
+				if (file->f_flags & O_NONBLOCK) {
+					ret = -EAGAIN;
+					break;
+				}
 
 				/* allow O_NONBLOCK to work well from other threads */
 				mutex_unlock(&list->read_mutex);
@@ -295,6 +295,13 @@
 
 }
 
+static int hidraw_fasync(int fd, struct file *file, int on)
+{
+	struct hidraw_list *list = file->private_data;
+
+	return fasync_helper(fd, file, on, &list->fasync);
+}
+
 static int hidraw_release(struct inode * inode, struct file * file)
 {
 	unsigned int minor = iminor(inode);
@@ -438,6 +445,7 @@
 	.open =         hidraw_open,
 	.release =      hidraw_release,
 	.unlocked_ioctl = hidraw_ioctl,
+	.fasync =	hidraw_fasync,
 #ifdef CONFIG_COMPAT
 	.compat_ioctl   = hidraw_ioctl,
 #endif
diff --git a/drivers/hid/i2c-hid/Kconfig b/drivers/hid/i2c-hid/Kconfig
new file mode 100644
index 0000000..b66617a
--- /dev/null
+++ b/drivers/hid/i2c-hid/Kconfig
@@ -0,0 +1,18 @@
+menu "I2C HID support"
+	depends on I2C
+
+config I2C_HID
+	tristate "HID over I2C transport layer"
+	default n
+	depends on I2C && INPUT
+	select HID
+	---help---
+	  Say Y here if you use a keyboard, a touchpad, a touchscreen, or any
+	  other HID based devices which is connected to your computer via I2C.
+
+	  If unsure, say N.
+
+	  This support is also available as a module.  If so, the module
+	  will be called i2c-hid.
+
+endmenu
diff --git a/drivers/hid/i2c-hid/Makefile b/drivers/hid/i2c-hid/Makefile
new file mode 100644
index 0000000..832d8f9
--- /dev/null
+++ b/drivers/hid/i2c-hid/Makefile
@@ -0,0 +1,5 @@
+#
+# Makefile for the I2C input drivers
+#
+
+obj-$(CONFIG_I2C_HID)				+= i2c-hid.o
diff --git a/drivers/hid/i2c-hid/i2c-hid.c b/drivers/hid/i2c-hid/i2c-hid.c
new file mode 100644
index 0000000..9ef22244
--- /dev/null
+++ b/drivers/hid/i2c-hid/i2c-hid.c
@@ -0,0 +1,979 @@
+/*
+ * HID over I2C protocol implementation
+ *
+ * Copyright (c) 2012 Benjamin Tissoires <benjamin.tissoires@gmail.com>
+ * Copyright (c) 2012 Ecole Nationale de l'Aviation Civile, France
+ * Copyright (c) 2012 Red Hat, Inc
+ *
+ * This code is partly based on "USB HID support for Linux":
+ *
+ *  Copyright (c) 1999 Andreas Gal
+ *  Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz>
+ *  Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc
+ *  Copyright (c) 2007-2008 Oliver Neukum
+ *  Copyright (c) 2006-2010 Jiri Kosina
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive for
+ * more details.
+ */
+
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/input.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/pm.h>
+#include <linux/device.h>
+#include <linux/wait.h>
+#include <linux/err.h>
+#include <linux/string.h>
+#include <linux/list.h>
+#include <linux/jiffies.h>
+#include <linux/kernel.h>
+#include <linux/hid.h>
+#include <linux/mutex.h>
+
+#include <linux/i2c/i2c-hid.h>
+
+/* flags */
+#define I2C_HID_STARTED		(1 << 0)
+#define I2C_HID_RESET_PENDING	(1 << 1)
+#define I2C_HID_READ_PENDING	(1 << 2)
+
+#define I2C_HID_PWR_ON		0x00
+#define I2C_HID_PWR_SLEEP	0x01
+
+/* debug option */
+static bool debug;
+module_param(debug, bool, 0444);
+MODULE_PARM_DESC(debug, "print a lot of debug information");
+
+#define i2c_hid_dbg(ihid, fmt, arg...)					  \
+do {									  \
+	if (debug)							  \
+		dev_printk(KERN_DEBUG, &(ihid)->client->dev, fmt, ##arg); \
+} while (0)
+
+struct i2c_hid_desc {
+	__le16 wHIDDescLength;
+	__le16 bcdVersion;
+	__le16 wReportDescLength;
+	__le16 wReportDescRegister;
+	__le16 wInputRegister;
+	__le16 wMaxInputLength;
+	__le16 wOutputRegister;
+	__le16 wMaxOutputLength;
+	__le16 wCommandRegister;
+	__le16 wDataRegister;
+	__le16 wVendorID;
+	__le16 wProductID;
+	__le16 wVersionID;
+	__le32 reserved;
+} __packed;
+
+struct i2c_hid_cmd {
+	unsigned int registerIndex;
+	__u8 opcode;
+	unsigned int length;
+	bool wait;
+};
+
+union command {
+	u8 data[0];
+	struct cmd {
+		__le16 reg;
+		__u8 reportTypeID;
+		__u8 opcode;
+	} __packed c;
+};
+
+#define I2C_HID_CMD(opcode_) \
+	.opcode = opcode_, .length = 4, \
+	.registerIndex = offsetof(struct i2c_hid_desc, wCommandRegister)
+
+/* fetch HID descriptor */
+static const struct i2c_hid_cmd hid_descr_cmd = { .length = 2 };
+/* fetch report descriptors */
+static const struct i2c_hid_cmd hid_report_descr_cmd = {
+		.registerIndex = offsetof(struct i2c_hid_desc,
+			wReportDescRegister),
+		.opcode = 0x00,
+		.length = 2 };
+/* commands */
+static const struct i2c_hid_cmd hid_reset_cmd =		{ I2C_HID_CMD(0x01),
+							  .wait = true };
+static const struct i2c_hid_cmd hid_get_report_cmd =	{ I2C_HID_CMD(0x02) };
+static const struct i2c_hid_cmd hid_set_report_cmd =	{ I2C_HID_CMD(0x03) };
+static const struct i2c_hid_cmd hid_set_power_cmd =	{ I2C_HID_CMD(0x08) };
+
+/*
+ * These definitions are not used here, but are defined by the spec.
+ * Keeping them here for documentation purposes.
+ *
+ * static const struct i2c_hid_cmd hid_get_idle_cmd = { I2C_HID_CMD(0x04) };
+ * static const struct i2c_hid_cmd hid_set_idle_cmd = { I2C_HID_CMD(0x05) };
+ * static const struct i2c_hid_cmd hid_get_protocol_cmd = { I2C_HID_CMD(0x06) };
+ * static const struct i2c_hid_cmd hid_set_protocol_cmd = { I2C_HID_CMD(0x07) };
+ */
+
+static DEFINE_MUTEX(i2c_hid_open_mut);
+
+/* The main device structure */
+struct i2c_hid {
+	struct i2c_client	*client;	/* i2c client */
+	struct hid_device	*hid;	/* pointer to corresponding HID dev */
+	union {
+		__u8 hdesc_buffer[sizeof(struct i2c_hid_desc)];
+		struct i2c_hid_desc hdesc;	/* the HID Descriptor */
+	};
+	__le16			wHIDDescRegister; /* location of the i2c
+						   * register of the HID
+						   * descriptor. */
+	unsigned int		bufsize;	/* i2c buffer size */
+	char			*inbuf;		/* Input buffer */
+	char			*cmdbuf;	/* Command buffer */
+	char			*argsbuf;	/* Command arguments buffer */
+
+	unsigned long		flags;		/* device flags */
+
+	wait_queue_head_t	wait;		/* For waiting the interrupt */
+};
+
+static int __i2c_hid_command(struct i2c_client *client,
+		const struct i2c_hid_cmd *command, u8 reportID,
+		u8 reportType, u8 *args, int args_len,
+		unsigned char *buf_recv, int data_len)
+{
+	struct i2c_hid *ihid = i2c_get_clientdata(client);
+	union command *cmd = (union command *)ihid->cmdbuf;
+	int ret;
+	struct i2c_msg msg[2];
+	int msg_num = 1;
+
+	int length = command->length;
+	bool wait = command->wait;
+	unsigned int registerIndex = command->registerIndex;
+
+	/* special case for hid_descr_cmd */
+	if (command == &hid_descr_cmd) {
+		cmd->c.reg = ihid->wHIDDescRegister;
+	} else {
+		cmd->data[0] = ihid->hdesc_buffer[registerIndex];
+		cmd->data[1] = ihid->hdesc_buffer[registerIndex + 1];
+	}
+
+	if (length > 2) {
+		cmd->c.opcode = command->opcode;
+		cmd->c.reportTypeID = reportID | reportType << 4;
+	}
+
+	memcpy(cmd->data + length, args, args_len);
+	length += args_len;
+
+	i2c_hid_dbg(ihid, "%s: cmd=%*ph\n", __func__, length, cmd->data);
+
+	msg[0].addr = client->addr;
+	msg[0].flags = client->flags & I2C_M_TEN;
+	msg[0].len = length;
+	msg[0].buf = cmd->data;
+	if (data_len > 0) {
+		msg[1].addr = client->addr;
+		msg[1].flags = client->flags & I2C_M_TEN;
+		msg[1].flags |= I2C_M_RD;
+		msg[1].len = data_len;
+		msg[1].buf = buf_recv;
+		msg_num = 2;
+		set_bit(I2C_HID_READ_PENDING, &ihid->flags);
+	}
+
+	if (wait)
+		set_bit(I2C_HID_RESET_PENDING, &ihid->flags);
+
+	ret = i2c_transfer(client->adapter, msg, msg_num);
+
+	if (data_len > 0)
+		clear_bit(I2C_HID_READ_PENDING, &ihid->flags);
+
+	if (ret != msg_num)
+		return ret < 0 ? ret : -EIO;
+
+	ret = 0;
+
+	if (wait) {
+		i2c_hid_dbg(ihid, "%s: waiting...\n", __func__);
+		if (!wait_event_timeout(ihid->wait,
+				!test_bit(I2C_HID_RESET_PENDING, &ihid->flags),
+				msecs_to_jiffies(5000)))
+			ret = -ENODATA;
+		i2c_hid_dbg(ihid, "%s: finished.\n", __func__);
+	}
+
+	return ret;
+}
+
+static int i2c_hid_command(struct i2c_client *client,
+		const struct i2c_hid_cmd *command,
+		unsigned char *buf_recv, int data_len)
+{
+	return __i2c_hid_command(client, command, 0, 0, NULL, 0,
+				buf_recv, data_len);
+}
+
+static int i2c_hid_get_report(struct i2c_client *client, u8 reportType,
+		u8 reportID, unsigned char *buf_recv, int data_len)
+{
+	struct i2c_hid *ihid = i2c_get_clientdata(client);
+	u8 args[3];
+	int ret;
+	int args_len = 0;
+	u16 readRegister = le16_to_cpu(ihid->hdesc.wDataRegister);
+
+	i2c_hid_dbg(ihid, "%s\n", __func__);
+
+	if (reportID >= 0x0F) {
+		args[args_len++] = reportID;
+		reportID = 0x0F;
+	}
+
+	args[args_len++] = readRegister & 0xFF;
+	args[args_len++] = readRegister >> 8;
+
+	ret = __i2c_hid_command(client, &hid_get_report_cmd, reportID,
+		reportType, args, args_len, buf_recv, data_len);
+	if (ret) {
+		dev_err(&client->dev,
+			"failed to retrieve report from device.\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static int i2c_hid_set_report(struct i2c_client *client, u8 reportType,
+		u8 reportID, unsigned char *buf, size_t data_len)
+{
+	struct i2c_hid *ihid = i2c_get_clientdata(client);
+	u8 *args = ihid->argsbuf;
+	int ret;
+	u16 dataRegister = le16_to_cpu(ihid->hdesc.wDataRegister);
+
+	/* hidraw already checked that data_len < HID_MAX_BUFFER_SIZE */
+	u16 size =	2			/* size */ +
+			(reportID ? 1 : 0)	/* reportID */ +
+			data_len		/* buf */;
+	int args_len =	(reportID >= 0x0F ? 1 : 0) /* optional third byte */ +
+			2			/* dataRegister */ +
+			size			/* args */;
+	int index = 0;
+
+	i2c_hid_dbg(ihid, "%s\n", __func__);
+
+	if (reportID >= 0x0F) {
+		args[index++] = reportID;
+		reportID = 0x0F;
+	}
+
+	args[index++] = dataRegister & 0xFF;
+	args[index++] = dataRegister >> 8;
+
+	args[index++] = size & 0xFF;
+	args[index++] = size >> 8;
+
+	if (reportID)
+		args[index++] = reportID;
+
+	memcpy(&args[index], buf, data_len);
+
+	ret = __i2c_hid_command(client, &hid_set_report_cmd, reportID,
+		reportType, args, args_len, NULL, 0);
+	if (ret) {
+		dev_err(&client->dev, "failed to set a report to device.\n");
+		return ret;
+	}
+
+	return data_len;
+}
+
+static int i2c_hid_set_power(struct i2c_client *client, int power_state)
+{
+	struct i2c_hid *ihid = i2c_get_clientdata(client);
+	int ret;
+
+	i2c_hid_dbg(ihid, "%s\n", __func__);
+
+	ret = __i2c_hid_command(client, &hid_set_power_cmd, power_state,
+		0, NULL, 0, NULL, 0);
+	if (ret)
+		dev_err(&client->dev, "failed to change power setting.\n");
+
+	return ret;
+}
+
+static int i2c_hid_hwreset(struct i2c_client *client)
+{
+	struct i2c_hid *ihid = i2c_get_clientdata(client);
+	int ret;
+
+	i2c_hid_dbg(ihid, "%s\n", __func__);
+
+	ret = i2c_hid_set_power(client, I2C_HID_PWR_ON);
+	if (ret)
+		return ret;
+
+	i2c_hid_dbg(ihid, "resetting...\n");
+
+	ret = i2c_hid_command(client, &hid_reset_cmd, NULL, 0);
+	if (ret) {
+		dev_err(&client->dev, "failed to reset device.\n");
+		i2c_hid_set_power(client, I2C_HID_PWR_SLEEP);
+		return ret;
+	}
+
+	return 0;
+}
+
+static void i2c_hid_get_input(struct i2c_hid *ihid)
+{
+	int ret, ret_size;
+	int size = le16_to_cpu(ihid->hdesc.wMaxInputLength);
+
+	ret = i2c_master_recv(ihid->client, ihid->inbuf, size);
+	if (ret != size) {
+		if (ret < 0)
+			return;
+
+		dev_err(&ihid->client->dev, "%s: got %d data instead of %d\n",
+			__func__, ret, size);
+		return;
+	}
+
+	ret_size = ihid->inbuf[0] | ihid->inbuf[1] << 8;
+
+	if (!ret_size) {
+		/* host or device initiated RESET completed */
+		if (test_and_clear_bit(I2C_HID_RESET_PENDING, &ihid->flags))
+			wake_up(&ihid->wait);
+		return;
+	}
+
+	if (ret_size > size) {
+		dev_err(&ihid->client->dev, "%s: incomplete report (%d/%d)\n",
+			__func__, size, ret_size);
+		return;
+	}
+
+	i2c_hid_dbg(ihid, "input: %*ph\n", ret_size, ihid->inbuf);
+
+	if (test_bit(I2C_HID_STARTED, &ihid->flags))
+		hid_input_report(ihid->hid, HID_INPUT_REPORT, ihid->inbuf + 2,
+				ret_size - 2, 1);
+
+	return;
+}
+
+static irqreturn_t i2c_hid_irq(int irq, void *dev_id)
+{
+	struct i2c_hid *ihid = dev_id;
+
+	if (test_bit(I2C_HID_READ_PENDING, &ihid->flags))
+		return IRQ_HANDLED;
+
+	i2c_hid_get_input(ihid);
+
+	return IRQ_HANDLED;
+}
+
+static int i2c_hid_get_report_length(struct hid_report *report)
+{
+	return ((report->size - 1) >> 3) + 1 +
+		report->device->report_enum[report->type].numbered + 2;
+}
+
+static void i2c_hid_init_report(struct hid_report *report, u8 *buffer,
+	size_t bufsize)
+{
+	struct hid_device *hid = report->device;
+	struct i2c_client *client = hid->driver_data;
+	struct i2c_hid *ihid = i2c_get_clientdata(client);
+	unsigned int size, ret_size;
+
+	size = i2c_hid_get_report_length(report);
+	if (i2c_hid_get_report(client,
+			report->type == HID_FEATURE_REPORT ? 0x03 : 0x01,
+			report->id, buffer, size))
+		return;
+
+	i2c_hid_dbg(ihid, "report (len=%d): %*ph\n", size, size, ihid->inbuf);
+
+	ret_size = buffer[0] | (buffer[1] << 8);
+
+	if (ret_size != size) {
+		dev_err(&client->dev, "error in %s size:%d / ret_size:%d\n",
+			__func__, size, ret_size);
+		return;
+	}
+
+	/* hid->driver_lock is held as we are in probe function,
+	 * we just need to setup the input fields, so using
+	 * hid_report_raw_event is safe. */
+	hid_report_raw_event(hid, report->type, buffer + 2, size - 2, 1);
+}
+
+/*
+ * Initialize all reports
+ */
+static void i2c_hid_init_reports(struct hid_device *hid)
+{
+	struct hid_report *report;
+	struct i2c_client *client = hid->driver_data;
+	struct i2c_hid *ihid = i2c_get_clientdata(client);
+	u8 *inbuf = kzalloc(ihid->bufsize, GFP_KERNEL);
+
+	if (!inbuf) {
+		dev_err(&client->dev, "can not retrieve initial reports\n");
+		return;
+	}
+
+	list_for_each_entry(report,
+		&hid->report_enum[HID_INPUT_REPORT].report_list, list)
+		i2c_hid_init_report(report, inbuf, ihid->bufsize);
+
+	list_for_each_entry(report,
+		&hid->report_enum[HID_FEATURE_REPORT].report_list, list)
+		i2c_hid_init_report(report, inbuf, ihid->bufsize);
+
+	kfree(inbuf);
+}
+
+/*
+ * Traverse the supplied list of reports and find the longest
+ */
+static void i2c_hid_find_max_report(struct hid_device *hid, unsigned int type,
+		unsigned int *max)
+{
+	struct hid_report *report;
+	unsigned int size;
+
+	/* We should not rely on wMaxInputLength, as some devices may set it to
+	 * a wrong length. */
+	list_for_each_entry(report, &hid->report_enum[type].report_list, list) {
+		size = i2c_hid_get_report_length(report);
+		if (*max < size)
+			*max = size;
+	}
+}
+
+static void i2c_hid_free_buffers(struct i2c_hid *ihid)
+{
+	kfree(ihid->inbuf);
+	kfree(ihid->argsbuf);
+	kfree(ihid->cmdbuf);
+	ihid->inbuf = NULL;
+	ihid->cmdbuf = NULL;
+	ihid->argsbuf = NULL;
+	ihid->bufsize = 0;
+}
+
+static int i2c_hid_alloc_buffers(struct i2c_hid *ihid, size_t report_size)
+{
+	/* the worst case is computed from the set_report command with a
+	 * reportID > 15 and the maximum report length */
+	int args_len = sizeof(__u8) + /* optional ReportID byte */
+		       sizeof(__u16) + /* data register */
+		       sizeof(__u16) + /* size of the report */
+		       report_size; /* report */
+
+	ihid->inbuf = kzalloc(report_size, GFP_KERNEL);
+	ihid->argsbuf = kzalloc(args_len, GFP_KERNEL);
+	ihid->cmdbuf = kzalloc(sizeof(union command) + args_len, GFP_KERNEL);
+
+	if (!ihid->inbuf || !ihid->argsbuf || !ihid->cmdbuf) {
+		i2c_hid_free_buffers(ihid);
+		return -ENOMEM;
+	}
+
+	ihid->bufsize = report_size;
+
+	return 0;
+}
+
+static int i2c_hid_get_raw_report(struct hid_device *hid,
+		unsigned char report_number, __u8 *buf, size_t count,
+		unsigned char report_type)
+{
+	struct i2c_client *client = hid->driver_data;
+	struct i2c_hid *ihid = i2c_get_clientdata(client);
+	size_t ret_count, ask_count;
+	int ret;
+
+	if (report_type == HID_OUTPUT_REPORT)
+		return -EINVAL;
+
+	/* +2 bytes to include the size of the reply in the query buffer */
+	ask_count = min(count + 2, (size_t)ihid->bufsize);
+
+	ret = i2c_hid_get_report(client,
+			report_type == HID_FEATURE_REPORT ? 0x03 : 0x01,
+			report_number, ihid->inbuf, ask_count);
+
+	if (ret < 0)
+		return ret;
+
+	ret_count = ihid->inbuf[0] | (ihid->inbuf[1] << 8);
+
+	if (ret_count <= 2)
+		return 0;
+
+	ret_count = min(ret_count, ask_count);
+
+	/* The query buffer contains the size, dropping it in the reply */
+	count = min(count, ret_count - 2);
+	memcpy(buf, ihid->inbuf + 2, count);
+
+	return count;
+}
+
+static int i2c_hid_output_raw_report(struct hid_device *hid, __u8 *buf,
+		size_t count, unsigned char report_type)
+{
+	struct i2c_client *client = hid->driver_data;
+	int report_id = buf[0];
+
+	if (report_type == HID_INPUT_REPORT)
+		return -EINVAL;
+
+	return i2c_hid_set_report(client,
+				report_type == HID_FEATURE_REPORT ? 0x03 : 0x02,
+				report_id, buf, count);
+}
+
+static int i2c_hid_parse(struct hid_device *hid)
+{
+	struct i2c_client *client = hid->driver_data;
+	struct i2c_hid *ihid = i2c_get_clientdata(client);
+	struct i2c_hid_desc *hdesc = &ihid->hdesc;
+	unsigned int rsize;
+	char *rdesc;
+	int ret;
+	int tries = 3;
+
+	i2c_hid_dbg(ihid, "entering %s\n", __func__);
+
+	rsize = le16_to_cpu(hdesc->wReportDescLength);
+	if (!rsize || rsize > HID_MAX_DESCRIPTOR_SIZE) {
+		dbg_hid("weird size of report descriptor (%u)\n", rsize);
+		return -EINVAL;
+	}
+
+	do {
+		ret = i2c_hid_hwreset(client);
+		if (ret)
+			msleep(1000);
+	} while (tries-- > 0 && ret);
+
+	if (ret)
+		return ret;
+
+	rdesc = kzalloc(rsize, GFP_KERNEL);
+
+	if (!rdesc) {
+		dbg_hid("couldn't allocate rdesc memory\n");
+		return -ENOMEM;
+	}
+
+	i2c_hid_dbg(ihid, "asking HID report descriptor\n");
+
+	ret = i2c_hid_command(client, &hid_report_descr_cmd, rdesc, rsize);
+	if (ret) {
+		hid_err(hid, "reading report descriptor failed\n");
+		kfree(rdesc);
+		return -EIO;
+	}
+
+	i2c_hid_dbg(ihid, "Report Descriptor: %*ph\n", rsize, rdesc);
+
+	ret = hid_parse_report(hid, rdesc, rsize);
+	kfree(rdesc);
+	if (ret) {
+		dbg_hid("parsing report descriptor failed\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static int i2c_hid_start(struct hid_device *hid)
+{
+	struct i2c_client *client = hid->driver_data;
+	struct i2c_hid *ihid = i2c_get_clientdata(client);
+	int ret;
+	unsigned int bufsize = HID_MIN_BUFFER_SIZE;
+
+	i2c_hid_find_max_report(hid, HID_INPUT_REPORT, &bufsize);
+	i2c_hid_find_max_report(hid, HID_OUTPUT_REPORT, &bufsize);
+	i2c_hid_find_max_report(hid, HID_FEATURE_REPORT, &bufsize);
+
+	if (bufsize > ihid->bufsize) {
+		i2c_hid_free_buffers(ihid);
+
+		ret = i2c_hid_alloc_buffers(ihid, bufsize);
+
+		if (ret)
+			return ret;
+	}
+
+	if (!(hid->quirks & HID_QUIRK_NO_INIT_REPORTS))
+		i2c_hid_init_reports(hid);
+
+	return 0;
+}
+
+static void i2c_hid_stop(struct hid_device *hid)
+{
+	struct i2c_client *client = hid->driver_data;
+	struct i2c_hid *ihid = i2c_get_clientdata(client);
+
+	hid->claimed = 0;
+
+	i2c_hid_free_buffers(ihid);
+}
+
+static int i2c_hid_open(struct hid_device *hid)
+{
+	struct i2c_client *client = hid->driver_data;
+	struct i2c_hid *ihid = i2c_get_clientdata(client);
+	int ret = 0;
+
+	mutex_lock(&i2c_hid_open_mut);
+	if (!hid->open++) {
+		ret = i2c_hid_set_power(client, I2C_HID_PWR_ON);
+		if (ret) {
+			hid->open--;
+			goto done;
+		}
+		set_bit(I2C_HID_STARTED, &ihid->flags);
+	}
+done:
+	mutex_unlock(&i2c_hid_open_mut);
+	return ret;
+}
+
+static void i2c_hid_close(struct hid_device *hid)
+{
+	struct i2c_client *client = hid->driver_data;
+	struct i2c_hid *ihid = i2c_get_clientdata(client);
+
+	/* protecting hid->open to make sure we don't restart
+	 * data acquistion due to a resumption we no longer
+	 * care about
+	 */
+	mutex_lock(&i2c_hid_open_mut);
+	if (!--hid->open) {
+		clear_bit(I2C_HID_STARTED, &ihid->flags);
+
+		/* Save some power */
+		i2c_hid_set_power(client, I2C_HID_PWR_SLEEP);
+	}
+	mutex_unlock(&i2c_hid_open_mut);
+}
+
+static int i2c_hid_power(struct hid_device *hid, int lvl)
+{
+	struct i2c_client *client = hid->driver_data;
+	struct i2c_hid *ihid = i2c_get_clientdata(client);
+	int ret = 0;
+
+	i2c_hid_dbg(ihid, "%s lvl:%d\n", __func__, lvl);
+
+	switch (lvl) {
+	case PM_HINT_FULLON:
+		ret = i2c_hid_set_power(client, I2C_HID_PWR_ON);
+		break;
+	case PM_HINT_NORMAL:
+		ret = i2c_hid_set_power(client, I2C_HID_PWR_SLEEP);
+		break;
+	}
+	return ret;
+}
+
+static int i2c_hid_hidinput_input_event(struct input_dev *dev,
+		unsigned int type, unsigned int code, int value)
+{
+	struct hid_device *hid = input_get_drvdata(dev);
+	struct hid_field *field;
+	int offset;
+
+	if (type == EV_FF)
+		return input_ff_event(dev, type, code, value);
+
+	if (type != EV_LED)
+		return -1;
+
+	offset = hidinput_find_field(hid, type, code, &field);
+
+	if (offset == -1) {
+		hid_warn(dev, "event field not found\n");
+		return -1;
+	}
+
+	return hid_set_field(field, offset, value);
+}
+
+static struct hid_ll_driver i2c_hid_ll_driver = {
+	.parse = i2c_hid_parse,
+	.start = i2c_hid_start,
+	.stop = i2c_hid_stop,
+	.open = i2c_hid_open,
+	.close = i2c_hid_close,
+	.power = i2c_hid_power,
+	.hidinput_input_event = i2c_hid_hidinput_input_event,
+};
+
+static int __devinit i2c_hid_init_irq(struct i2c_client *client)
+{
+	struct i2c_hid *ihid = i2c_get_clientdata(client);
+	int ret;
+
+	dev_dbg(&client->dev, "Requesting IRQ: %d\n", client->irq);
+
+	ret = request_threaded_irq(client->irq, NULL, i2c_hid_irq,
+			IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
+			client->name, ihid);
+	if (ret < 0) {
+		dev_warn(&client->dev,
+			"Could not register for %s interrupt, irq = %d,"
+			" ret = %d\n",
+			client->name, client->irq, ret);
+
+		return ret;
+	}
+
+	return 0;
+}
+
+static int __devinit i2c_hid_fetch_hid_descriptor(struct i2c_hid *ihid)
+{
+	struct i2c_client *client = ihid->client;
+	struct i2c_hid_desc *hdesc = &ihid->hdesc;
+	unsigned int dsize;
+	int ret;
+
+	/* Fetch the length of HID description, retrieve the 4 first bytes:
+	 * bytes 0-1 -> length
+	 * bytes 2-3 -> bcdVersion (has to be 1.00) */
+	ret = i2c_hid_command(client, &hid_descr_cmd, ihid->hdesc_buffer, 4);
+
+	i2c_hid_dbg(ihid, "%s, ihid->hdesc_buffer: %*ph\n",
+			__func__, 4, ihid->hdesc_buffer);
+
+	if (ret) {
+		dev_err(&client->dev,
+			"unable to fetch the size of HID descriptor (ret=%d)\n",
+			ret);
+		return -ENODEV;
+	}
+
+	dsize = le16_to_cpu(hdesc->wHIDDescLength);
+	/*
+	 * the size of the HID descriptor should at least contain
+	 * its size and the bcdVersion (4 bytes), and should not be greater
+	 * than sizeof(struct i2c_hid_desc) as we directly fill this struct
+	 * through i2c_hid_command.
+	 */
+	if (dsize < 4 || dsize > sizeof(struct i2c_hid_desc)) {
+		dev_err(&client->dev, "weird size of HID descriptor (%u)\n",
+			dsize);
+		return -ENODEV;
+	}
+
+	/* check bcdVersion == 1.0 */
+	if (le16_to_cpu(hdesc->bcdVersion) != 0x0100) {
+		dev_err(&client->dev,
+			"unexpected HID descriptor bcdVersion (0x%04hx)\n",
+			le16_to_cpu(hdesc->bcdVersion));
+		return -ENODEV;
+	}
+
+	i2c_hid_dbg(ihid, "Fetching the HID descriptor\n");
+
+	ret = i2c_hid_command(client, &hid_descr_cmd, ihid->hdesc_buffer,
+				dsize);
+	if (ret) {
+		dev_err(&client->dev, "hid_descr_cmd Fail\n");
+		return -ENODEV;
+	}
+
+	i2c_hid_dbg(ihid, "HID Descriptor: %*ph\n", dsize, ihid->hdesc_buffer);
+
+	return 0;
+}
+
+static int __devinit i2c_hid_probe(struct i2c_client *client,
+		const struct i2c_device_id *dev_id)
+{
+	int ret;
+	struct i2c_hid *ihid;
+	struct hid_device *hid;
+	__u16 hidRegister;
+	struct i2c_hid_platform_data *platform_data = client->dev.platform_data;
+
+	dbg_hid("HID probe called for i2c 0x%02x\n", client->addr);
+
+	if (!platform_data) {
+		dev_err(&client->dev, "HID register address not provided\n");
+		return -EINVAL;
+	}
+
+	if (!client->irq) {
+		dev_err(&client->dev,
+			"HID over i2c has not been provided an Int IRQ\n");
+		return -EINVAL;
+	}
+
+	ihid = kzalloc(sizeof(struct i2c_hid), GFP_KERNEL);
+	if (!ihid)
+		return -ENOMEM;
+
+	i2c_set_clientdata(client, ihid);
+
+	ihid->client = client;
+
+	hidRegister = platform_data->hid_descriptor_address;
+	ihid->wHIDDescRegister = cpu_to_le16(hidRegister);
+
+	init_waitqueue_head(&ihid->wait);
+
+	/* we need to allocate the command buffer without knowing the maximum
+	 * size of the reports. Let's use HID_MIN_BUFFER_SIZE, then we do the
+	 * real computation later. */
+	ret = i2c_hid_alloc_buffers(ihid, HID_MIN_BUFFER_SIZE);
+	if (ret < 0)
+		goto err;
+
+	ret = i2c_hid_fetch_hid_descriptor(ihid);
+	if (ret < 0)
+		goto err;
+
+	ret = i2c_hid_init_irq(client);
+	if (ret < 0)
+		goto err;
+
+	hid = hid_allocate_device();
+	if (IS_ERR(hid)) {
+		ret = PTR_ERR(hid);
+		goto err_irq;
+	}
+
+	ihid->hid = hid;
+
+	hid->driver_data = client;
+	hid->ll_driver = &i2c_hid_ll_driver;
+	hid->hid_get_raw_report = i2c_hid_get_raw_report;
+	hid->hid_output_raw_report = i2c_hid_output_raw_report;
+	hid->dev.parent = &client->dev;
+	hid->bus = BUS_I2C;
+	hid->version = le16_to_cpu(ihid->hdesc.bcdVersion);
+	hid->vendor = le16_to_cpu(ihid->hdesc.wVendorID);
+	hid->product = le16_to_cpu(ihid->hdesc.wProductID);
+
+	snprintf(hid->name, sizeof(hid->name), "%s %04hX:%04hX",
+		 client->name, hid->vendor, hid->product);
+
+	ret = hid_add_device(hid);
+	if (ret) {
+		if (ret != -ENODEV)
+			hid_err(client, "can't add hid device: %d\n", ret);
+		goto err_mem_free;
+	}
+
+	return 0;
+
+err_mem_free:
+	hid_destroy_device(hid);
+
+err_irq:
+	free_irq(client->irq, ihid);
+
+err:
+	i2c_hid_free_buffers(ihid);
+	kfree(ihid);
+	return ret;
+}
+
+static int __devexit i2c_hid_remove(struct i2c_client *client)
+{
+	struct i2c_hid *ihid = i2c_get_clientdata(client);
+	struct hid_device *hid;
+
+	hid = ihid->hid;
+	hid_destroy_device(hid);
+
+	free_irq(client->irq, ihid);
+
+	if (ihid->bufsize)
+		i2c_hid_free_buffers(ihid);
+
+	kfree(ihid);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int i2c_hid_suspend(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+
+	if (device_may_wakeup(&client->dev))
+		enable_irq_wake(client->irq);
+
+	/* Save some power */
+	i2c_hid_set_power(client, I2C_HID_PWR_SLEEP);
+
+	return 0;
+}
+
+static int i2c_hid_resume(struct device *dev)
+{
+	int ret;
+	struct i2c_client *client = to_i2c_client(dev);
+
+	ret = i2c_hid_hwreset(client);
+	if (ret)
+		return ret;
+
+	if (device_may_wakeup(&client->dev))
+		disable_irq_wake(client->irq);
+
+	return 0;
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(i2c_hid_pm, i2c_hid_suspend, i2c_hid_resume);
+
+static const struct i2c_device_id i2c_hid_id_table[] = {
+	{ "hid", 0 },
+	{ },
+};
+MODULE_DEVICE_TABLE(i2c, i2c_hid_id_table);
+
+
+static struct i2c_driver i2c_hid_driver = {
+	.driver = {
+		.name	= "i2c_hid",
+		.owner	= THIS_MODULE,
+		.pm	= &i2c_hid_pm,
+	},
+
+	.probe		= i2c_hid_probe,
+	.remove		= __devexit_p(i2c_hid_remove),
+
+	.id_table	= i2c_hid_id_table,
+};
+
+module_i2c_driver(i2c_hid_driver);
+
+MODULE_DESCRIPTION("HID over I2C core driver");
+MODULE_AUTHOR("Benjamin Tissoires <benjamin.tissoires@gmail.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c
index 11c7932..ac9e352 100644
--- a/drivers/hid/usbhid/hid-quirks.c
+++ b/drivers/hid/usbhid/hid-quirks.c
@@ -72,6 +72,7 @@
 	{ USB_VENDOR_ID_ELO, USB_DEVICE_ID_ELO_TS2700, HID_QUIRK_NOGET },
 	{ USB_VENDOR_ID_FREESCALE, USB_DEVICE_ID_FREESCALE_MX28, HID_QUIRK_NOGET },
 	{ USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS, HID_QUIRK_NOGET },
+	{ USB_VENDOR_ID_NOVATEK, USB_DEVICE_ID_NOVATEK_MOUSE, HID_QUIRK_NO_INIT_REPORTS },
 	{ USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN, HID_QUIRK_NO_INIT_REPORTS },
 	{ USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN1, HID_QUIRK_NO_INIT_REPORTS },
 	{ USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN2, HID_QUIRK_NO_INIT_REPORTS },
@@ -79,9 +80,11 @@
 	{ USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3001, HID_QUIRK_NOGET },
 	{ USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3008, HID_QUIRK_NOGET },
 	{ USB_VENDOR_ID_SENNHEISER, USB_DEVICE_ID_SENNHEISER_BTD500USB, HID_QUIRK_NOGET },
+	{ USB_VENDOR_ID_SIGMATEL, USB_DEVICE_ID_SIGMATEL_STMP3780, HID_QUIRK_NOGET },
 	{ USB_VENDOR_ID_SUN, USB_DEVICE_ID_RARITAN_KVM_DONGLE, HID_QUIRK_NOGET },
 	{ USB_VENDOR_ID_SYMBOL, USB_DEVICE_ID_SYMBOL_SCANNER_1, HID_QUIRK_NOGET },
 	{ USB_VENDOR_ID_SYMBOL, USB_DEVICE_ID_SYMBOL_SCANNER_2, HID_QUIRK_NOGET },
+	{ USB_VENDOR_ID_TPV, USB_DEVICE_ID_TPV_OPTICAL_TOUCHSCREEN, HID_QUIRK_NOGET },
 	{ USB_VENDOR_ID_TURBOX, USB_DEVICE_ID_TURBOX_KEYBOARD, HID_QUIRK_NOGET },
 	{ USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_PF1209, HID_QUIRK_MULTI_INPUT },
 	{ USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_WP4030U, HID_QUIRK_MULTI_INPUT },
diff --git a/drivers/hid/usbhid/hiddev.c b/drivers/hid/usbhid/hiddev.c
index 14599e2..87bd649 100644
--- a/drivers/hid/usbhid/hiddev.c
+++ b/drivers/hid/usbhid/hiddev.c
@@ -361,10 +361,6 @@
 			prepare_to_wait(&list->hiddev->wait, &wait, TASK_INTERRUPTIBLE);
 
 			while (list->head == list->tail) {
-				if (file->f_flags & O_NONBLOCK) {
-					retval = -EAGAIN;
-					break;
-				}
 				if (signal_pending(current)) {
 					retval = -ERESTARTSYS;
 					break;
@@ -373,6 +369,10 @@
 					retval = -EIO;
 					break;
 				}
+				if (file->f_flags & O_NONBLOCK) {
+					retval = -EAGAIN;
+					break;
+				}
 
 				/* let O_NONBLOCK tasks run */
 				mutex_unlock(&list->thread_lock);
@@ -625,7 +625,7 @@
 		break;
 
 	case HIDIOCAPPLICATION:
-		if (arg < 0 || arg >= hid->maxapplication)
+		if (arg >= hid->maxapplication)
 			break;
 
 		for (i = 0; i < hid->maxcollection; i++)
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index 4800d4c..32f238f 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -1208,6 +1208,14 @@
 	This driver can also be built as a module. If so it will be called
 	twl4030-madc-hwmon.
 
+config SENSORS_VEXPRESS
+	tristate "Versatile Express"
+	depends on VEXPRESS_CONFIG
+	help
+	  This driver provides support for hardware sensors available on
+	  the ARM Ltd's Versatile Express platform. It can provide wide
+	  range of information like temperature, power, energy.
+
 config SENSORS_VIA_CPUTEMP
 	tristate "VIA CPU temperature sensor"
 	depends on X86
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
index a930f09..5da2874 100644
--- a/drivers/hwmon/Makefile
+++ b/drivers/hwmon/Makefile
@@ -122,6 +122,7 @@
 obj-$(CONFIG_SENSORS_TMP401)	+= tmp401.o
 obj-$(CONFIG_SENSORS_TMP421)	+= tmp421.o
 obj-$(CONFIG_SENSORS_TWL4030_MADC)+= twl4030-madc-hwmon.o
+obj-$(CONFIG_SENSORS_VEXPRESS)	+= vexpress.o
 obj-$(CONFIG_SENSORS_VIA_CPUTEMP)+= via-cputemp.o
 obj-$(CONFIG_SENSORS_VIA686A)	+= via686a.o
 obj-$(CONFIG_SENSORS_VT1211)	+= vt1211.o
diff --git a/drivers/hwmon/vexpress.c b/drivers/hwmon/vexpress.c
new file mode 100644
index 0000000..59fd126
--- /dev/null
+++ b/drivers/hwmon/vexpress.c
@@ -0,0 +1,229 @@
+/*
+ * 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.
+ *
+ * Copyright (C) 2012 ARM Limited
+ */
+
+#define DRVNAME "vexpress-hwmon"
+#define pr_fmt(fmt) DRVNAME ": " fmt
+
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/hwmon.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/vexpress.h>
+
+struct vexpress_hwmon_data {
+	struct device *hwmon_dev;
+	struct vexpress_config_func *func;
+};
+
+static ssize_t vexpress_hwmon_name_show(struct device *dev,
+		struct device_attribute *dev_attr, char *buffer)
+{
+	const char *compatible = of_get_property(dev->of_node, "compatible",
+			NULL);
+
+	return sprintf(buffer, "%s\n", compatible);
+}
+
+static ssize_t vexpress_hwmon_label_show(struct device *dev,
+		struct device_attribute *dev_attr, char *buffer)
+{
+	const char *label = of_get_property(dev->of_node, "label", NULL);
+
+	if (!label)
+		return -ENOENT;
+
+	return snprintf(buffer, PAGE_SIZE, "%s\n", label);
+}
+
+static ssize_t vexpress_hwmon_u32_show(struct device *dev,
+		struct device_attribute *dev_attr, char *buffer)
+{
+	struct vexpress_hwmon_data *data = dev_get_drvdata(dev);
+	int err;
+	u32 value;
+
+	err = vexpress_config_read(data->func, 0, &value);
+	if (err)
+		return err;
+
+	return snprintf(buffer, PAGE_SIZE, "%u\n", value /
+			to_sensor_dev_attr(dev_attr)->index);
+}
+
+static ssize_t vexpress_hwmon_u64_show(struct device *dev,
+		struct device_attribute *dev_attr, char *buffer)
+{
+	struct vexpress_hwmon_data *data = dev_get_drvdata(dev);
+	int err;
+	u32 value_hi, value_lo;
+
+	err = vexpress_config_read(data->func, 0, &value_lo);
+	if (err)
+		return err;
+
+	err = vexpress_config_read(data->func, 1, &value_hi);
+	if (err)
+		return err;
+
+	return snprintf(buffer, PAGE_SIZE, "%llu\n",
+			div_u64(((u64)value_hi << 32) | value_lo,
+			to_sensor_dev_attr(dev_attr)->index));
+}
+
+static DEVICE_ATTR(name, S_IRUGO, vexpress_hwmon_name_show, NULL);
+
+#define VEXPRESS_HWMON_ATTRS(_name, _label_attr, _input_attr)	\
+struct attribute *vexpress_hwmon_attrs_##_name[] = {		\
+	&dev_attr_name.attr,					\
+	&dev_attr_##_label_attr.attr,				\
+	&sensor_dev_attr_##_input_attr.dev_attr.attr,		\
+	NULL							\
+}
+
+#if !defined(CONFIG_REGULATOR_VEXPRESS)
+static DEVICE_ATTR(in1_label, S_IRUGO, vexpress_hwmon_label_show, NULL);
+static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, vexpress_hwmon_u32_show,
+		NULL, 1000);
+static VEXPRESS_HWMON_ATTRS(volt, in1_label, in1_input);
+static struct attribute_group vexpress_hwmon_group_volt = {
+	.attrs = vexpress_hwmon_attrs_volt,
+};
+#endif
+
+static DEVICE_ATTR(curr1_label, S_IRUGO, vexpress_hwmon_label_show, NULL);
+static SENSOR_DEVICE_ATTR(curr1_input, S_IRUGO, vexpress_hwmon_u32_show,
+		NULL, 1000);
+static VEXPRESS_HWMON_ATTRS(amp, curr1_label, curr1_input);
+static struct attribute_group vexpress_hwmon_group_amp = {
+	.attrs = vexpress_hwmon_attrs_amp,
+};
+
+static DEVICE_ATTR(temp1_label, S_IRUGO, vexpress_hwmon_label_show, NULL);
+static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, vexpress_hwmon_u32_show,
+		NULL, 1000);
+static VEXPRESS_HWMON_ATTRS(temp, temp1_label, temp1_input);
+static struct attribute_group vexpress_hwmon_group_temp = {
+	.attrs = vexpress_hwmon_attrs_temp,
+};
+
+static DEVICE_ATTR(power1_label, S_IRUGO, vexpress_hwmon_label_show, NULL);
+static SENSOR_DEVICE_ATTR(power1_input, S_IRUGO, vexpress_hwmon_u32_show,
+		NULL, 1);
+static VEXPRESS_HWMON_ATTRS(power, power1_label, power1_input);
+static struct attribute_group vexpress_hwmon_group_power = {
+	.attrs = vexpress_hwmon_attrs_power,
+};
+
+static DEVICE_ATTR(energy1_label, S_IRUGO, vexpress_hwmon_label_show, NULL);
+static SENSOR_DEVICE_ATTR(energy1_input, S_IRUGO, vexpress_hwmon_u64_show,
+		NULL, 1);
+static VEXPRESS_HWMON_ATTRS(energy, energy1_label, energy1_input);
+static struct attribute_group vexpress_hwmon_group_energy = {
+	.attrs = vexpress_hwmon_attrs_energy,
+};
+
+static struct of_device_id vexpress_hwmon_of_match[] = {
+#if !defined(CONFIG_REGULATOR_VEXPRESS)
+	{
+		.compatible = "arm,vexpress-volt",
+		.data = &vexpress_hwmon_group_volt,
+	},
+#endif
+	{
+		.compatible = "arm,vexpress-amp",
+		.data = &vexpress_hwmon_group_amp,
+	}, {
+		.compatible = "arm,vexpress-temp",
+		.data = &vexpress_hwmon_group_temp,
+	}, {
+		.compatible = "arm,vexpress-power",
+		.data = &vexpress_hwmon_group_power,
+	}, {
+		.compatible = "arm,vexpress-energy",
+		.data = &vexpress_hwmon_group_energy,
+	},
+	{}
+};
+MODULE_DEVICE_TABLE(of, vexpress_hwmon_of_match);
+
+static int vexpress_hwmon_probe(struct platform_device *pdev)
+{
+	int err;
+	const struct of_device_id *match;
+	struct vexpress_hwmon_data *data;
+
+	data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
+	platform_set_drvdata(pdev, data);
+
+	match = of_match_device(vexpress_hwmon_of_match, &pdev->dev);
+	if (!match)
+		return -ENODEV;
+
+	data->func = vexpress_config_func_get_by_dev(&pdev->dev);
+	if (!data->func)
+		return -ENODEV;
+
+	err = sysfs_create_group(&pdev->dev.kobj, match->data);
+	if (err)
+		goto error;
+
+	data->hwmon_dev = hwmon_device_register(&pdev->dev);
+	if (IS_ERR(data->hwmon_dev)) {
+		err = PTR_ERR(data->hwmon_dev);
+		goto error;
+	}
+
+	return 0;
+
+error:
+	sysfs_remove_group(&pdev->dev.kobj, match->data);
+	vexpress_config_func_put(data->func);
+	return err;
+}
+
+static int __devexit vexpress_hwmon_remove(struct platform_device *pdev)
+{
+	struct vexpress_hwmon_data *data = platform_get_drvdata(pdev);
+	const struct of_device_id *match;
+
+	hwmon_device_unregister(data->hwmon_dev);
+
+	match = of_match_device(vexpress_hwmon_of_match, &pdev->dev);
+	sysfs_remove_group(&pdev->dev.kobj, match->data);
+
+	vexpress_config_func_put(data->func);
+
+	return 0;
+}
+
+static struct platform_driver vexpress_hwmon_driver = {
+	.probe = vexpress_hwmon_probe,
+	.remove = __devexit_p(vexpress_hwmon_remove),
+	.driver	= {
+		.name = DRVNAME,
+		.owner = THIS_MODULE,
+		.of_match_table = vexpress_hwmon_of_match,
+	},
+};
+
+module_platform_driver(vexpress_hwmon_driver);
+
+MODULE_AUTHOR("Pawel Moll <pawel.moll@arm.com>");
+MODULE_DESCRIPTION("Versatile Express hwmon sensors driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:vexpress-hwmon");
diff --git a/drivers/i2c/busses/i2c-nuc900.c b/drivers/i2c/busses/i2c-nuc900.c
index f41502e..a23b91b 100644
--- a/drivers/i2c/busses/i2c-nuc900.c
+++ b/drivers/i2c/busses/i2c-nuc900.c
@@ -304,7 +304,7 @@
 
 	case STATE_READ:
 		/* we have a byte of data in the data register, do
-		 * something with it, and then work out wether we are
+		 * something with it, and then work out whether we are
 		 * going to do any more read/write
 		 */
 
diff --git a/drivers/i2c/busses/i2c-s3c2410.c b/drivers/i2c/busses/i2c-s3c2410.c
index 9d90272..b33d95e 100644
--- a/drivers/i2c/busses/i2c-s3c2410.c
+++ b/drivers/i2c/busses/i2c-s3c2410.c
@@ -208,7 +208,7 @@
 	if (msg->flags & I2C_M_REV_DIR_ADDR)
 		addr ^= 1;
 
-	/* todo - check for wether ack wanted or not */
+	/* todo - check for whether ack wanted or not */
 	s3c24xx_i2c_enable_ack(i2c);
 
 	iiccon = readl(i2c->regs + S3C2410_IICCON);
@@ -397,7 +397,7 @@
 
 	case STATE_READ:
 		/* we have a byte of data in the data register, do
-		 * something with it, and then work out wether we are
+		 * something with it, and then work out whether we are
 		 * going to do any more read/write
 		 */
 
diff --git a/drivers/input/input-mt.c b/drivers/input/input-mt.c
index 1abbc17..8c4b50f 100644
--- a/drivers/input/input-mt.c
+++ b/drivers/input/input-mt.c
@@ -251,7 +251,7 @@
 
 	if (mt->flags & INPUT_MT_DROP_UNUSED) {
 		for (s = mt->slots; s != mt->slots + mt->num_slots; s++) {
-			if (s->frame == mt->frame)
+			if (input_mt_is_used(mt, s))
 				continue;
 			input_mt_slot(dev, s - mt->slots);
 			input_event(dev, EV_ABS, ABS_MT_TRACKING_ID, -1);
diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
index de08740..77629d3 100644
--- a/drivers/input/keyboard/Kconfig
+++ b/drivers/input/keyboard/Kconfig
@@ -409,7 +409,7 @@
 
 config KEYBOARD_NOMADIK
 	tristate "ST-Ericsson Nomadik SKE keyboard"
-	depends on PLAT_NOMADIK
+	depends on (ARCH_NOMADIK || ARCH_U8500)
 	select INPUT_MATRIXKMAP
 	help
 	  Say Y here if you want to use a keypad provided on the SKE controller
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
index 7c0f1ec..104a7c3 100644
--- a/drivers/input/misc/Kconfig
+++ b/drivers/input/misc/Kconfig
@@ -72,6 +72,16 @@
 	  To compile this driver as a module, choose M here: the
 	  module will be called ad714x-spi.
 
+config INPUT_ARIZONA_HAPTICS
+	tristate "Arizona haptics support"
+	depends on MFD_ARIZONA && SND_SOC
+	select INPUT_FF_MEMLESS
+	help
+	  Say Y to enable support for the haptics module in Arizona CODECs.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called arizona-haptics.
+
 config INPUT_BMA150
 	tristate "BMA150/SMB380 acceleration sensor support"
 	depends on I2C
diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile
index 83fe6f5..5ea769e 100644
--- a/drivers/input/misc/Makefile
+++ b/drivers/input/misc/Makefile
@@ -14,6 +14,7 @@
 obj-$(CONFIG_INPUT_ADXL34X_I2C)		+= adxl34x-i2c.o
 obj-$(CONFIG_INPUT_ADXL34X_SPI)		+= adxl34x-spi.o
 obj-$(CONFIG_INPUT_APANEL)		+= apanel.o
+obj-$(CONFIG_INPUT_ARIZONA_HAPTICS)	+= arizona-haptics.o
 obj-$(CONFIG_INPUT_ATI_REMOTE2)		+= ati_remote2.o
 obj-$(CONFIG_INPUT_ATLAS_BTNS)		+= atlas_btns.o
 obj-$(CONFIG_INPUT_BFIN_ROTARY)		+= bfin_rotary.o
diff --git a/drivers/input/misc/arizona-haptics.c b/drivers/input/misc/arizona-haptics.c
new file mode 100644
index 0000000..7a04f54
--- /dev/null
+++ b/drivers/input/misc/arizona-haptics.c
@@ -0,0 +1,255 @@
+/*
+ * Arizona haptics 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/platform_device.h>
+#include <linux/input.h>
+#include <linux/slab.h>
+
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+
+#include <linux/mfd/arizona/core.h>
+#include <linux/mfd/arizona/pdata.h>
+#include <linux/mfd/arizona/registers.h>
+
+struct arizona_haptics {
+	struct arizona *arizona;
+	struct input_dev *input_dev;
+	struct work_struct work;
+
+	struct mutex mutex;
+	u8 intensity;
+};
+
+static void arizona_haptics_work(struct work_struct *work)
+{
+	struct arizona_haptics *haptics = container_of(work,
+						       struct arizona_haptics,
+						       work);
+	struct arizona *arizona = haptics->arizona;
+	struct mutex *dapm_mutex = &arizona->dapm->card->dapm_mutex;
+	int ret;
+
+	if (!haptics->arizona->dapm) {
+		dev_err(arizona->dev, "No DAPM context\n");
+		return;
+	}
+
+	if (haptics->intensity) {
+		ret = regmap_update_bits(arizona->regmap,
+					 ARIZONA_HAPTICS_PHASE_2_INTENSITY,
+					 ARIZONA_PHASE2_INTENSITY_MASK,
+					 haptics->intensity);
+		if (ret != 0) {
+			dev_err(arizona->dev, "Failed to set intensity: %d\n",
+				ret);
+			return;
+		}
+
+		/* This enable sequence will be a noop if already enabled */
+		ret = regmap_update_bits(arizona->regmap,
+					 ARIZONA_HAPTICS_CONTROL_1,
+					 ARIZONA_HAP_CTRL_MASK,
+					 1 << ARIZONA_HAP_CTRL_SHIFT);
+		if (ret != 0) {
+			dev_err(arizona->dev, "Failed to start haptics: %d\n",
+				ret);
+			return;
+		}
+
+		mutex_lock_nested(dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
+
+		ret = snd_soc_dapm_enable_pin(arizona->dapm, "HAPTICS");
+		if (ret != 0) {
+			dev_err(arizona->dev, "Failed to start HAPTICS: %d\n",
+				ret);
+			mutex_unlock(dapm_mutex);
+			return;
+		}
+
+		ret = snd_soc_dapm_sync(arizona->dapm);
+		if (ret != 0) {
+			dev_err(arizona->dev, "Failed to sync DAPM: %d\n",
+				ret);
+			mutex_unlock(dapm_mutex);
+			return;
+		}
+
+		mutex_unlock(dapm_mutex);
+
+	} else {
+		/* This disable sequence will be a noop if already enabled */
+		mutex_lock_nested(dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
+
+		ret = snd_soc_dapm_disable_pin(arizona->dapm, "HAPTICS");
+		if (ret != 0) {
+			dev_err(arizona->dev, "Failed to disable HAPTICS: %d\n",
+				ret);
+			mutex_unlock(dapm_mutex);
+			return;
+		}
+
+		ret = snd_soc_dapm_sync(arizona->dapm);
+		if (ret != 0) {
+			dev_err(arizona->dev, "Failed to sync DAPM: %d\n",
+				ret);
+			mutex_unlock(dapm_mutex);
+			return;
+		}
+
+		mutex_unlock(dapm_mutex);
+
+		ret = regmap_update_bits(arizona->regmap,
+					 ARIZONA_HAPTICS_CONTROL_1,
+					 ARIZONA_HAP_CTRL_MASK,
+					 1 << ARIZONA_HAP_CTRL_SHIFT);
+		if (ret != 0) {
+			dev_err(arizona->dev, "Failed to stop haptics: %d\n",
+				ret);
+			return;
+		}
+	}
+}
+
+static int arizona_haptics_play(struct input_dev *input, void *data,
+				struct ff_effect *effect)
+{
+	struct arizona_haptics *haptics = input_get_drvdata(input);
+	struct arizona *arizona = haptics->arizona;
+
+	if (!arizona->dapm) {
+		dev_err(arizona->dev, "No DAPM context\n");
+		return -EBUSY;
+	}
+
+	if (effect->u.rumble.strong_magnitude) {
+		/* Scale the magnitude into the range the device supports */
+		if (arizona->pdata.hap_act) {
+			haptics->intensity =
+				effect->u.rumble.strong_magnitude >> 9;
+			if (effect->direction < 0x8000)
+				haptics->intensity += 0x7f;
+		} else {
+			haptics->intensity =
+				effect->u.rumble.strong_magnitude >> 8;
+		}
+	} else {
+		haptics->intensity = 0;
+	}
+
+	schedule_work(&haptics->work);
+
+	return 0;
+}
+
+static void arizona_haptics_close(struct input_dev *input)
+{
+	struct arizona_haptics *haptics = input_get_drvdata(input);
+	struct mutex *dapm_mutex = &haptics->arizona->dapm->card->dapm_mutex;
+
+	cancel_work_sync(&haptics->work);
+
+	mutex_lock_nested(dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
+
+	if (haptics->arizona->dapm)
+		snd_soc_dapm_disable_pin(haptics->arizona->dapm, "HAPTICS");
+
+	mutex_unlock(dapm_mutex);
+}
+
+static int arizona_haptics_probe(struct platform_device *pdev)
+{
+	struct arizona *arizona = dev_get_drvdata(pdev->dev.parent);
+	struct arizona_haptics *haptics;
+	int ret;
+
+	haptics = devm_kzalloc(&pdev->dev, sizeof(*haptics), GFP_KERNEL);
+	if (!haptics)
+		return -ENOMEM;
+
+	haptics->arizona = arizona;
+
+	ret = regmap_update_bits(arizona->regmap, ARIZONA_HAPTICS_CONTROL_1,
+				 ARIZONA_HAP_ACT, arizona->pdata.hap_act);
+	if (ret != 0) {
+		dev_err(arizona->dev, "Failed to set haptics actuator: %d\n",
+			ret);
+		return ret;
+	}
+
+	INIT_WORK(&haptics->work, arizona_haptics_work);
+
+	haptics->input_dev = input_allocate_device();
+	if (haptics->input_dev == NULL) {
+		dev_err(arizona->dev, "Failed to allocate input device\n");
+		return -ENOMEM;
+	}
+
+	input_set_drvdata(haptics->input_dev, haptics);
+
+	haptics->input_dev->name = "arizona:haptics";
+	haptics->input_dev->dev.parent = pdev->dev.parent;
+	haptics->input_dev->close = arizona_haptics_close;
+	__set_bit(FF_RUMBLE, haptics->input_dev->ffbit);
+
+	ret = input_ff_create_memless(haptics->input_dev, NULL,
+				      arizona_haptics_play);
+	if (ret < 0) {
+		dev_err(arizona->dev, "input_ff_create_memless() failed: %d\n",
+			ret);
+		goto err_ialloc;
+	}
+
+	ret = input_register_device(haptics->input_dev);
+	if (ret < 0) {
+		dev_err(arizona->dev, "couldn't register input device: %d\n",
+			ret);
+		goto err_iff;
+	}
+
+	platform_set_drvdata(pdev, haptics);
+
+	return 0;
+
+err_iff:
+	if (haptics->input_dev)
+		input_ff_destroy(haptics->input_dev);
+err_ialloc:
+	input_free_device(haptics->input_dev);
+
+	return ret;
+}
+
+static int arizona_haptics_remove(struct platform_device *pdev)
+{
+	struct arizona_haptics *haptics = platform_get_drvdata(pdev);
+
+	input_unregister_device(haptics->input_dev);
+
+	return 0;
+}
+
+static struct platform_driver arizona_haptics_driver = {
+	.probe		= arizona_haptics_probe,
+	.remove		= arizona_haptics_remove,
+	.driver		= {
+		.name	= "arizona-haptics",
+		.owner	= THIS_MODULE,
+	},
+};
+module_platform_driver(arizona_haptics_driver);
+
+MODULE_ALIAS("platform:arizona-haptics");
+MODULE_DESCRIPTION("Arizona haptics driver");
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
diff --git a/drivers/isdn/hisax/amd7930_fn.c b/drivers/isdn/hisax/amd7930_fn.c
index 89342f7..525471e 100644
--- a/drivers/isdn/hisax/amd7930_fn.c
+++ b/drivers/isdn/hisax/amd7930_fn.c
@@ -628,7 +628,7 @@
 		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
+			Amd7930_ph_command(cs, 0x20, "HW_RESET REQUEST"); //LMR1 bit 5
 			spin_unlock_irqrestore(&cs->lock, flags);
 		} else {
 			Amd7930_ph_command(cs, 0x40, "HW_RESET REQUEST");
diff --git a/drivers/isdn/hisax/isar.c b/drivers/isdn/hisax/isar.c
index ff5e139..7fdf347 100644
--- a/drivers/isdn/hisax/isar.c
+++ b/drivers/isdn/hisax/isar.c
@@ -1417,7 +1417,7 @@
 						   &bcs->hw.isar.reg->Flags))
 				bcs->hw.isar.dpath = 1;
 			else {
-				printk(KERN_WARNING"isar modeisar both pathes in use\n");
+				printk(KERN_WARNING"isar modeisar both paths in use\n");
 				return (1);
 			}
 			break;
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 6120071..bd8bf09 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -4124,7 +4124,7 @@
 __ATTR(component_size, S_IRUGO|S_IWUSR, size_show, size_store);
 
 
-/* Metdata version.
+/* Metadata version.
  * This is one of
  *   'none' for arrays with no metadata (good luck...)
  *   'external' for arrays with externally managed metadata,
diff --git a/drivers/md/persistent-data/dm-block-manager.c b/drivers/md/persistent-data/dm-block-manager.c
index 5ba2777..a3ae091 100644
--- a/drivers/md/persistent-data/dm-block-manager.c
+++ b/drivers/md/persistent-data/dm-block-manager.c
@@ -25,7 +25,7 @@
  * may be held at once.  This is just an implementation detail.
  *
  * ii) Recursive locking attempts are detected and return EINVAL.  A stack
- * trace is also emitted for the previous lock aquisition.
+ * trace is also emitted for the previous lock acquisition.
  *
  * iii) Priority is given to write locks.
  */
@@ -109,7 +109,7 @@
 			DMERR("previously held here:");
 			print_stack_trace(lock->traces + i, 4);
 
-			DMERR("subsequent aquisition attempted here:");
+			DMERR("subsequent acquisition attempted here:");
 			t.nr_entries = 0;
 			t.max_entries = MAX_STACK;
 			t.entries = entries;
diff --git a/drivers/md/persistent-data/dm-btree.h b/drivers/md/persistent-data/dm-btree.h
index ae02c84..a2cd5044 100644
--- a/drivers/md/persistent-data/dm-btree.h
+++ b/drivers/md/persistent-data/dm-btree.h
@@ -35,7 +35,7 @@
  */
 
 /*
- * Infomation about the values stored within the btree.
+ * Information about the values stored within the btree.
  */
 struct dm_btree_value_type {
 	void *context;
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index a450268..3380372 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -1576,7 +1576,7 @@
 	 * This happens in stages:
 	 * 1/ create a new kmem_cache and allocate the required number of
 	 *    stripe_heads.
-	 * 2/ gather all the old stripe_heads and tranfer the pages across
+	 * 2/ gather all the old stripe_heads and transfer the pages across
 	 *    to the new stripe_heads.  This will have the side effect of
 	 *    freezing the array as once all stripe_heads have been collected,
 	 *    no IO will be possible.  Old stripe heads are freed once their
diff --git a/drivers/media/dvb-frontends/drxk_hard.c b/drivers/media/dvb-frontends/drxk_hard.c
index 8b4c6d5..df9abe8 100644
--- a/drivers/media/dvb-frontends/drxk_hard.c
+++ b/drivers/media/dvb-frontends/drxk_hard.c
@@ -948,7 +948,7 @@
 		state->m_oscClockFreq = 20250;
 		break;
 	default:
-		printk(KERN_ERR "drxk: Clock Frequency is unkonwn\n");
+		printk(KERN_ERR "drxk: Clock Frequency is unknown\n");
 		return -EINVAL;
 	}
 	/*
diff --git a/drivers/media/platform/mx2_emmaprp.c b/drivers/media/platform/mx2_emmaprp.c
index 8f22ce5..bfa6507 100644
--- a/drivers/media/platform/mx2_emmaprp.c
+++ b/drivers/media/platform/mx2_emmaprp.c
@@ -371,7 +371,7 @@
 	if (!curr_ctx->aborting) {
 		if ((irqst & PRP_INTR_ST_RDERR) ||
 		(irqst & PRP_INTR_ST_CH2WERR)) {
-			pr_err("PrP bus error ocurred, this transfer is probably corrupted\n");
+			pr_err("PrP bus error occurred, this transfer is probably corrupted\n");
 			writel(PRP_CNTL_SWRST, pcdev->base_emma + PRP_CNTL);
 		} else if (irqst & PRP_INTR_ST_CH2B1CI) { /* buffer ready */
 			src_vb = v4l2_m2m_src_buf_remove(curr_ctx->m2m_ctx);
diff --git a/drivers/media/platform/omap/omap_vout.c b/drivers/media/platform/omap/omap_vout.c
index 4b1becc..9935040 100644
--- a/drivers/media/platform/omap/omap_vout.c
+++ b/drivers/media/platform/omap/omap_vout.c
@@ -45,7 +45,7 @@
 #include <media/v4l2-ioctl.h>
 
 #include <plat/cpu.h>
-#include <plat-omap/dma-omap.h>
+#include <linux/omap-dma.h>
 #include <video/omapvrfb.h>
 #include <video/omapdss.h>
 
diff --git a/drivers/media/platform/omap/omap_vout_vrfb.c b/drivers/media/platform/omap/omap_vout_vrfb.c
index 8340445..cf1c437 100644
--- a/drivers/media/platform/omap/omap_vout_vrfb.c
+++ b/drivers/media/platform/omap/omap_vout_vrfb.c
@@ -16,7 +16,7 @@
 #include <media/videobuf-dma-contig.h>
 #include <media/v4l2-device.h>
 
-#include <plat-omap/dma-omap.h>
+#include <linux/omap-dma.h>
 #include <video/omapvrfb.h>
 
 #include "omap_voutdef.h"
diff --git a/drivers/media/platform/omap3isp/ispstat.h b/drivers/media/platform/omap3isp/ispstat.h
index 99cf104..fd15094 100644
--- a/drivers/media/platform/omap3isp/ispstat.h
+++ b/drivers/media/platform/omap3isp/ispstat.h
@@ -30,7 +30,7 @@
 
 #include <linux/types.h>
 #include <linux/omap3isp.h>
-#include <plat-omap/dma-omap.h>
+#include <linux/omap-dma.h>
 #include <media/v4l2-event.h>
 
 #include "isp.h"
diff --git a/drivers/media/platform/soc_camera/omap1_camera.c b/drivers/media/platform/soc_camera/omap1_camera.c
index d3cfe65..39a77f0 100644
--- a/drivers/media/platform/soc_camera/omap1_camera.c
+++ b/drivers/media/platform/soc_camera/omap1_camera.c
@@ -34,7 +34,7 @@
 #include <media/videobuf-dma-contig.h>
 #include <media/videobuf-dma-sg.h>
 
-#include <plat-omap/dma-omap.h>
+#include <linux/omap-dma.h>
 
 
 #define DRIVER_NAME		"omap1-camera"
diff --git a/drivers/message/i2o/README.ioctl b/drivers/message/i2o/README.ioctl
index 5fb195af4..4a7d2eb 100644
--- a/drivers/message/i2o/README.ioctl
+++ b/drivers/message/i2o/README.ioctl
@@ -138,7 +138,7 @@
 
    The return value is the size in bytes of the data written into
    ops->resbuf if no errors occur.  If an error occurs, -1 is returned 
-   and errno is set appropriatly:
+   and errno is set appropriately:
 
       EFAULT      Invalid user space pointer was passed
       ENXIO       Invalid IOP number
@@ -222,7 +222,7 @@
    RETURNS
 
    This function returns 0 no errors occur. If an error occurs, -1 
-   is returned and errno is set appropriatly:
+   is returned and errno is set appropriately:
 
       EFAULT      Invalid user space pointer was passed
       ENXIO       Invalid IOP number
@@ -264,7 +264,7 @@
    RETURNS
 
    This function returns 0 if no errors occur.  If an error occurs, -1
-   is returned and errno is set appropriatly:
+   is returned and errno is set appropriately:
 
       EFAULT      Invalid user space pointer was passed
       ENXIO       Invalid IOP number
@@ -301,7 +301,7 @@
    RETURNS
 
    This function returns 0 if no errors occur.  If an error occurs, -1
-   is returned and errno is set appropriatly:
+   is returned and errno is set appropriately:
 
       EFAULT      Invalid user space pointer was passed
       ENXIO       Invalid IOP number
@@ -325,7 +325,7 @@
    RETURNS
 
    This function returns 0 if no erro occur.  If an error occurs, -1 is
-   returned and errno is set appropriatly:
+   returned and errno is set appropriately:
 
       ETIMEDOUT   Timeout waiting for reply message
       ENXIO       Invalid IOP number
@@ -360,7 +360,7 @@
    RETURNS
 
    This function returns 0 if no error occur. If an error occurs, -1
-   is returned and errno is set appropriatly:
+   is returned and errno is set appropriately:
 
       EFAULT      Invalid user space pointer was passed
       ENXIO       Invalid IOP number
diff --git a/drivers/message/i2o/i2o_block.c b/drivers/message/i2o/i2o_block.c
index 4796bbf..49e86ae 100644
--- a/drivers/message/i2o/i2o_block.c
+++ b/drivers/message/i2o/i2o_block.c
@@ -609,7 +609,7 @@
 	u8 operation;
 
 	/*
-	 * This is to deail with the case of an application
+	 * This is to deal with the case of an application
 	 * opening a device and then the device disappears while
 	 * it's in use, and then the application tries to release
 	 * it.  ex: Unmounting a deleted RAID volume at reboot.
diff --git a/drivers/message/i2o/i2o_config.c b/drivers/message/i2o/i2o_config.c
index 9a49c24..5451bef 100644
--- a/drivers/message/i2o/i2o_config.c
+++ b/drivers/message/i2o/i2o_config.c
@@ -189,7 +189,7 @@
 		return -ENXIO;
 
 	/*
-	 * Stop users being able to try and allocate arbitary amounts
+	 * Stop users being able to try and allocate arbitrary amounts
 	 * of DMA space. 64K is way more than sufficient for this.
 	 */
 	if (kcmd.oplen > 65536)
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 94bdf83..b63987c 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -211,7 +211,6 @@
 	depends on I2C=y && GENERIC_HARDIRQS
 	select MFD_CORE
 	select REGMAP_I2C
-	depends on REGULATOR
 	help
 	  If you say yes here you get support for the TPS6586X series of
 	  Power Management chips.
diff --git a/drivers/mfd/ab8500-core.c b/drivers/mfd/ab8500-core.c
index 127b00a..3e27c03 100644
--- a/drivers/mfd/ab8500-core.c
+++ b/drivers/mfd/ab8500-core.c
@@ -565,15 +565,10 @@
 	else
 		num_irqs = AB8500_NR_IRQS;
 
-	if (ab8500->irq_base) {
-		ab8500->domain = irq_domain_add_legacy(
-			NULL, num_irqs, ab8500->irq_base,
-			0, &ab8500_irq_ops, ab8500);
-	}
-	else {
-		ab8500->domain = irq_domain_add_linear(
-			np, num_irqs, &ab8500_irq_ops, ab8500);
-	}
+	/* If ->irq_base is zero this will give a linear mapping */
+	ab8500->domain = irq_domain_add_simple(NULL,
+			num_irqs, ab8500->irq_base,
+			&ab8500_irq_ops, ab8500);
 
 	if (!ab8500->domain) {
 		dev_err(ab8500->dev, "Failed to create irqdomain\n");
diff --git a/drivers/mfd/arizona-core.c b/drivers/mfd/arizona-core.c
index 1a6f943f..c784f46 100644
--- a/drivers/mfd/arizona-core.c
+++ b/drivers/mfd/arizona-core.c
@@ -272,6 +272,7 @@
 static struct mfd_cell wm5102_devs[] = {
 	{ .name = "arizona-extcon" },
 	{ .name = "arizona-gpio" },
+	{ .name = "arizona-haptics" },
 	{ .name = "arizona-micsupp" },
 	{ .name = "arizona-pwm" },
 	{ .name = "wm5102-codec" },
@@ -280,6 +281,7 @@
 static struct mfd_cell wm5110_devs[] = {
 	{ .name = "arizona-extcon" },
 	{ .name = "arizona-gpio" },
+	{ .name = "arizona-haptics" },
 	{ .name = "arizona-micsupp" },
 	{ .name = "arizona-pwm" },
 	{ .name = "wm5110-codec" },
diff --git a/drivers/mfd/db8500-prcmu.c b/drivers/mfd/db8500-prcmu.c
index dc56915..2971056 100644
--- a/drivers/mfd/db8500-prcmu.c
+++ b/drivers/mfd/db8500-prcmu.c
@@ -2743,9 +2743,15 @@
 
 static int db8500_irq_init(struct device_node *np)
 {
-	db8500_irq_domain = irq_domain_add_legacy(
-		np, NUM_PRCMU_WAKEUPS, IRQ_PRCMU_BASE,
-		0, &db8500_irq_ops, NULL);
+	int irq_base = -1;
+
+	/* In the device tree case, just take some IRQs */
+	if (!np)
+		irq_base = IRQ_PRCMU_BASE;
+
+	db8500_irq_domain = irq_domain_add_simple(
+		np, NUM_PRCMU_WAKEUPS, irq_base,
+		&db8500_irq_ops, NULL);
 
 	if (!db8500_irq_domain) {
 		pr_err("Failed to create irqdomain\n");
diff --git a/drivers/mfd/max8997.c b/drivers/mfd/max8997.c
index f1235170..abd5c80 100644
--- a/drivers/mfd/max8997.c
+++ b/drivers/mfd/max8997.c
@@ -21,8 +21,10 @@
  * This driver is based on max8998.c
  */
 
+#include <linux/err.h>
 #include <linux/slab.h>
 #include <linux/i2c.h>
+#include <linux/of_irq.h>
 #include <linux/interrupt.h>
 #include <linux/pm_runtime.h>
 #include <linux/module.h>
@@ -47,6 +49,13 @@
 	{ .name = "max8997-led", .id = 2 },
 };
 
+#ifdef CONFIG_OF
+static struct of_device_id __devinitdata max8997_pmic_dt_match[] = {
+	{ .compatible = "maxim,max8997-pmic", .data = TYPE_MAX8997 },
+	{},
+};
+#endif
+
 int max8997_read_reg(struct i2c_client *i2c, u8 reg, u8 *dest)
 {
 	struct max8997_dev *max8997 = i2c_get_clientdata(i2c);
@@ -123,6 +132,58 @@
 }
 EXPORT_SYMBOL_GPL(max8997_update_reg);
 
+#ifdef CONFIG_OF
+/*
+ * Only the common platform data elements for max8997 are parsed here from the
+ * device tree. Other sub-modules of max8997 such as pmic, rtc and others have
+ * to parse their own platform data elements from device tree.
+ *
+ * The max8997 platform data structure is instantiated here and the drivers for
+ * the sub-modules need not instantiate another instance while parsing their
+ * platform data.
+ */
+static struct max8997_platform_data *max8997_i2c_parse_dt_pdata(
+					struct device *dev)
+{
+	struct max8997_platform_data *pd;
+
+	pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL);
+	if (!pd) {
+		dev_err(dev, "could not allocate memory for pdata\n");
+		return ERR_PTR(-ENOMEM);
+	}
+
+	pd->ono = irq_of_parse_and_map(dev->of_node, 1);
+
+	/*
+	 * ToDo: the 'wakeup' member in the platform data is more of a linux
+	 * specfic information. Hence, there is no binding for that yet and
+	 * not parsed here.
+	 */
+
+	return pd;
+}
+#else
+static struct max8997_platform_data *max8997_i2c_parse_dt_pdata(
+					struct device *dev)
+{
+	return 0;
+}
+#endif
+
+static inline int max8997_i2c_get_driver_data(struct i2c_client *i2c,
+						const struct i2c_device_id *id)
+{
+#ifdef CONFIG_OF
+	if (i2c->dev.of_node) {
+		const struct of_device_id *match;
+		match = of_match_node(max8997_pmic_dt_match, i2c->dev.of_node);
+		return (int)match->data;
+	}
+#endif
+	return (int)id->driver_data;
+}
+
 static int max8997_i2c_probe(struct i2c_client *i2c,
 			    const struct i2c_device_id *id)
 {
@@ -137,12 +198,21 @@
 	i2c_set_clientdata(i2c, max8997);
 	max8997->dev = &i2c->dev;
 	max8997->i2c = i2c;
-	max8997->type = id->driver_data;
+	max8997->type = max8997_i2c_get_driver_data(i2c, id);
 	max8997->irq = i2c->irq;
 
+	if (max8997->dev->of_node) {
+		pdata = max8997_i2c_parse_dt_pdata(max8997->dev);
+		if (IS_ERR(pdata)) {
+			ret = PTR_ERR(pdata);
+			goto err;
+		}
+	}
+
 	if (!pdata)
 		goto err;
 
+	max8997->pdata = pdata;
 	max8997->ono = pdata->ono;
 
 	mutex_init(&max8997->iolock);
@@ -434,6 +504,7 @@
 		   .name = "max8997",
 		   .owner = THIS_MODULE,
 		   .pm = &max8997_pm,
+		   .of_match_table = of_match_ptr(max8997_pmic_dt_match),
 	},
 	.probe = max8997_i2c_probe,
 	.remove = max8997_i2c_remove,
diff --git a/drivers/mfd/tps6586x.c b/drivers/mfd/tps6586x.c
index 9f92c3b..87ba7ad 100644
--- a/drivers/mfd/tps6586x.c
+++ b/drivers/mfd/tps6586x.c
@@ -24,8 +24,6 @@
 #include <linux/err.h>
 #include <linux/i2c.h>
 #include <linux/regmap.h>
-#include <linux/regulator/of_regulator.h>
-#include <linux/regulator/machine.h>
 
 #include <linux/mfd/core.h>
 #include <linux/mfd/tps6586x.h>
@@ -99,6 +97,9 @@
 		.name = "tps6586x-gpio",
 	},
 	{
+		.name = "tps6586x-pmic",
+	},
+	{
 		.name = "tps6586x-rtc",
 	},
 	{
@@ -350,80 +351,19 @@
 }
 
 #ifdef CONFIG_OF
-static struct of_regulator_match tps6586x_matches[] = {
-	{ .name = "sys",     .driver_data = (void *)TPS6586X_ID_SYS     },
-	{ .name = "sm0",     .driver_data = (void *)TPS6586X_ID_SM_0    },
-	{ .name = "sm1",     .driver_data = (void *)TPS6586X_ID_SM_1    },
-	{ .name = "sm2",     .driver_data = (void *)TPS6586X_ID_SM_2    },
-	{ .name = "ldo0",    .driver_data = (void *)TPS6586X_ID_LDO_0   },
-	{ .name = "ldo1",    .driver_data = (void *)TPS6586X_ID_LDO_1   },
-	{ .name = "ldo2",    .driver_data = (void *)TPS6586X_ID_LDO_2   },
-	{ .name = "ldo3",    .driver_data = (void *)TPS6586X_ID_LDO_3   },
-	{ .name = "ldo4",    .driver_data = (void *)TPS6586X_ID_LDO_4   },
-	{ .name = "ldo5",    .driver_data = (void *)TPS6586X_ID_LDO_5   },
-	{ .name = "ldo6",    .driver_data = (void *)TPS6586X_ID_LDO_6   },
-	{ .name = "ldo7",    .driver_data = (void *)TPS6586X_ID_LDO_7   },
-	{ .name = "ldo8",    .driver_data = (void *)TPS6586X_ID_LDO_8   },
-	{ .name = "ldo9",    .driver_data = (void *)TPS6586X_ID_LDO_9   },
-	{ .name = "ldo_rtc", .driver_data = (void *)TPS6586X_ID_LDO_RTC },
-};
-
 static struct tps6586x_platform_data *tps6586x_parse_dt(struct i2c_client *client)
 {
-	const unsigned int num = ARRAY_SIZE(tps6586x_matches);
 	struct device_node *np = client->dev.of_node;
 	struct tps6586x_platform_data *pdata;
-	struct tps6586x_subdev_info *devs;
-	struct device_node *regs;
-	const char *sys_rail_name = NULL;
-	unsigned int count;
-	unsigned int i, j;
-	int err;
-
-	regs = of_find_node_by_name(np, "regulators");
-	if (!regs)
-		return NULL;
-
-	err = of_regulator_match(&client->dev, regs, tps6586x_matches, num);
-	if (err < 0) {
-		of_node_put(regs);
-		return NULL;
-	}
-
-	of_node_put(regs);
-	count = err;
-
-	devs = devm_kzalloc(&client->dev, count * sizeof(*devs), GFP_KERNEL);
-	if (!devs)
-		return NULL;
-
-	for (i = 0, j = 0; i < num && j < count; i++) {
-		struct regulator_init_data *reg_idata;
-
-		if (!tps6586x_matches[i].init_data)
-			continue;
-
-		reg_idata  = tps6586x_matches[i].init_data;
-		devs[j].name = "tps6586x-regulator";
-		devs[j].platform_data = tps6586x_matches[i].init_data;
-		devs[j].id = (int)tps6586x_matches[i].driver_data;
-		if (devs[j].id == TPS6586X_ID_SYS)
-			sys_rail_name = reg_idata->constraints.name;
-
-		if ((devs[j].id == TPS6586X_ID_LDO_5) ||
-			(devs[j].id == TPS6586X_ID_LDO_RTC))
-			reg_idata->supply_regulator = sys_rail_name;
-
-		devs[j].of_node = tps6586x_matches[i].of_node;
-		j++;
-	}
 
 	pdata = devm_kzalloc(&client->dev, sizeof(*pdata), GFP_KERNEL);
-	if (!pdata)
+	if (!pdata) {
+		dev_err(&client->dev, "Memory allocation failed\n");
 		return NULL;
+	}
 
-	pdata->num_subdevs = count;
-	pdata->subdevs = devs;
+	pdata->num_subdevs = 0;
+	pdata->subdevs = NULL;
 	pdata->gpio_base = -1;
 	pdata->irq_base = -1;
 	pdata->pm_off = of_property_read_bool(np, "ti,system-power-controller");
diff --git a/drivers/mfd/wm5102-tables.c b/drivers/mfd/wm5102-tables.c
index 14490cc..3141c4a 100644
--- a/drivers/mfd/wm5102-tables.c
+++ b/drivers/mfd/wm5102-tables.c
@@ -258,6 +258,7 @@
 	{ 0x00000154, 0x0000 },   /* R340   - Rate Estimator 3 */ 
 	{ 0x00000155, 0x0000 },   /* R341   - Rate Estimator 4 */ 
 	{ 0x00000156, 0x0000 },   /* R342   - Rate Estimator 5 */ 
+	{ 0x00000161, 0x0000 },   /* R353   - Dynamic Frequency Scaling 1 */ 
 	{ 0x00000171, 0x0000 },   /* R369   - FLL1 Control 1 */ 
 	{ 0x00000172, 0x0008 },   /* R370   - FLL1 Control 2 */ 
 	{ 0x00000173, 0x0018 },   /* R371   - FLL1 Control 3 */ 
@@ -1047,6 +1048,7 @@
 	case ARIZONA_RATE_ESTIMATOR_3:
 	case ARIZONA_RATE_ESTIMATOR_4:
 	case ARIZONA_RATE_ESTIMATOR_5:
+	case ARIZONA_DYNAMIC_FREQUENCY_SCALING_1:
 	case ARIZONA_FLL1_CONTROL_1:
 	case ARIZONA_FLL1_CONTROL_2:
 	case ARIZONA_FLL1_CONTROL_3:
@@ -1079,6 +1081,7 @@
 	case ARIZONA_FLL2_GPIO_CLOCK:
 	case ARIZONA_MIC_CHARGE_PUMP_1:
 	case ARIZONA_LDO1_CONTROL_1:
+	case ARIZONA_LDO1_CONTROL_2:
 	case ARIZONA_LDO2_CONTROL_1:
 	case ARIZONA_MIC_BIAS_CTRL_1:
 	case ARIZONA_MIC_BIAS_CTRL_2:
diff --git a/drivers/mfd/wm8994-core.c b/drivers/mfd/wm8994-core.c
index c7f62ac..bcb226f 100644
--- a/drivers/mfd/wm8994-core.c
+++ b/drivers/mfd/wm8994-core.c
@@ -401,13 +401,19 @@
  */
 static int wm8994_device_init(struct wm8994 *wm8994, int irq)
 {
-	struct wm8994_pdata *pdata = wm8994->dev->platform_data;
+	struct wm8994_pdata *pdata;
 	struct regmap_config *regmap_config;
 	const struct reg_default *regmap_patch = NULL;
 	const char *devname;
 	int ret, i, patch_regs;
 	int pulls = 0;
 
+	if (dev_get_platdata(wm8994->dev)) {
+		pdata = dev_get_platdata(wm8994->dev);
+		wm8994->pdata = *pdata;
+	}
+	pdata = &wm8994->pdata;
+
 	dev_set_drvdata(wm8994->dev, wm8994);
 
 	/* Add the on-chip regulators first for bootstrapping */
@@ -604,25 +610,22 @@
 		}
 	}
 
-	if (pdata) {
-		wm8994->irq_base = pdata->irq_base;
-		wm8994->gpio_base = pdata->gpio_base;
+	wm8994->irq_base = pdata->irq_base;
+	wm8994->gpio_base = pdata->gpio_base;
 
-		/* GPIO configuration is only applied if it's non-zero */
-		for (i = 0; i < ARRAY_SIZE(pdata->gpio_defaults); i++) {
-			if (pdata->gpio_defaults[i]) {
-				wm8994_set_bits(wm8994, WM8994_GPIO_1 + i,
-						0xffff,
-						pdata->gpio_defaults[i]);
-			}
+	/* GPIO configuration is only applied if it's non-zero */
+	for (i = 0; i < ARRAY_SIZE(pdata->gpio_defaults); i++) {
+		if (pdata->gpio_defaults[i]) {
+			wm8994_set_bits(wm8994, WM8994_GPIO_1 + i,
+					0xffff, pdata->gpio_defaults[i]);
 		}
-
-		wm8994->ldo_ena_always_driven = pdata->ldo_ena_always_driven;
-
-		if (pdata->spkmode_pu)
-			pulls |= WM8994_SPKMODE_PU;
 	}
 
+	wm8994->ldo_ena_always_driven = pdata->ldo_ena_always_driven;
+
+	if (pdata->spkmode_pu)
+		pulls |= WM8994_SPKMODE_PU;
+
 	/* Disable unneeded pulls */
 	wm8994_set_bits(wm8994, WM8994_PULL_CONTROL_2,
 			WM8994_LDO1ENA_PD | WM8994_LDO2ENA_PD |
diff --git a/drivers/misc/atmel-ssc.c b/drivers/misc/atmel-ssc.c
index c58f9ab..158da5a 100644
--- a/drivers/misc/atmel-ssc.c
+++ b/drivers/misc/atmel-ssc.c
@@ -18,6 +18,8 @@
 #include <linux/slab.h>
 #include <linux/module.h>
 
+#include <linux/of.h>
+
 /* Serialize access to ssc_list and user count */
 static DEFINE_SPINLOCK(user_lock);
 static LIST_HEAD(ssc_list);
@@ -29,7 +31,13 @@
 
 	spin_lock(&user_lock);
 	list_for_each_entry(ssc, &ssc_list, list) {
-		if (ssc->pdev->id == ssc_num) {
+		if (ssc->pdev->dev.of_node) {
+			if (of_alias_get_id(ssc->pdev->dev.of_node, "ssc")
+				== ssc_num) {
+				ssc_valid = 1;
+				break;
+			}
+		} else if (ssc->pdev->id == ssc_num) {
 			ssc_valid = 1;
 			break;
 		}
@@ -68,39 +76,93 @@
 }
 EXPORT_SYMBOL(ssc_free);
 
-static int __init ssc_probe(struct platform_device *pdev)
+static struct atmel_ssc_platform_data at91rm9200_config = {
+	.use_dma = 0,
+};
+
+static struct atmel_ssc_platform_data at91sam9g45_config = {
+	.use_dma = 1,
+};
+
+static const struct platform_device_id atmel_ssc_devtypes[] = {
+	{
+		.name = "at91rm9200_ssc",
+		.driver_data = (unsigned long) &at91rm9200_config,
+	}, {
+		.name = "at91sam9g45_ssc",
+		.driver_data = (unsigned long) &at91sam9g45_config,
+	}, {
+		/* sentinel */
+	}
+};
+
+#ifdef CONFIG_OF
+static const struct of_device_id atmel_ssc_dt_ids[] = {
+	{
+		.compatible = "atmel,at91rm9200-ssc",
+		.data = &at91rm9200_config,
+	}, {
+		.compatible = "atmel,at91sam9g45-ssc",
+		.data = &at91sam9g45_config,
+	}, {
+		/* sentinel */
+	}
+};
+MODULE_DEVICE_TABLE(of, atmel_ssc_dt_ids);
+#endif
+
+static inline const struct atmel_ssc_platform_data * __init
+	atmel_ssc_get_driver_data(struct platform_device *pdev)
 {
-	int retval = 0;
+	if (pdev->dev.of_node) {
+		const struct of_device_id *match;
+		match = of_match_node(atmel_ssc_dt_ids, pdev->dev.of_node);
+		if (match == NULL)
+			return NULL;
+		return match->data;
+	}
+
+	return (struct atmel_ssc_platform_data *)
+		platform_get_device_id(pdev)->driver_data;
+}
+
+static int ssc_probe(struct platform_device *pdev)
+{
 	struct resource *regs;
 	struct ssc_device *ssc;
+	const struct atmel_ssc_platform_data *plat_dat;
 
-	ssc = kzalloc(sizeof(struct ssc_device), GFP_KERNEL);
+	ssc = devm_kzalloc(&pdev->dev, sizeof(struct ssc_device), GFP_KERNEL);
 	if (!ssc) {
 		dev_dbg(&pdev->dev, "out of memory\n");
-		retval = -ENOMEM;
-		goto out;
+		return -ENOMEM;
 	}
 
+	ssc->pdev = pdev;
+
+	plat_dat = atmel_ssc_get_driver_data(pdev);
+	if (!plat_dat)
+		return -ENODEV;
+	ssc->pdata = (struct atmel_ssc_platform_data *)plat_dat;
+
 	regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (!regs) {
 		dev_dbg(&pdev->dev, "no mmio resource defined\n");
-		retval = -ENXIO;
-		goto out_free;
+		return -ENXIO;
 	}
 
-	ssc->clk = clk_get(&pdev->dev, "pclk");
-	if (IS_ERR(ssc->clk)) {
-		dev_dbg(&pdev->dev, "no pclk clock defined\n");
-		retval = -ENXIO;
-		goto out_free;
-	}
-
-	ssc->pdev = pdev;
-	ssc->regs = ioremap(regs->start, resource_size(regs));
+	ssc->regs = devm_request_and_ioremap(&pdev->dev, regs);
 	if (!ssc->regs) {
 		dev_dbg(&pdev->dev, "ioremap failed\n");
-		retval = -EINVAL;
-		goto out_clk;
+		return -EINVAL;
+	}
+
+	ssc->phybase = regs->start;
+
+	ssc->clk = devm_clk_get(&pdev->dev, "pclk");
+	if (IS_ERR(ssc->clk)) {
+		dev_dbg(&pdev->dev, "no pclk clock defined\n");
+		return -ENXIO;
 	}
 
 	/* disable all interrupts */
@@ -112,8 +174,7 @@
 	ssc->irq = platform_get_irq(pdev, 0);
 	if (!ssc->irq) {
 		dev_dbg(&pdev->dev, "could not get irq\n");
-		retval = -ENXIO;
-		goto out_unmap;
+		return -ENXIO;
 	}
 
 	spin_lock(&user_lock);
@@ -125,16 +186,7 @@
 	dev_info(&pdev->dev, "Atmel SSC device at 0x%p (irq %d)\n",
 			ssc->regs, ssc->irq);
 
-	goto out;
-
-out_unmap:
-	iounmap(ssc->regs);
-out_clk:
-	clk_put(ssc->clk);
-out_free:
-	kfree(ssc);
-out:
-	return retval;
+	return 0;
 }
 
 static int ssc_remove(struct platform_device *pdev)
@@ -142,34 +194,23 @@
 	struct ssc_device *ssc = platform_get_drvdata(pdev);
 
 	spin_lock(&user_lock);
-	iounmap(ssc->regs);
-	clk_put(ssc->clk);
 	list_del(&ssc->list);
-	kfree(ssc);
 	spin_unlock(&user_lock);
 
 	return 0;
 }
 
 static struct platform_driver ssc_driver = {
-	.remove		= ssc_remove,
 	.driver		= {
 		.name		= "ssc",
 		.owner		= THIS_MODULE,
+		.of_match_table	= of_match_ptr(atmel_ssc_dt_ids),
 	},
+	.id_table	= atmel_ssc_devtypes,
+	.probe		= ssc_probe,
+	.remove		= ssc_remove,
 };
-
-static int __init ssc_init(void)
-{
-	return platform_driver_probe(&ssc_driver, ssc_probe);
-}
-module_init(ssc_init);
-
-static void __exit ssc_exit(void)
-{
-	platform_driver_unregister(&ssc_driver);
-}
-module_exit(ssc_exit);
+module_platform_driver(ssc_driver);
 
 MODULE_AUTHOR("Hans-Christian Egtvedt <hcegtvedt@atmel.com>");
 MODULE_DESCRIPTION("SSC driver for Atmel AVR32 and AT91");
diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
index 737e4ed..8d13c65 100644
--- a/drivers/mmc/host/Kconfig
+++ b/drivers/mmc/host/Kconfig
@@ -533,7 +533,7 @@
 	  If unsure, say Y.
 
 config MMC_DW_EXYNOS
-	tristate "Exynos specific extentions for Synopsys DW Memory Card Interface"
+	tristate "Exynos specific extensions for Synopsys DW Memory Card Interface"
 	depends on MMC_DW
 	select MMC_DW_PLTFM
 	help
diff --git a/drivers/mtd/maps/plat-ram.c b/drivers/mtd/maps/plat-ram.c
index 891558d..2de66b0 100644
--- a/drivers/mtd/maps/plat-ram.c
+++ b/drivers/mtd/maps/plat-ram.c
@@ -219,7 +219,7 @@
 
 	platram_setrw(info, PLATRAM_RW);
 
-	/* check to see if there are any available partitions, or wether
+	/* check to see if there are any available partitions, or whether
 	 * to add this device whole */
 
 	err = mtd_device_parse_register(info->mtd, pdata->probes, NULL,
diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
index 531807d..dae191b 100644
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -546,7 +546,7 @@
 
 config MTD_NAND_FSMC
 	tristate "Support for NAND on ST Micros FSMC"
-	depends on PLAT_SPEAR || PLAT_NOMADIK || MACH_U300
+	depends on PLAT_SPEAR || ARCH_NOMADIK || ARCH_U8500 || MACH_U300
 	help
 	  Enables support for NAND Flash chips on the ST Microelectronics
 	  Flexible Static Memory Controller (FSMC)
diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index 5c8978e..1f34ba1 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -27,7 +27,6 @@
 #include <linux/bch.h>
 #endif
 
-#include <plat-omap/dma-omap.h>
 #include <linux/platform_data/mtd-nand-omap2.h>
 
 #define	DRIVER_NAME	"omap2-nand"
diff --git a/drivers/mtd/nand/s3c2410.c b/drivers/mtd/nand/s3c2410.c
index 295e4be..79ded48 100644
--- a/drivers/mtd/nand/s3c2410.c
+++ b/drivers/mtd/nand/s3c2410.c
@@ -879,7 +879,7 @@
 	if (chip->ecc.mode != NAND_ECC_HW)
 		return;
 
-		/* change the behaviour depending on wether we are using
+		/* change the behaviour depending on whether we are using
 		 * the large or small page nand device */
 
 	if (chip->page_shift > 10) {
diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c
index 99f96e1..00cd3da 100644
--- a/drivers/mtd/onenand/omap2.c
+++ b/drivers/mtd/onenand/omap2.c
@@ -41,7 +41,7 @@
 #include <linux/platform_data/mtd-onenand-omap2.h>
 #include <asm/gpio.h>
 
-#include <plat-omap/dma-omap.h>
+#include <linux/omap-dma.h>
 
 #define DRIVER_NAME "omap2-onenand"
 
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
index 6dded56..21b68e5 100644
--- a/drivers/net/bonding/bonding.h
+++ b/drivers/net/bonding/bonding.h
@@ -245,7 +245,7 @@
 	struct   delayed_work ad_work;
 	struct   delayed_work mcast_work;
 #ifdef CONFIG_DEBUG_FS
-	/* debugging suport via debugfs */
+	/* debugging support via debugfs */
 	struct	 dentry *debug_dir;
 #endif /* CONFIG_DEBUG_FS */
 };
diff --git a/drivers/net/ethernet/8390/ax88796.c b/drivers/net/ethernet/8390/ax88796.c
index 0338352..70dba5d 100644
--- a/drivers/net/ethernet/8390/ax88796.c
+++ b/drivers/net/ethernet/8390/ax88796.c
@@ -109,7 +109,7 @@
 /*
  * ax_initial_check
  *
- * do an initial probe for the card to check wether it exists
+ * do an initial probe for the card to check whether it exists
  * and is functional
  */
 static int ax_initial_check(struct net_device *dev)
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c
index b8b4b74..09b625e 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c
@@ -4318,7 +4318,7 @@
 
 	if (o->next_tx_only >= o->max_cos)
 		/* >= becuase tx only must always be smaller than cos since the
-		 * primary connection suports COS 0
+		 * primary connection supports COS 0
 		 */
 		BNX2X_ERR("illegal value for next tx_only: %d. max cos was %d",
 			   o->next_tx_only, o->max_cos);
diff --git a/drivers/net/ethernet/chelsio/cxgb3/t3_hw.c b/drivers/net/ethernet/chelsio/cxgb3/t3_hw.c
index aef45d3..3dee686 100644
--- a/drivers/net/ethernet/chelsio/cxgb3/t3_hw.c
+++ b/drivers/net/ethernet/chelsio/cxgb3/t3_hw.c
@@ -3307,7 +3307,7 @@
 	    G_NUMFSTTRNSEQRX(t3_read_reg(adap, A_PCIE_MODE));
 	log2_width = fls(adap->params.pci.width) - 1;
 	acklat = ack_lat[log2_width][pldsize];
-	if (val & 1)		/* check LOsEnable */
+	if (val & PCI_EXP_LNKCTL_ASPM_L0S)	/* check LOsEnable */
 		acklat += fst_trn_tx * 4;
 	rpllmt = rpl_tmr[log2_width][pldsize] + fst_trn_rx * 4;
 
diff --git a/drivers/net/ethernet/intel/e1000/e1000_ethtool.c b/drivers/net/ethernet/intel/e1000/e1000_ethtool.c
index 9089d00..14e3051 100644
--- a/drivers/net/ethernet/intel/e1000/e1000_ethtool.c
+++ b/drivers/net/ethernet/intel/e1000/e1000_ethtool.c
@@ -1671,7 +1671,7 @@
 	/* apply any specific unsupported masks here */
 	switch (hw->device_id) {
 	case E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3:
-		/* KSP3 does not suppport UCAST wake-ups */
+		/* KSP3 does not support UCAST wake-ups */
 		wol->supported &= ~WAKE_UCAST;
 
 		if (adapter->wol & E1000_WUFC_EX)
diff --git a/drivers/net/ethernet/mellanox/mlx4/eq.c b/drivers/net/ethernet/mellanox/mlx4/eq.c
index b84a88b..c48cf6f 100644
--- a/drivers/net/ethernet/mellanox/mlx4/eq.c
+++ b/drivers/net/ethernet/mellanox/mlx4/eq.c
@@ -1267,7 +1267,7 @@
 		/* Temporary use polling for command completions */
 		mlx4_cmd_use_polling(dev);
 
-		/* Map the new eq to handle all asyncronous events */
+		/* Map the new eq to handle all asynchronous events */
 		err = mlx4_MAP_EQ(dev, get_async_ev_mask(dev), 0,
 				  priv->eq_table.eq[i].eqn);
 		if (err) {
diff --git a/drivers/net/ethernet/micrel/ksz884x.c b/drivers/net/ethernet/micrel/ksz884x.c
index 093d594..83f0ea9 100644
--- a/drivers/net/ethernet/micrel/ksz884x.c
+++ b/drivers/net/ethernet/micrel/ksz884x.c
@@ -6769,7 +6769,7 @@
 /*
  * This enables fast aging in the KSZ8842 switch.  Not sure what situation
  * needs that.  However, fast aging is used to flush the dynamic MAC table when
- * STP suport is enabled.
+ * STP support is enabled.
  */
 static int fast_aging;
 
diff --git a/drivers/net/ethernet/myricom/myri10ge/myri10ge_mcp_gen_header.h b/drivers/net/ethernet/myricom/myri10ge/myri10ge_mcp_gen_header.h
index 7ec4b86..75ec5e7 100644
--- a/drivers/net/ethernet/myricom/myri10ge/myri10ge_mcp_gen_header.h
+++ b/drivers/net/ethernet/myricom/myri10ge/myri10ge_mcp_gen_header.h
@@ -27,7 +27,7 @@
 	 *
 	 * Fields below this comment are extensions added in later versions
 	 * of this struct, drivers should compare the header_length against
-	 * offsetof(field) to check wether a given MCP implements them.
+	 * offsetof(field) to check whether a given MCP implements them.
 	 *
 	 * Never remove any field.  Keep everything naturally align.
 	 */
diff --git a/drivers/net/sungem_phy.c b/drivers/net/sungem_phy.c
index 58f13ad..ae7cd7f 100644
--- a/drivers/net/sungem_phy.c
+++ b/drivers/net/sungem_phy.c
@@ -608,7 +608,7 @@
 	if ( mode == BCM54XX_COPPER)
 		return genmii_poll_link(phy);
 
-	/* try to find out wether we have a link */
+	/* try to find out whether we have a link */
 	phy_write(phy, MII_NCONFIG, 0x2000);
 	phy_reg = phy_read(phy, MII_NCONFIG);
 
@@ -634,7 +634,7 @@
 
 	phy->speed = SPEED_1000;
 
-	/* find out wether we are running half- or full duplex */
+	/* find out whether we are running half- or full duplex */
 	phy_write(phy, MII_NCONFIG, 0x2000);
 	phy_reg = phy_read(phy, MII_NCONFIG);
 
@@ -681,7 +681,7 @@
 	if ( mode == BCM54XX_COPPER)
 		return genmii_poll_link(phy);
 
-	/* find out wether we have a link */
+	/* find out whether we have a link */
 	phy_write(phy, MII_NCONFIG, 0x7000);
 	phy_reg = phy_read(phy, MII_NCONFIG);
 
@@ -710,7 +710,7 @@
 
 	phy->speed = SPEED_1000;
 
-	/* find out wether we are running half- or full duplex */
+	/* find out whether we are running half- or full duplex */
 	phy_write(phy, MII_NCONFIG, 0x7000);
 	phy_reg = phy_read(phy, MII_NCONFIG);
 
diff --git a/drivers/net/wimax/i2400m/debugfs.c b/drivers/net/wimax/i2400m/debugfs.c
index 4b66ab1..6702da8 100644
--- a/drivers/net/wimax/i2400m/debugfs.c
+++ b/drivers/net/wimax/i2400m/debugfs.c
@@ -209,6 +209,7 @@
 		result = i2400m_reset(i2400m, rt);
 		if (result >= 0)
 			result = 0;
+		break;
 	default:
 		result = -EINVAL;
 	}
diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c
index 8e9b826..7ae73fb 100644
--- a/drivers/net/wireless/ath/ath9k/pci.c
+++ b/drivers/net/wireless/ath/ath9k/pci.c
@@ -114,23 +114,23 @@
 
 	if ((ath9k_hw_get_btcoex_scheme(ah) != ATH_BTCOEX_CFG_NONE) &&
 	    (AR_SREV_9285(ah))) {
-		/* Bluetooth coexistance requires disabling ASPM. */
+		/* Bluetooth coexistence requires disabling ASPM. */
 		pcie_capability_clear_word(pdev, PCI_EXP_LNKCTL,
-			PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1);
+			PCI_EXP_LNKCTL_ASPM_L0S | PCI_EXP_LNKCTL_ASPM_L1);
 
 		/*
 		 * Both upstream and downstream PCIe components should
 		 * have the same ASPM settings.
 		 */
 		pcie_capability_clear_word(parent, PCI_EXP_LNKCTL,
-			PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1);
+			PCI_EXP_LNKCTL_ASPM_L0S | PCI_EXP_LNKCTL_ASPM_L1);
 
 		ath_info(common, "Disabling ASPM since BTCOEX is enabled\n");
 		return;
 	}
 
 	pcie_capability_read_word(parent, PCI_EXP_LNKCTL, &aspm);
-	if (aspm & (PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1)) {
+	if (aspm & (PCI_EXP_LNKCTL_ASPM_L0S | PCI_EXP_LNKCTL_ASPM_L1)) {
 		ah->aspm_enabled = true;
 		/* Initialize PCIe PM and SERDES registers. */
 		ath9k_hw_configpcipowersave(ah, false);
diff --git a/drivers/net/wireless/atmel.c b/drivers/net/wireless/atmel.c
index 4a4e98f..4374079 100644
--- a/drivers/net/wireless/atmel.c
+++ b/drivers/net/wireless/atmel.c
@@ -2963,7 +2963,7 @@
 	ssid_el_p[1] = priv->SSID_size;
 	memcpy(ssid_el_p + 2, priv->SSID, priv->SSID_size);
 	ssid_el_p[2 + priv->SSID_size] = WLAN_EID_SUPP_RATES;
-	ssid_el_p[3 + priv->SSID_size] = 4; /* len of suported rates */
+	ssid_el_p[3 + priv->SSID_size] = 4; /* len of supported rates */
 	memcpy(ssid_el_p + 4 + priv->SSID_size, atmel_basic_rates, 4);
 
 	atmel_transmit_management_frame(priv, &header, (void *)&body, bodysize);
diff --git a/drivers/net/wireless/ipw2x00/ipw2100.h b/drivers/net/wireless/ipw2x00/ipw2100.h
index 9731252..5fe17cb 100644
--- a/drivers/net/wireless/ipw2x00/ipw2100.h
+++ b/drivers/net/wireless/ipw2x00/ipw2100.h
@@ -1045,7 +1045,7 @@
 	IPW_ORD_POWER_MGMT_MODE,	// Power mode - 0=CAM, 1=PSP
 	IPW_ORD_POWER_MGMT_INDEX,	//NS //
 	IPW_ORD_COUNTRY_CODE,	// IEEE country code as recv'd from beacon
-	IPW_ORD_COUNTRY_CHANNELS,	// channels suported by country
+	IPW_ORD_COUNTRY_CHANNELS,	// channels supported by country
 // IPW_ORD_COUNTRY_CHANNELS:
 // For 11b the lower 2-byte are used for channels from 1-14
 //   and the higher 2-byte are not used.
diff --git a/drivers/net/wireless/iwlegacy/4965.h b/drivers/net/wireless/iwlegacy/4965.h
index 2d092f3..1b15b0b 100644
--- a/drivers/net/wireless/iwlegacy/4965.h
+++ b/drivers/net/wireless/iwlegacy/4965.h
@@ -917,10 +917,6 @@
 /* PCI registers */
 #define PCI_CFG_RETRY_TIMEOUT	0x041
 
-/* PCI register values */
-#define PCI_CFG_LINK_CTRL_VAL_L0S_EN	0x01
-#define PCI_CFG_LINK_CTRL_VAL_L1_EN	0x02
-
 #define IL4965_DEFAULT_TX_RETRY  15
 
 /* EEPROM */
diff --git a/drivers/net/wireless/iwlegacy/common.c b/drivers/net/wireless/iwlegacy/common.c
index 318ed3c..7e16d10 100644
--- a/drivers/net/wireless/iwlegacy/common.c
+++ b/drivers/net/wireless/iwlegacy/common.c
@@ -1183,9 +1183,10 @@
 void
 il_power_initialize(struct il_priv *il)
 {
-	u16 lctl = il_pcie_link_ctl(il);
+	u16 lctl;
 
-	il->power_data.pci_pm = !(lctl & PCI_CFG_LINK_CTRL_VAL_L0S_EN);
+	pcie_capability_read_word(il->pci_dev, PCI_EXP_LNKCTL, &lctl);
+	il->power_data.pci_pm = !(lctl & PCI_EXP_LNKCTL_ASPM_L0S);
 
 	il->power_data.debug_sleep_level_override = -1;
 
@@ -4233,9 +4234,8 @@
 	 *    power savings, even without L1.
 	 */
 	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) {
+		pcie_capability_read_word(il->pci_dev, PCI_EXP_LNKCTL, &lctl);
+		if (lctl & PCI_EXP_LNKCTL_ASPM_L1) {
 			/* L1-ASPM enabled; disable(!) L0S  */
 			il_set_bit(il, CSR_GIO_REG,
 				   CSR_GIO_REG_VAL_L0S_ENABLED);
diff --git a/drivers/net/wireless/iwlegacy/common.h b/drivers/net/wireless/iwlegacy/common.h
index e254cba..a9a569f 100644
--- a/drivers/net/wireless/iwlegacy/common.h
+++ b/drivers/net/wireless/iwlegacy/common.h
@@ -1829,14 +1829,6 @@
  * PCI						     *
  *****************************************************/
 
-static inline u16
-il_pcie_link_ctl(struct il_priv *il)
-{
-	u16 pci_lnk_ctl;
-	pcie_capability_read_word(il->pci_dev, PCI_EXP_LNKCTL, &pci_lnk_ctl);
-	return pci_lnk_ctl;
-}
-
 void il_bg_watchdog(unsigned long data);
 u32 il_usecs_to_beacons(struct il_priv *il, u32 usec, u32 beacon_interval);
 __le32 il_add_beacon_time(struct il_priv *il, u32 base, u32 addon,
@@ -2434,10 +2426,6 @@
 /* PCI registers */
 #define PCI_CFG_RETRY_TIMEOUT	0x041
 
-/* PCI register values */
-#define PCI_CFG_LINK_CTRL_VAL_L0S_EN	0x01
-#define PCI_CFG_LINK_CTRL_VAL_L1_EN	0x02
-
 struct il_rate_info {
 	u8 plcp;		/* uCode API:  RATE_6M_PLCP, etc. */
 	u8 plcp_siso;		/* uCode API:  RATE_SISO_6M_PLCP, etc. */
diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c
index d66cad4..35708b9 100644
--- a/drivers/net/wireless/iwlwifi/pcie/trans.c
+++ b/drivers/net/wireless/iwlwifi/pcie/trans.c
@@ -94,8 +94,6 @@
 
 /* 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 void iwl_pcie_apm_config(struct iwl_trans *trans)
 {
@@ -111,9 +109,7 @@
 	 *    power savings, even without L1.
 	 */
 	pcie_capability_read_word(trans_pcie->pci_dev, PCI_EXP_LNKCTL, &lctl);
-
-	if ((lctl & PCI_CFG_LINK_CTRL_VAL_L1_EN) ==
-				PCI_CFG_LINK_CTRL_VAL_L1_EN) {
+	if (lctl & PCI_EXP_LNKCTL_ASPM_L1) {
 		/* L1-ASPM enabled; disable(!) L0S */
 		iwl_set_bit(trans, CSR_GIO_REG, CSR_GIO_REG_VAL_L0S_ENABLED);
 		dev_info(trans->dev, "L1 Enabled; Disabling L0S\n");
@@ -122,7 +118,7 @@
 		iwl_clear_bit(trans, CSR_GIO_REG, CSR_GIO_REG_VAL_L0S_ENABLED);
 		dev_info(trans->dev, "L1 Disabled; Enabling L0S\n");
 	}
-	trans->pm_support = !(lctl & PCI_CFG_LINK_CTRL_VAL_L0S_EN);
+	trans->pm_support = !(lctl & PCI_EXP_LNKCTL_ASPM_L0S);
 }
 
 /*
diff --git a/drivers/net/wireless/zd1211rw/zd_chip.c b/drivers/net/wireless/zd1211rw/zd_chip.c
index ff306d7..71ab320 100644
--- a/drivers/net/wireless/zd1211rw/zd_chip.c
+++ b/drivers/net/wireless/zd1211rw/zd_chip.c
@@ -1155,7 +1155,7 @@
 	if (r)
 		goto out;
 	/* Currently we support IEEE 802.11g for full and high speed USB.
-	 * It might be discussed, whether we should suppport pure b mode for
+	 * It might be discussed, whether we should support pure b mode for
 	 * full speed USB.
 	 */
 	r = set_mandatory_rates(chip, 1);
diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c
index a543746..ad6a8b6 100644
--- a/drivers/pci/bus.c
+++ b/drivers/pci/bus.c
@@ -170,6 +170,11 @@
 	int retval;
 
 	pci_fixup_device(pci_fixup_final, dev);
+
+	retval = pcibios_add_device(dev);
+	if (retval)
+		return retval;
+
 	retval = device_add(&dev->dev);
 	if (retval)
 		return retval;
diff --git a/drivers/pci/ioapic.c b/drivers/pci/ioapic.c
index 2eca902..3c6bbdd 100644
--- a/drivers/pci/ioapic.c
+++ b/drivers/pci/ioapic.c
@@ -125,3 +125,5 @@
 
 module_init(ioapic_init);
 module_exit(ioapic_exit);
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c
index aeccc91..bafd2bb 100644
--- a/drivers/pci/iov.c
+++ b/drivers/pci/iov.c
@@ -106,7 +106,7 @@
 		virtfn->resource[i].name = pci_name(virtfn);
 		virtfn->resource[i].flags = res->flags;
 		size = resource_size(res);
-		do_div(size, iov->total);
+		do_div(size, iov->total_VFs);
 		virtfn->resource[i].start = res->start + size * id;
 		virtfn->resource[i].end = virtfn->resource[i].start + size - 1;
 		rc = request_resource(res, &virtfn->resource[i]);
@@ -194,7 +194,7 @@
 	u16 status;
 	struct pci_sriov *iov = dev->sriov;
 
-	if (!iov->nr_virtfn)
+	if (!iov->num_VFs)
 		return 0;
 
 	if (!(iov->cap & PCI_SRIOV_CAP_VFM))
@@ -216,7 +216,7 @@
 	u16 status;
 	struct pci_sriov *iov = container_of(work, struct pci_sriov, mtask);
 
-	for (i = iov->initial; i < iov->nr_virtfn; i++) {
+	for (i = iov->initial_VFs; i < iov->num_VFs; i++) {
 		state = readb(iov->mstate + i);
 		if (state == PCI_SRIOV_VFM_MI) {
 			writeb(PCI_SRIOV_VFM_AV, iov->mstate + i);
@@ -244,7 +244,7 @@
 	resource_size_t pa;
 	struct pci_sriov *iov = dev->sriov;
 
-	if (nr_virtfn <= iov->initial)
+	if (nr_virtfn <= iov->initial_VFs)
 		return 0;
 
 	pci_read_config_dword(dev, iov->pos + PCI_SRIOV_VFM, &table);
@@ -294,15 +294,15 @@
 	if (!nr_virtfn)
 		return 0;
 
-	if (iov->nr_virtfn)
+	if (iov->num_VFs)
 		return -EINVAL;
 
 	pci_read_config_word(dev, iov->pos + PCI_SRIOV_INITIAL_VF, &initial);
-	if (initial > iov->total ||
-	    (!(iov->cap & PCI_SRIOV_CAP_VFM) && (initial != iov->total)))
+	if (initial > iov->total_VFs ||
+	    (!(iov->cap & PCI_SRIOV_CAP_VFM) && (initial != iov->total_VFs)))
 		return -EIO;
 
-	if (nr_virtfn < 0 || nr_virtfn > iov->total ||
+	if (nr_virtfn < 0 || nr_virtfn > iov->total_VFs ||
 	    (!(iov->cap & PCI_SRIOV_CAP_VFM) && (nr_virtfn > initial)))
 		return -EINVAL;
 
@@ -359,7 +359,7 @@
 	msleep(100);
 	pci_cfg_access_unlock(dev);
 
-	iov->initial = initial;
+	iov->initial_VFs = initial;
 	if (nr_virtfn < initial)
 		initial = nr_virtfn;
 
@@ -376,7 +376,7 @@
 	}
 
 	kobject_uevent(&dev->dev.kobj, KOBJ_CHANGE);
-	iov->nr_virtfn = nr_virtfn;
+	iov->num_VFs = nr_virtfn;
 
 	return 0;
 
@@ -401,13 +401,13 @@
 	int i;
 	struct pci_sriov *iov = dev->sriov;
 
-	if (!iov->nr_virtfn)
+	if (!iov->num_VFs)
 		return;
 
 	if (iov->cap & PCI_SRIOV_CAP_VFM)
 		sriov_disable_migration(dev);
 
-	for (i = 0; i < iov->nr_virtfn; i++)
+	for (i = 0; i < iov->num_VFs; i++)
 		virtfn_remove(dev, i, 0);
 
 	iov->ctrl &= ~(PCI_SRIOV_CTRL_VFE | PCI_SRIOV_CTRL_MSE);
@@ -419,7 +419,7 @@
 	if (iov->link != dev->devfn)
 		sysfs_remove_link(&dev->dev.kobj, "dep_link");
 
-	iov->nr_virtfn = 0;
+	iov->num_VFs = 0;
 }
 
 static int sriov_init(struct pci_dev *dev, int pos)
@@ -496,7 +496,7 @@
 	iov->pos = pos;
 	iov->nres = nres;
 	iov->ctrl = ctrl;
-	iov->total = total;
+	iov->total_VFs = total;
 	iov->offset = offset;
 	iov->stride = stride;
 	iov->pgsz = pgsz;
@@ -529,7 +529,7 @@
 
 static void sriov_release(struct pci_dev *dev)
 {
-	BUG_ON(dev->sriov->nr_virtfn);
+	BUG_ON(dev->sriov->num_VFs);
 
 	if (dev != dev->sriov->dev)
 		pci_dev_put(dev->sriov->dev);
@@ -554,7 +554,7 @@
 		pci_update_resource(dev, i);
 
 	pci_write_config_dword(dev, iov->pos + PCI_SRIOV_SYS_PGSIZE, iov->pgsz);
-	pci_write_config_word(dev, iov->pos + PCI_SRIOV_NUM_VF, iov->nr_virtfn);
+	pci_write_config_word(dev, iov->pos + PCI_SRIOV_NUM_VF, iov->num_VFs);
 	pci_write_config_word(dev, iov->pos + PCI_SRIOV_CTRL, iov->ctrl);
 	if (iov->ctrl & PCI_SRIOV_CTRL_VFE)
 		msleep(100);
@@ -661,7 +661,7 @@
 	list_for_each_entry(dev, &bus->devices, bus_list) {
 		if (!dev->is_physfn)
 			continue;
-		busnr = virtfn_bus(dev, dev->sriov->total - 1);
+		busnr = virtfn_bus(dev, dev->sriov->total_VFs - 1);
 		if (busnr > max)
 			max = busnr;
 	}
@@ -729,9 +729,56 @@
  */
 int pci_num_vf(struct pci_dev *dev)
 {
-	if (!dev || !dev->is_physfn)
+	if (!dev->is_physfn)
 		return 0;
-	else
-		return dev->sriov->nr_virtfn;
+
+	return dev->sriov->num_VFs;
 }
 EXPORT_SYMBOL_GPL(pci_num_vf);
+
+/**
+ * pci_sriov_set_totalvfs -- reduce the TotalVFs available
+ * @dev: the PCI PF device
+ * numvfs: number that should be used for TotalVFs supported
+ *
+ * Should be called from PF driver's probe routine with
+ * device's mutex held.
+ *
+ * Returns 0 if PF is an SRIOV-capable device and
+ * value of numvfs valid. If not a PF with VFS, return -EINVAL;
+ * if VFs already enabled, return -EBUSY.
+ */
+int pci_sriov_set_totalvfs(struct pci_dev *dev, u16 numvfs)
+{
+	if (!dev->is_physfn || (numvfs > dev->sriov->total_VFs))
+		return -EINVAL;
+
+	/* Shouldn't change if VFs already enabled */
+	if (dev->sriov->ctrl & PCI_SRIOV_CTRL_VFE)
+		return -EBUSY;
+	else
+		dev->sriov->driver_max_VFs = numvfs;
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(pci_sriov_set_totalvfs);
+
+/**
+ * pci_sriov_get_totalvfs -- get total VFs supported on this devic3
+ * @dev: the PCI PF device
+ *
+ * For a PCIe device with SRIOV support, return the PCIe
+ * SRIOV capability value of TotalVFs or the value of driver_max_VFs
+ * if the driver reduced it.  Otherwise, -EINVAL.
+ */
+int pci_sriov_get_totalvfs(struct pci_dev *dev)
+{
+	if (!dev->is_physfn)
+		return -EINVAL;
+
+	if (dev->sriov->driver_max_VFs)
+		return dev->sriov->driver_max_VFs;
+
+	return dev->sriov->total_VFs;
+}
+EXPORT_SYMBOL_GPL(pci_sriov_get_totalvfs);
diff --git a/drivers/pci/irq.c b/drivers/pci/irq.c
index e5f69a4..b008cf8 100644
--- a/drivers/pci/irq.c
+++ b/drivers/pci/irq.c
@@ -14,11 +14,11 @@
 {
 	struct pci_dev *parent = to_pci_dev(pdev->dev.parent);
 
-	dev_printk(KERN_ERR, &pdev->dev,
-		   "Potentially misrouted IRQ (Bridge %s %04x:%04x)\n",
-		   dev_name(&parent->dev), parent->vendor, parent->device);
-	dev_printk(KERN_ERR, &pdev->dev, "%s\n", reason);
-	dev_printk(KERN_ERR, &pdev->dev, "Please report to linux-kernel@vger.kernel.org\n");
+	dev_err(&pdev->dev,
+		"Potentially misrouted IRQ (Bridge %s %04x:%04x)\n",
+		dev_name(&parent->dev), parent->vendor, parent->device);
+	dev_err(&pdev->dev, "%s\n", reason);
+	dev_err(&pdev->dev, "Please report to linux-kernel@vger.kernel.org\n");
 	WARN_ON(1);
 }
 
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index 1dc78c5..f79cbcd 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -248,31 +248,26 @@
 static long local_pci_probe(void *_ddi)
 {
 	struct drv_dev_and_id *ddi = _ddi;
-	struct device *dev = &ddi->dev->dev;
-	struct device *parent = dev->parent;
+	struct pci_dev *pci_dev = ddi->dev;
+	struct pci_driver *pci_drv = ddi->drv;
+	struct device *dev = &pci_dev->dev;
 	int rc;
 
-	/* The parent bridge must be in active state when probing */
-	if (parent)
-		pm_runtime_get_sync(parent);
-	/* Unbound PCI devices are always set to disabled and suspended.
-	 * During probe, the device is set to enabled and active and the
-	 * usage count is incremented.  If the driver supports runtime PM,
-	 * it should call pm_runtime_put_noidle() in its probe routine and
-	 * pm_runtime_get_noresume() in its remove routine.
+	/*
+	 * Unbound PCI devices are always put in D0, regardless of
+	 * runtime PM status.  During probe, the device is set to
+	 * active and the usage count is incremented.  If the driver
+	 * supports runtime PM, it should call pm_runtime_put_noidle()
+	 * in its probe routine and pm_runtime_get_noresume() in its
+	 * remove routine.
 	 */
-	pm_runtime_get_noresume(dev);
-	pm_runtime_set_active(dev);
-	pm_runtime_enable(dev);
-
-	rc = ddi->drv->probe(ddi->dev, ddi->id);
+	pm_runtime_get_sync(dev);
+	pci_dev->driver = pci_drv;
+	rc = pci_drv->probe(pci_dev, ddi->id);
 	if (rc) {
-		pm_runtime_disable(dev);
-		pm_runtime_set_suspended(dev);
-		pm_runtime_put_noidle(dev);
+		pci_dev->driver = NULL;
+		pm_runtime_put_sync(dev);
 	}
-	if (parent)
-		pm_runtime_put(parent);
 	return rc;
 }
 
@@ -322,10 +317,8 @@
 		id = pci_match_device(drv, pci_dev);
 		if (id)
 			error = pci_call_probe(drv, pci_dev, id);
-		if (error >= 0) {
-			pci_dev->driver = drv;
+		if (error >= 0)
 			error = 0;
-		}
 	}
 	return error;
 }
@@ -361,9 +354,7 @@
 	}
 
 	/* Undo the runtime PM settings in local_pci_probe() */
-	pm_runtime_disable(dev);
-	pm_runtime_set_suspended(dev);
-	pm_runtime_put_noidle(dev);
+	pm_runtime_put_sync(dev);
 
 	/*
 	 * If the device is still on, set the power state as "unknown",
@@ -986,6 +977,13 @@
 	pci_power_t prev = pci_dev->current_state;
 	int error;
 
+	/*
+	 * If pci_dev->driver is not set (unbound), the device should
+	 * always remain in D0 regardless of the runtime PM status
+	 */
+	if (!pci_dev->driver)
+		return 0;
+
 	if (!pm || !pm->runtime_suspend)
 		return -ENOSYS;
 
@@ -1007,10 +1005,10 @@
 		return 0;
 	}
 
-	if (!pci_dev->state_saved)
+	if (!pci_dev->state_saved) {
 		pci_save_state(pci_dev);
-
-	pci_finish_runtime_suspend(pci_dev);
+		pci_finish_runtime_suspend(pci_dev);
+	}
 
 	return 0;
 }
@@ -1021,6 +1019,13 @@
 	struct pci_dev *pci_dev = to_pci_dev(dev);
 	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
 
+	/*
+	 * If pci_dev->driver is not set (unbound), the device should
+	 * always remain in D0 regardless of the runtime PM status
+	 */
+	if (!pci_dev->driver)
+		return 0;
+
 	if (!pm || !pm->runtime_resume)
 		return -ENOSYS;
 
@@ -1038,8 +1043,16 @@
 
 static int pci_pm_runtime_idle(struct device *dev)
 {
+	struct pci_dev *pci_dev = to_pci_dev(dev);
 	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
 
+	/*
+	 * If pci_dev->driver is not set (unbound), the device should
+	 * always remain in D0 regardless of the runtime PM status
+	 */
+	if (!pci_dev->driver)
+		goto out;
+
 	if (!pm)
 		return -ENOSYS;
 
@@ -1049,8 +1062,8 @@
 			return ret;
 	}
 
+out:
 	pm_runtime_suspend(dev);
-
 	return 0;
 }
 
diff --git a/drivers/pci/pci-stub.c b/drivers/pci/pci-stub.c
index 775e933..6e47c51 100644
--- a/drivers/pci/pci-stub.c
+++ b/drivers/pci/pci-stub.c
@@ -28,7 +28,7 @@
 
 static int pci_stub_probe(struct pci_dev *dev, const struct pci_device_id *id)
 {
-	dev_printk(KERN_INFO, &dev->dev, "claimed by stub\n");
+	dev_info(&dev->dev, "claimed by stub\n");
 	return 0;
 }
 
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index 68d56f0..05b78b1 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -401,6 +401,106 @@
 }
 #endif
 
+#ifdef CONFIG_PCI_IOV
+static ssize_t sriov_totalvfs_show(struct device *dev,
+				   struct device_attribute *attr,
+				   char *buf)
+{
+	struct pci_dev *pdev = to_pci_dev(dev);
+
+	return sprintf(buf, "%u\n", pci_sriov_get_totalvfs(pdev));
+}
+
+
+static ssize_t sriov_numvfs_show(struct device *dev,
+				 struct device_attribute *attr,
+				 char *buf)
+{
+	struct pci_dev *pdev = to_pci_dev(dev);
+
+	return sprintf(buf, "%u\n", pdev->sriov->num_VFs);
+}
+
+/*
+ * num_vfs > 0; number of vfs to enable
+ * num_vfs = 0; disable all vfs
+ *
+ * Note: SRIOV spec doesn't allow partial VF
+ *       disable, so its all or none.
+ */
+static ssize_t sriov_numvfs_store(struct device *dev,
+				  struct device_attribute *attr,
+				  const char *buf, size_t count)
+{
+	struct pci_dev *pdev = to_pci_dev(dev);
+	int num_vfs_enabled = 0;
+	int num_vfs;
+	int ret = 0;
+	u16 total;
+
+	if (kstrtoint(buf, 0, &num_vfs) < 0)
+		return -EINVAL;
+
+	/* is PF driver loaded w/callback */
+	if (!pdev->driver || !pdev->driver->sriov_configure) {
+		dev_info(&pdev->dev,
+			 "Driver doesn't support SRIOV configuration via sysfs\n");
+		return -ENOSYS;
+	}
+
+	/* if enabling vf's ... */
+	total = pci_sriov_get_totalvfs(pdev);
+	/* Requested VFs to enable < totalvfs and none enabled already */
+	if ((num_vfs > 0) && (num_vfs <= total)) {
+		if (pdev->sriov->num_VFs == 0) {
+			num_vfs_enabled =
+				pdev->driver->sriov_configure(pdev, num_vfs);
+			if ((num_vfs_enabled >= 0) &&
+			    (num_vfs_enabled != num_vfs)) {
+				dev_warn(&pdev->dev,
+					 "Only %d VFs enabled\n",
+					 num_vfs_enabled);
+				return count;
+			} else if (num_vfs_enabled < 0)
+				/* error code from driver callback */
+				return num_vfs_enabled;
+		} else if (num_vfs == pdev->sriov->num_VFs) {
+			dev_warn(&pdev->dev,
+				 "%d VFs already enabled; no enable action taken\n",
+				 num_vfs);
+			return count;
+		} else {
+			dev_warn(&pdev->dev,
+				 "%d VFs already enabled. Disable before enabling %d VFs\n",
+				 pdev->sriov->num_VFs, num_vfs);
+			return -EINVAL;
+		}
+	}
+
+	/* disable vfs */
+	if (num_vfs == 0) {
+		if (pdev->sriov->num_VFs != 0) {
+			ret = pdev->driver->sriov_configure(pdev, 0);
+			return ret ? ret : count;
+		} else {
+			dev_warn(&pdev->dev,
+				 "All VFs disabled; no disable action taken\n");
+			return count;
+		}
+	}
+
+	dev_err(&pdev->dev,
+		"Invalid value for number of VFs to enable: %d\n", num_vfs);
+
+	return -EINVAL;
+}
+
+static struct device_attribute sriov_totalvfs_attr = __ATTR_RO(sriov_totalvfs);
+static struct device_attribute sriov_numvfs_attr =
+		__ATTR(sriov_numvfs, (S_IRUGO|S_IWUSR|S_IWGRP),
+		       sriov_numvfs_show, sriov_numvfs_store);
+#endif /* CONFIG_PCI_IOV */
+
 struct device_attribute pci_dev_attrs[] = {
 	__ATTR_RO(resource),
 	__ATTR_RO(vendor),
@@ -1262,29 +1362,20 @@
 		pdev->rom_attr = attr;
 	}
 
-	if ((pdev->class >> 8) == PCI_CLASS_DISPLAY_VGA) {
-		retval = device_create_file(&pdev->dev, &vga_attr);
-		if (retval)
-			goto err_rom_file;
-	}
-
 	/* add platform-specific attributes */
 	retval = pcibios_add_platform_entries(pdev);
 	if (retval)
-		goto err_vga_file;
+		goto err_rom_file;
 
 	/* add sysfs entries for various capabilities */
 	retval = pci_create_capabilities_sysfs(pdev);
 	if (retval)
-		goto err_vga_file;
+		goto err_rom_file;
 
 	pci_create_firmware_label_files(pdev);
 
 	return 0;
 
-err_vga_file:
-	if ((pdev->class >> 8) == PCI_CLASS_DISPLAY_VGA)
-		device_remove_file(&pdev->dev, &vga_attr);
 err_rom_file:
 	if (rom_size) {
 		sysfs_remove_bin_file(&pdev->dev.kobj, pdev->rom_attr);
@@ -1370,3 +1461,62 @@
 }
 
 late_initcall(pci_sysfs_init);
+
+static struct attribute *pci_dev_dev_attrs[] = {
+	&vga_attr.attr,
+	NULL,
+};
+
+static umode_t pci_dev_attrs_are_visible(struct kobject *kobj,
+						struct attribute *a, int n)
+{
+	struct device *dev = container_of(kobj, struct device, kobj);
+	struct pci_dev *pdev = to_pci_dev(dev);
+
+	if (a == &vga_attr.attr)
+		if ((pdev->class >> 8) != PCI_CLASS_DISPLAY_VGA)
+			return 0;
+
+	return a->mode;
+}
+
+#ifdef CONFIG_PCI_IOV
+static struct attribute *sriov_dev_attrs[] = {
+	&sriov_totalvfs_attr.attr,
+	&sriov_numvfs_attr.attr,
+	NULL,
+};
+
+static umode_t sriov_attrs_are_visible(struct kobject *kobj,
+					 struct attribute *a, int n)
+{
+	struct device *dev = container_of(kobj, struct device, kobj);
+
+	if (!dev_is_pf(dev))
+		return 0;
+
+	return a->mode;
+}
+
+static struct attribute_group sriov_dev_attr_group = {
+	.attrs = sriov_dev_attrs,
+	.is_visible = sriov_attrs_are_visible,
+};
+#endif /* CONFIG_PCI_IOV */
+
+static struct attribute_group pci_dev_attr_group = {
+	.attrs = pci_dev_dev_attrs,
+	.is_visible = pci_dev_attrs_are_visible,
+};
+
+static const struct attribute_group *pci_dev_attr_groups[] = {
+	&pci_dev_attr_group,
+#ifdef CONFIG_PCI_IOV
+	&sriov_dev_attr_group,
+#endif
+	NULL,
+};
+
+struct device_type pci_dev_type = {
+	.groups = pci_dev_attr_groups,
+};
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index bdf66b5..5cb5820 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -1333,6 +1333,19 @@
 		dr->pinned = 1;
 }
 
+/*
+ * pcibios_add_device - provide arch specific hooks when adding device dev
+ * @dev: the PCI device being added
+ *
+ * Permits the platform to provide architecture specific functionality when
+ * devices are added. This is the default implementation. Architecture
+ * implementations can override this.
+ */
+int __weak pcibios_add_device (struct pci_dev *dev)
+{
+	return 0;
+}
+
 /**
  * pcibios_disable_device - disable arch specific PCI resources for device dev
  * @dev: the PCI device to disable
@@ -1578,15 +1591,25 @@
 
 	pci_write_config_word(dev, dev->pm_cap + PCI_PM_CTRL, pmcsr);
 
-	/* PCI (as opposed to PCIe) PME requires that the device have
-	   its PME# line hooked up correctly. Not all hardware vendors
-	   do this, so the PME never gets delivered and the device
-	   remains asleep. The easiest way around this is to
-	   periodically walk the list of suspended devices and check
-	   whether any have their PME flag set. The assumption is that
-	   we'll wake up often enough anyway that this won't be a huge
-	   hit, and the power savings from the devices will still be a
-	   win. */
+	/*
+	 * PCI (as opposed to PCIe) PME requires that the device have
+	 * its PME# line hooked up correctly. Not all hardware vendors
+	 * do this, so the PME never gets delivered and the device
+	 * remains asleep. The easiest way around this is to
+	 * periodically walk the list of suspended devices and check
+	 * whether any have their PME flag set. The assumption is that
+	 * we'll wake up often enough anyway that this won't be a huge
+	 * hit, and the power savings from the devices will still be a
+	 * win.
+	 *
+	 * Although PCIe uses in-band PME message instead of PME# line
+	 * to report PME, PME does not work for some PCIe devices in
+	 * reality.  For example, there are devices that set their PME
+	 * status bits, but don't really bother to send a PME message;
+	 * there are PCI Express Root Ports that don't bother to
+	 * trigger interrupts when they receive PME messages from the
+	 * devices below.  So PME poll is used for PCIe devices too.
+	 */
 
 	if (dev->pme_poll) {
 		struct pci_pme_device *pme_dev;
@@ -1900,6 +1923,8 @@
 	u16 pmc;
 
 	pm_runtime_forbid(&dev->dev);
+	pm_runtime_set_active(&dev->dev);
+	pm_runtime_enable(&dev->dev);
 	device_enable_async_suspend(&dev->dev);
 	dev->wakeup_prepared = false;
 
@@ -3865,14 +3890,13 @@
 }
 
 /**
- * pci_ext_cfg_enabled - can we access extended PCI config space?
- * @dev: The PCI device of the root bridge.
+ * pci_ext_cfg_avail - can we access extended PCI config space?
  *
  * Returns 1 if we can access PCI extended config space (offsets
  * greater than 0xff). This is the default implementation. Architecture
  * implementations can override this.
  */
-int __weak pci_ext_cfg_avail(struct pci_dev *dev)
+int __weak pci_ext_cfg_avail(void)
 {
 	return 1;
 }
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index e253881..e851829 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -158,6 +158,7 @@
 }
 extern struct device_attribute pci_dev_attrs[];
 extern struct device_attribute pcibus_dev_attrs[];
+extern struct device_type pci_dev_type;
 extern struct bus_attribute pci_bus_attrs[];
 
 
@@ -229,13 +230,14 @@
 	int nres;		/* number of resources */
 	u32 cap;		/* SR-IOV Capabilities */
 	u16 ctrl;		/* SR-IOV Control */
-	u16 total;		/* total VFs associated with the PF */
-	u16 initial;		/* initial VFs associated with the PF */
-	u16 nr_virtfn;		/* number of VFs available */
+	u16 total_VFs;		/* total VFs associated with the PF */
+	u16 initial_VFs;	/* initial VFs associated with the PF */
+	u16 num_VFs;		/* number of VFs available */
 	u16 offset;		/* first VF Routing ID offset */
 	u16 stride;		/* following VF stride */
 	u32 pgsz;		/* page size for BAR alignment */
 	u8 link;		/* Function Dependency Link */
+	u16 driver_max_VFs;	/* max num VFs driver supports */
 	struct pci_dev *dev;	/* lowest numbered PF */
 	struct pci_dev *self;	/* this PF */
 	struct mutex lock;	/* lock for VF bus */
diff --git a/drivers/pci/pcie/aer/aerdrv.h b/drivers/pci/pcie/aer/aerdrv.h
index 94a7598..22f840f 100644
--- a/drivers/pci/pcie/aer/aerdrv.h
+++ b/drivers/pci/pcie/aer/aerdrv.h
@@ -87,6 +87,9 @@
 static inline pci_ers_result_t merge_result(enum pci_ers_result orig,
 		enum pci_ers_result new)
 {
+	if (new == PCI_ERS_RESULT_NO_AER_DRIVER)
+		return PCI_ERS_RESULT_NO_AER_DRIVER;
+
 	if (new == PCI_ERS_RESULT_NONE)
 		return orig;
 
@@ -97,7 +100,7 @@
 		break;
 	case PCI_ERS_RESULT_DISCONNECT:
 		if (new == PCI_ERS_RESULT_NEED_RESET)
-			orig = new;
+			orig = PCI_ERS_RESULT_NEED_RESET;
 		break;
 	default:
 		break;
diff --git a/drivers/pci/pcie/aer/aerdrv_core.c b/drivers/pci/pcie/aer/aerdrv_core.c
index af4e31c..421bbc5 100644
--- a/drivers/pci/pcie/aer/aerdrv_core.c
+++ b/drivers/pci/pcie/aer/aerdrv_core.c
@@ -232,13 +232,27 @@
 				   dev->driver ?
 				   "no AER-aware driver" : "no driver");
 		}
-		goto out;
+
+		/*
+		 * If there's any device in the subtree that does not
+		 * have an error_detected callback, returning
+		 * PCI_ERS_RESULT_NO_AER_DRIVER prevents calling of
+		 * the subsequent mmio_enabled/slot_reset/resume
+		 * callbacks of "any" device in the subtree. All the
+		 * devices in the subtree are left in the error state
+		 * without recovery.
+		 */
+
+		if (!(dev->hdr_type & PCI_HEADER_TYPE_BRIDGE))
+			vote = PCI_ERS_RESULT_NO_AER_DRIVER;
+		else
+			vote = PCI_ERS_RESULT_NONE;
+	} else {
+		err_handler = dev->driver->err_handler;
+		vote = err_handler->error_detected(dev, result_data->state);
 	}
 
-	err_handler = dev->driver->err_handler;
-	vote = err_handler->error_detected(dev, result_data->state);
 	result_data->result = merge_result(result_data->result, vote);
-out:
 	device_unlock(&dev->dev);
 	return 0;
 }
diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c
index 213753b..b52630b 100644
--- a/drivers/pci/pcie/aspm.c
+++ b/drivers/pci/pcie/aspm.c
@@ -242,8 +242,7 @@
 		return;
 
 	/* Training failed. Restore common clock configurations */
-	dev_printk(KERN_ERR, &parent->dev,
-		   "ASPM: Could not configure common clock\n");
+	dev_err(&parent->dev, "ASPM: Could not configure common clock\n");
 	list_for_each_entry(child, &linkbus->devices, bus_list)
 		pcie_capability_write_word(child, PCI_EXP_LNKCTL,
 					   child_reg[PCI_FUNC(child->devfn)]);
@@ -427,7 +426,8 @@
 
 static void pcie_config_aspm_dev(struct pci_dev *pdev, u32 val)
 {
-	pcie_capability_clear_and_set_word(pdev, PCI_EXP_LNKCTL, 0x3, val);
+	pcie_capability_clear_and_set_word(pdev, PCI_EXP_LNKCTL,
+					   PCI_EXP_LNKCTL_ASPMC, val);
 }
 
 static void pcie_config_aspm_link(struct pcie_link_state *link, u32 state)
@@ -442,12 +442,12 @@
 		return;
 	/* Convert ASPM state to upstream/downstream ASPM register state */
 	if (state & ASPM_STATE_L0S_UP)
-		dwstream |= PCIE_LINK_STATE_L0S;
+		dwstream |= PCI_EXP_LNKCTL_ASPM_L0S;
 	if (state & ASPM_STATE_L0S_DW)
-		upstream |= PCIE_LINK_STATE_L0S;
+		upstream |= PCI_EXP_LNKCTL_ASPM_L0S;
 	if (state & ASPM_STATE_L1) {
-		upstream |= PCIE_LINK_STATE_L1;
-		dwstream |= PCIE_LINK_STATE_L1;
+		upstream |= PCI_EXP_LNKCTL_ASPM_L1;
+		dwstream |= PCI_EXP_LNKCTL_ASPM_L1;
 	}
 	/*
 	 * Spec 2.0 suggests all functions should be configured the
@@ -507,9 +507,7 @@
 		 */
 		pcie_capability_read_dword(child, PCI_EXP_DEVCAP, &reg32);
 		if (!(reg32 & PCI_EXP_DEVCAP_RBER) && !aspm_force) {
-			dev_printk(KERN_INFO, &child->dev, "disabling ASPM"
-				" on pre-1.1 PCIe device.  You can enable it"
-				" with 'pcie_aspm=force'\n");
+			dev_info(&child->dev, "disabling ASPM on pre-1.1 PCIe device.  You can enable it with 'pcie_aspm=force'\n");
 			return -EINVAL;
 		}
 	}
diff --git a/drivers/pci/pcie/portdrv_core.c b/drivers/pci/pcie/portdrv_core.c
index ed129b4..b42133a 100644
--- a/drivers/pci/pcie/portdrv_core.c
+++ b/drivers/pci/pcie/portdrv_core.c
@@ -120,8 +120,7 @@
 		 * the value in this field indicates which MSI-X Table entry is
 		 * used to generate the interrupt message."
 		 */
-		pos = pci_pcie_cap(dev);
-		pci_read_config_word(dev, pos + PCI_EXP_FLAGS, &reg16);
+		pcie_capability_read_word(dev, PCI_EXP_FLAGS, &reg16);
 		entry = (reg16 & PCI_EXP_FLAGS_IRQ) >> 9;
 		if (entry >= nr_entries)
 			goto Error;
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 3683f60..6186f03 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -521,7 +521,7 @@
 
 void pcie_update_link_speed(struct pci_bus *bus, u16 linksta)
 {
-	bus->cur_bus_speed = pcie_link_speed[linksta & 0xf];
+	bus->cur_bus_speed = pcie_link_speed[linksta & PCI_EXP_LNKSTA_CLS];
 }
 EXPORT_SYMBOL_GPL(pcie_update_link_speed);
 
@@ -579,14 +579,16 @@
 	if (pos) {
 		u16 status;
 		enum pci_bus_speed max;
-		pci_read_config_word(bridge, pos + 2, &status);
 
-		if (status & 0x8000) {
+		pci_read_config_word(bridge, pos + PCI_X_BRIDGE_SSTATUS,
+				     &status);
+
+		if (status & PCI_X_SSTATUS_533MHZ) {
 			max = PCI_SPEED_133MHz_PCIX_533;
-		} else if (status & 0x4000) {
+		} else if (status & PCI_X_SSTATUS_266MHZ) {
 			max = PCI_SPEED_133MHz_PCIX_266;
-		} else if (status & 0x0002) {
-			if (((status >> 12) & 0x3) == 2) {
+		} else if (status & PCI_X_SSTATUS_133MHZ) {
+			if ((status & PCI_X_SSTATUS_VERS) == PCI_X_SSTATUS_V2) {
 				max = PCI_SPEED_133MHz_PCIX_ECC;
 			} else {
 				max = PCI_SPEED_133MHz_PCIX;
@@ -596,7 +598,8 @@
 		}
 
 		bus->max_bus_speed = max;
-		bus->cur_bus_speed = pcix_bus_speed[(status >> 6) & 0xf];
+		bus->cur_bus_speed = pcix_bus_speed[
+			(status & PCI_X_SSTATUS_FREQ) >> 6];
 
 		return;
 	}
@@ -607,7 +610,7 @@
 		u16 linksta;
 
 		pcie_capability_read_dword(bridge, PCI_EXP_LNKCAP, &linkcap);
-		bus->max_bus_speed = pcie_link_speed[linkcap & 0xf];
+		bus->max_bus_speed = pcie_link_speed[linkcap & PCI_EXP_LNKCAP_SLS];
 
 		pcie_capability_read_word(bridge, PCI_EXP_LNKSTA, &linksta);
 		pcie_update_link_speed(bus, linksta);
@@ -975,6 +978,7 @@
 	dev->sysdata = dev->bus->sysdata;
 	dev->dev.parent = dev->bus->bridge;
 	dev->dev.bus = &pci_bus_type;
+	dev->dev.type = &pci_dev_type;
 	dev->hdr_type = hdr_type & 0x7f;
 	dev->multifunction = !!(hdr_type & 0x80);
 	dev->error_state = pci_channel_io_normal;
@@ -1889,6 +1893,28 @@
 	return max;
 }
 
+/**
+ * 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;
+
+	max = pci_scan_child_bus(bus);
+	pci_assign_unassigned_bus_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);
 EXPORT_SYMBOL(pci_scan_bridge);
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 22ad3ee..8f7a634 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -1790,6 +1790,45 @@
 			 PCI_DEVICE_ID_TOSHIBA_TC86C001_IDE,
 			 quirk_tc86c001_ide);
 
+/*
+ * PLX PCI 9050 PCI Target bridge controller has an errata that prevents the
+ * local configuration registers accessible via BAR0 (memory) or BAR1 (i/o)
+ * being read correctly if bit 7 of the base address is set.
+ * The BAR0 or BAR1 region may be disabled (size 0) or enabled (size 128).
+ * Re-allocate the regions to a 256-byte boundary if necessary.
+ */
+static void quirk_plx_pci9050(struct pci_dev *dev)
+{
+	unsigned int bar;
+
+	/* Fixed in revision 2 (PCI 9052). */
+	if (dev->revision >= 2)
+		return;
+	for (bar = 0; bar <= 1; bar++)
+		if (pci_resource_len(dev, bar) == 0x80 &&
+		    (pci_resource_start(dev, bar) & 0x80)) {
+			struct resource *r = &dev->resource[bar];
+			dev_info(&dev->dev,
+				 "Re-allocating PLX PCI 9050 BAR %u to length 256 to avoid bit 7 bug\n",
+				 bar);
+			r->start = 0;
+			r->end = 0xff;
+		}
+}
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
+			 quirk_plx_pci9050);
+/*
+ * The following Meilhaus (vendor ID 0x1402) device IDs (amongst others)
+ * may be using the PLX PCI 9050: 0x0630, 0x0940, 0x0950, 0x0960, 0x100b,
+ * 0x1400, 0x140a, 0x140b, 0x14e0, 0x14ea, 0x14eb, 0x1604, 0x1608, 0x160c,
+ * 0x168f, 0x2000, 0x2600, 0x3000, 0x810a, 0x810b.
+ *
+ * Currently, device IDs 0x2000 and 0x2600 are used by the Comedi "me_daq"
+ * driver.
+ */
+DECLARE_PCI_FIXUP_HEADER(0x1402, 0x2000, quirk_plx_pci9050);
+DECLARE_PCI_FIXUP_HEADER(0x1402, 0x2600, quirk_plx_pci9050);
+
 static void quirk_netmos(struct pci_dev *dev)
 {
 	unsigned int num_parallel = (dev->subsystem_device & 0xf0) >> 4;
diff --git a/drivers/pci/remove.c b/drivers/pci/remove.c
index 513972f..7c0fd92 100644
--- a/drivers/pci/remove.c
+++ b/drivers/pci/remove.c
@@ -111,3 +111,39 @@
 	pci_remove_bus_device(dev);
 }
 EXPORT_SYMBOL(pci_stop_and_remove_bus_device);
+
+void pci_stop_root_bus(struct pci_bus *bus)
+{
+	struct pci_dev *child, *tmp;
+	struct pci_host_bridge *host_bridge;
+
+	if (!pci_is_root_bus(bus))
+		return;
+
+	host_bridge = to_pci_host_bridge(bus->bridge);
+	list_for_each_entry_safe_reverse(child, tmp,
+					 &bus->devices, bus_list)
+		pci_stop_bus_device(child);
+
+	/* stop the host bridge */
+	device_del(&host_bridge->dev);
+}
+
+void pci_remove_root_bus(struct pci_bus *bus)
+{
+	struct pci_dev *child, *tmp;
+	struct pci_host_bridge *host_bridge;
+
+	if (!pci_is_root_bus(bus))
+		return;
+
+	host_bridge = to_pci_host_bridge(bus->bridge);
+	list_for_each_entry_safe(child, tmp,
+				 &bus->devices, bus_list)
+		pci_remove_bus_device(child);
+	pci_remove_bus(bus);
+	host_bridge->bus = NULL;
+
+	/* remove the host bridge */
+	put_device(&host_bridge->dev);
+}
diff --git a/drivers/pci/rom.c b/drivers/pci/rom.c
index 0b3037a..ab886b7 100644
--- a/drivers/pci/rom.c
+++ b/drivers/pci/rom.c
@@ -118,11 +118,17 @@
 	void __iomem *rom;
 
 	/*
+	 * Some devices may provide ROMs via a source other than the BAR
+	 */
+	if (pdev->rom && pdev->romlen) {
+		*size = pdev->romlen;
+		return phys_to_virt(pdev->rom);
+	/*
 	 * IORESOURCE_ROM_SHADOW set on x86, x86_64 and IA64 supports legacy
 	 * memory map if the VGA enable bit of the Bridge Control register is
 	 * set for embedded VGA.
 	 */
-	if (res->flags & IORESOURCE_ROM_SHADOW) {
+	} else if (res->flags & IORESOURCE_ROM_SHADOW) {
 		/* primary video rom always starts here */
 		start = (loff_t)0xC0000;
 		*size = 0x20000; /* cover C000:0 through E000:0 */
@@ -181,7 +187,8 @@
 	if (res->flags & (IORESOURCE_ROM_COPY | IORESOURCE_ROM_BIOS_COPY))
 		return;
 
-	iounmap(rom);
+	if (!pdev->rom || !pdev->romlen)
+		iounmap(rom);
 
 	/* Disable again before continuing, leave enabled if pci=rom */
 	if (!(res->flags & (IORESOURCE_ROM_ENABLE | IORESOURCE_ROM_SHADOW)))
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index 1e808ca..6d3591d 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -1550,25 +1550,12 @@
 }
 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)
+void pci_assign_unassigned_bus_resources(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 ||
@@ -1579,11 +1566,4 @@
 	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/xen-pcifront.c b/drivers/pci/xen-pcifront.c
index db542f4..966abc6 100644
--- a/drivers/pci/xen-pcifront.c
+++ b/drivers/pci/xen-pcifront.c
@@ -1068,13 +1068,16 @@
 	case XenbusStateInitialising:
 	case XenbusStateInitWait:
 	case XenbusStateInitialised:
-	case XenbusStateClosed:
 		break;
 
 	case XenbusStateConnected:
 		pcifront_try_connect(pdev);
 		break;
 
+	case XenbusStateClosed:
+		if (xdev->state == XenbusStateClosed)
+			break;
+		/* Missed the backend's CLOSING state -- fallthrough */
 	case XenbusStateClosing:
 		dev_warn(&xdev->dev, "backend going away!\n");
 		pcifront_try_disconnect(pdev);
diff --git a/drivers/pinctrl/mvebu/pinctrl-dove.c b/drivers/pinctrl/mvebu/pinctrl-dove.c
index ffe74b2..40c9c3e 100644
--- a/drivers/pinctrl/mvebu/pinctrl-dove.c
+++ b/drivers/pinctrl/mvebu/pinctrl-dove.c
@@ -22,22 +22,22 @@
 
 #include "pinctrl-mvebu.h"
 
-#define DOVE_SB_REGS_VIRT_BASE		0xfde00000
-#define DOVE_MPP_VIRT_BASE		(DOVE_SB_REGS_VIRT_BASE | 0xd0200)
+#define DOVE_SB_REGS_VIRT_BASE		IOMEM(0xfde00000)
+#define DOVE_MPP_VIRT_BASE		(DOVE_SB_REGS_VIRT_BASE + 0xd0200)
 #define DOVE_PMU_MPP_GENERAL_CTRL	(DOVE_MPP_VIRT_BASE + 0x10)
 #define  DOVE_AU0_AC97_SEL		BIT(16)
-#define DOVE_GLOBAL_CONFIG_1		(DOVE_SB_REGS_VIRT_BASE | 0xe802C)
+#define DOVE_GLOBAL_CONFIG_1		(DOVE_SB_REGS_VIRT_BASE + 0xe802C)
 #define  DOVE_TWSI_ENABLE_OPTION1	BIT(7)
-#define DOVE_GLOBAL_CONFIG_2		(DOVE_SB_REGS_VIRT_BASE | 0xe8030)
+#define DOVE_GLOBAL_CONFIG_2		(DOVE_SB_REGS_VIRT_BASE + 0xe8030)
 #define  DOVE_TWSI_ENABLE_OPTION2	BIT(20)
 #define  DOVE_TWSI_ENABLE_OPTION3	BIT(21)
 #define  DOVE_TWSI_OPTION3_GPIO		BIT(22)
-#define DOVE_SSP_CTRL_STATUS_1		(DOVE_SB_REGS_VIRT_BASE | 0xe8034)
+#define DOVE_SSP_CTRL_STATUS_1		(DOVE_SB_REGS_VIRT_BASE + 0xe8034)
 #define  DOVE_SSP_ON_AU1		BIT(0)
-#define DOVE_MPP_GENERAL_VIRT_BASE	(DOVE_SB_REGS_VIRT_BASE | 0xe803c)
+#define DOVE_MPP_GENERAL_VIRT_BASE	(DOVE_SB_REGS_VIRT_BASE + 0xe803c)
 #define  DOVE_AU1_SPDIFO_GPIO_EN	BIT(1)
 #define  DOVE_NAND_GPIO_EN		BIT(0)
-#define DOVE_GPIO_LO_VIRT_BASE		(DOVE_SB_REGS_VIRT_BASE | 0xd0400)
+#define DOVE_GPIO_LO_VIRT_BASE		(DOVE_SB_REGS_VIRT_BASE + 0xd0400)
 #define DOVE_MPP_CTRL4_VIRT_BASE	(DOVE_GPIO_LO_VIRT_BASE + 0x40)
 #define  DOVE_SPI_GPIO_SEL		BIT(5)
 #define  DOVE_UART1_GPIO_SEL		BIT(4)
@@ -234,6 +234,14 @@
 	unsigned long gmpp = readl(DOVE_MPP_GENERAL_VIRT_BASE);
 	unsigned long gcfg2 = readl(DOVE_GLOBAL_CONFIG_2);
 
+	/*
+	 * clear all audio1 related bits before configure
+	 */
+	gcfg2 &= ~DOVE_TWSI_OPTION3_GPIO;
+	gmpp &= ~DOVE_AU1_SPDIFO_GPIO_EN;
+	sspc1 &= ~DOVE_SSP_ON_AU1;
+	mpp4 &= ~DOVE_AU1_GPIO_SEL;
+
 	if (config & BIT(0))
 		gcfg2 |= DOVE_TWSI_OPTION3_GPIO;
 	if (config & BIT(1))
diff --git a/drivers/pinctrl/mvebu/pinctrl-kirkwood.c b/drivers/pinctrl/mvebu/pinctrl-kirkwood.c
index 9a74ef6..fa6ce31 100644
--- a/drivers/pinctrl/mvebu/pinctrl-kirkwood.c
+++ b/drivers/pinctrl/mvebu/pinctrl-kirkwood.c
@@ -21,340 +21,341 @@
 
 #include "pinctrl-mvebu.h"
 
-#define V(f6180, f6190, f6192, f6281, f6282)		\
+#define V(f6180, f6190, f6192, f6281, f6282, dx4122)	\
 	((f6180 << 0) | (f6190 << 1) | (f6192 << 2) |	\
-	 (f6281 << 3) | (f6282 << 4))
+	 (f6281 << 3) | (f6282 << 4) | (dx4122 << 5))
 
 enum kirkwood_variant {
-	VARIANT_MV88F6180 = V(1, 0, 0, 0, 0),
-	VARIANT_MV88F6190 = V(0, 1, 0, 0, 0),
-	VARIANT_MV88F6192 = V(0, 0, 1, 0, 0),
-	VARIANT_MV88F6281 = V(0, 0, 0, 1, 0),
-	VARIANT_MV88F6282 = V(0, 0, 0, 0, 1),
+	VARIANT_MV88F6180	= V(1, 0, 0, 0, 0, 0),
+	VARIANT_MV88F6190	= V(0, 1, 0, 0, 0, 0),
+	VARIANT_MV88F6192	= V(0, 0, 1, 0, 0, 0),
+	VARIANT_MV88F6281	= V(0, 0, 0, 1, 0, 0),
+	VARIANT_MV88F6282	= V(0, 0, 0, 0, 1, 0),
+	VARIANT_MV98DX4122	= V(0, 0, 0, 0, 0, 1),
 };
 
 static struct mvebu_mpp_mode mv88f6xxx_mpp_modes[] = {
 	MPP_MODE(0,
-		MPP_VAR_FUNCTION(0x0, "gpio", NULL,      V(1, 1, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0x1, "nand", "io2",     V(1, 1, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0x2, "spi", "cs",       V(1, 1, 1, 1, 1))),
+		MPP_VAR_FUNCTION(0x0, "gpio", NULL,      V(1, 1, 1, 1, 1, 1)),
+		MPP_VAR_FUNCTION(0x1, "nand", "io2",     V(1, 1, 1, 1, 1, 1)),
+		MPP_VAR_FUNCTION(0x2, "spi", "cs",       V(1, 1, 1, 1, 1, 1))),
 	MPP_MODE(1,
-		MPP_VAR_FUNCTION(0x0, "gpo", NULL,       V(1, 1, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0x1, "nand", "io3",     V(1, 1, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0x2, "spi", "mosi",     V(1, 1, 1, 1, 1))),
+		MPP_VAR_FUNCTION(0x0, "gpo", NULL,       V(1, 1, 1, 1, 1, 1)),
+		MPP_VAR_FUNCTION(0x1, "nand", "io3",     V(1, 1, 1, 1, 1, 1)),
+		MPP_VAR_FUNCTION(0x2, "spi", "mosi",     V(1, 1, 1, 1, 1, 1))),
 	MPP_MODE(2,
-		MPP_VAR_FUNCTION(0x0, "gpo", NULL,       V(1, 1, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0x1, "nand", "io4",     V(1, 1, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0x2, "spi", "sck",      V(1, 1, 1, 1, 1))),
+		MPP_VAR_FUNCTION(0x0, "gpo", NULL,       V(1, 1, 1, 1, 1, 1)),
+		MPP_VAR_FUNCTION(0x1, "nand", "io4",     V(1, 1, 1, 1, 1, 1)),
+		MPP_VAR_FUNCTION(0x2, "spi", "sck",      V(1, 1, 1, 1, 1, 1))),
 	MPP_MODE(3,
-		MPP_VAR_FUNCTION(0x0, "gpo", NULL,       V(1, 1, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0x1, "nand", "io5",     V(1, 1, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0x2, "spi", "miso",     V(1, 1, 1, 1, 1))),
+		MPP_VAR_FUNCTION(0x0, "gpo", NULL,       V(1, 1, 1, 1, 1, 1)),
+		MPP_VAR_FUNCTION(0x1, "nand", "io5",     V(1, 1, 1, 1, 1, 1)),
+		MPP_VAR_FUNCTION(0x2, "spi", "miso",     V(1, 1, 1, 1, 1, 1))),
 	MPP_MODE(4,
-		MPP_VAR_FUNCTION(0x0, "gpio", NULL,      V(1, 1, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0x1, "nand", "io6",     V(1, 1, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0x2, "uart0", "rxd",    V(1, 1, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0x5, "sata1", "act",    V(0, 0, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0xb, "lcd", "hsync",    V(0, 0, 0, 0, 1)),
-		MPP_VAR_FUNCTION(0xd, "ptp", "clk",      V(1, 1, 1, 1, 0))),
+		MPP_VAR_FUNCTION(0x0, "gpio", NULL,      V(1, 1, 1, 1, 1, 1)),
+		MPP_VAR_FUNCTION(0x1, "nand", "io6",     V(1, 1, 1, 1, 1, 1)),
+		MPP_VAR_FUNCTION(0x2, "uart0", "rxd",    V(1, 1, 1, 1, 1, 1)),
+		MPP_VAR_FUNCTION(0x5, "sata1", "act",    V(0, 0, 1, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0xb, "lcd", "hsync",    V(0, 0, 0, 0, 1, 0)),
+		MPP_VAR_FUNCTION(0xd, "ptp", "clk",      V(1, 1, 1, 1, 0, 0))),
 	MPP_MODE(5,
-		MPP_VAR_FUNCTION(0x0, "gpo", NULL,       V(1, 1, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0x1, "nand", "io7",     V(1, 1, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0x2, "uart0", "txd",    V(1, 1, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0x4, "ptp", "trig",     V(1, 1, 1, 1, 0)),
-		MPP_VAR_FUNCTION(0x5, "sata0", "act",    V(0, 1, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0xb, "lcd", "vsync",    V(0, 0, 0, 0, 1))),
+		MPP_VAR_FUNCTION(0x0, "gpo", NULL,       V(1, 1, 1, 1, 1, 1)),
+		MPP_VAR_FUNCTION(0x1, "nand", "io7",     V(1, 1, 1, 1, 1, 1)),
+		MPP_VAR_FUNCTION(0x2, "uart0", "txd",    V(1, 1, 1, 1, 1, 1)),
+		MPP_VAR_FUNCTION(0x4, "ptp", "trig",     V(1, 1, 1, 1, 0, 0)),
+		MPP_VAR_FUNCTION(0x5, "sata0", "act",    V(0, 1, 1, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0xb, "lcd", "vsync",    V(0, 0, 0, 0, 1, 0))),
 	MPP_MODE(6,
-		MPP_VAR_FUNCTION(0x0, "sysrst", "out",   V(1, 1, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0x1, "spi", "mosi",     V(1, 1, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0x2, "ptp", "trig",     V(1, 1, 1, 1, 0))),
+		MPP_VAR_FUNCTION(0x0, "sysrst", "out",   V(1, 1, 1, 1, 1, 1)),
+		MPP_VAR_FUNCTION(0x1, "spi", "mosi",     V(1, 1, 1, 1, 1, 1)),
+		MPP_VAR_FUNCTION(0x2, "ptp", "trig",     V(1, 1, 1, 1, 0, 0))),
 	MPP_MODE(7,
-		MPP_VAR_FUNCTION(0x0, "gpo", NULL,       V(1, 1, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0x1, "pex", "rsto",     V(1, 1, 1, 1, 0)),
-		MPP_VAR_FUNCTION(0x2, "spi", "cs",       V(1, 1, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0x3, "ptp", "trig",     V(1, 1, 1, 1, 0)),
-		MPP_VAR_FUNCTION(0xb, "lcd", "pwm",      V(0, 0, 0, 0, 1))),
+		MPP_VAR_FUNCTION(0x0, "gpo", NULL,       V(1, 1, 1, 1, 1, 1)),
+		MPP_VAR_FUNCTION(0x1, "pex", "rsto",     V(1, 1, 1, 1, 0, 1)),
+		MPP_VAR_FUNCTION(0x2, "spi", "cs",       V(1, 1, 1, 1, 1, 1)),
+		MPP_VAR_FUNCTION(0x3, "ptp", "trig",     V(1, 1, 1, 1, 0, 0)),
+		MPP_VAR_FUNCTION(0xb, "lcd", "pwm",      V(0, 0, 0, 0, 1, 0))),
 	MPP_MODE(8,
-		MPP_VAR_FUNCTION(0x0, "gpio", NULL,      V(1, 1, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0x1, "twsi0", "sda",    V(1, 1, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0x2, "uart0", "rts",    V(1, 1, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0x3, "uart1", "rts",    V(1, 1, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0x4, "mii-1", "rxerr",  V(0, 1, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0x5, "sata1", "prsnt",  V(0, 0, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0xc, "ptp", "clk",      V(1, 1, 1, 1, 0)),
-		MPP_VAR_FUNCTION(0xd, "mii", "col",      V(1, 1, 1, 1, 1))),
+		MPP_VAR_FUNCTION(0x0, "gpio", NULL,      V(1, 1, 1, 1, 1, 1)),
+		MPP_VAR_FUNCTION(0x1, "twsi0", "sda",    V(1, 1, 1, 1, 1, 1)),
+		MPP_VAR_FUNCTION(0x2, "uart0", "rts",    V(1, 1, 1, 1, 1, 1)),
+		MPP_VAR_FUNCTION(0x3, "uart1", "rts",    V(1, 1, 1, 1, 1, 1)),
+		MPP_VAR_FUNCTION(0x4, "mii-1", "rxerr",  V(0, 1, 1, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0x5, "sata1", "prsnt",  V(0, 0, 1, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0xc, "ptp", "clk",      V(1, 1, 1, 1, 0, 0)),
+		MPP_VAR_FUNCTION(0xd, "mii", "col",      V(1, 1, 1, 1, 1, 0))),
 	MPP_MODE(9,
-		MPP_VAR_FUNCTION(0x0, "gpio", NULL,      V(1, 1, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0x1, "twsi0", "sck",    V(1, 1, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0x2, "uart0", "cts",    V(1, 1, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0x3, "uart1", "cts",    V(1, 1, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0x5, "sata0", "prsnt",  V(0, 1, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0xc, "ptp", "evreq",    V(1, 1, 1, 1, 0)),
-		MPP_VAR_FUNCTION(0xd, "mii", "crs",      V(1, 1, 1, 1, 1))),
+		MPP_VAR_FUNCTION(0x0, "gpio", NULL,      V(1, 1, 1, 1, 1, 1)),
+		MPP_VAR_FUNCTION(0x1, "twsi0", "sck",    V(1, 1, 1, 1, 1, 1)),
+		MPP_VAR_FUNCTION(0x2, "uart0", "cts",    V(1, 1, 1, 1, 1, 1)),
+		MPP_VAR_FUNCTION(0x3, "uart1", "cts",    V(1, 1, 1, 1, 1, 1)),
+		MPP_VAR_FUNCTION(0x5, "sata0", "prsnt",  V(0, 1, 1, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0xc, "ptp", "evreq",    V(1, 1, 1, 1, 0, 0)),
+		MPP_VAR_FUNCTION(0xd, "mii", "crs",      V(1, 1, 1, 1, 1, 0))),
 	MPP_MODE(10,
-		MPP_VAR_FUNCTION(0x0, "gpo", NULL,       V(1, 1, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0x2, "spi", "sck",      V(1, 1, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0X3, "uart0", "txd",    V(1, 1, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0x5, "sata1", "act",    V(0, 0, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0xc, "ptp", "trig",     V(1, 1, 1, 1, 0))),
+		MPP_VAR_FUNCTION(0x0, "gpo", NULL,       V(1, 1, 1, 1, 1, 1)),
+		MPP_VAR_FUNCTION(0x2, "spi", "sck",      V(1, 1, 1, 1, 1, 1)),
+		MPP_VAR_FUNCTION(0X3, "uart0", "txd",    V(1, 1, 1, 1, 1, 1)),
+		MPP_VAR_FUNCTION(0x5, "sata1", "act",    V(0, 0, 1, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0xc, "ptp", "trig",     V(1, 1, 1, 1, 0, 0))),
 	MPP_MODE(11,
-		MPP_VAR_FUNCTION(0x0, "gpio", NULL,      V(1, 1, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0x2, "spi", "miso",     V(1, 1, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0x3, "uart0", "rxd",    V(1, 1, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0x4, "ptp-1", "evreq",  V(1, 1, 1, 1, 0)),
-		MPP_VAR_FUNCTION(0xc, "ptp-2", "trig",   V(1, 1, 1, 1, 0)),
-		MPP_VAR_FUNCTION(0xd, "ptp", "clk",      V(1, 1, 1, 1, 0)),
-		MPP_VAR_FUNCTION(0x5, "sata0", "act",    V(0, 1, 1, 1, 1))),
+		MPP_VAR_FUNCTION(0x0, "gpio", NULL,      V(1, 1, 1, 1, 1, 1)),
+		MPP_VAR_FUNCTION(0x2, "spi", "miso",     V(1, 1, 1, 1, 1, 1)),
+		MPP_VAR_FUNCTION(0x3, "uart0", "rxd",    V(1, 1, 1, 1, 1, 1)),
+		MPP_VAR_FUNCTION(0x4, "ptp-1", "evreq",  V(1, 1, 1, 1, 0, 0)),
+		MPP_VAR_FUNCTION(0xc, "ptp-2", "trig",   V(1, 1, 1, 1, 0, 0)),
+		MPP_VAR_FUNCTION(0xd, "ptp", "clk",      V(1, 1, 1, 1, 0, 0)),
+		MPP_VAR_FUNCTION(0x5, "sata0", "act",    V(0, 1, 1, 1, 1, 0))),
 	MPP_MODE(12,
-		MPP_VAR_FUNCTION(0x0, "gpo", NULL,       V(1, 1, 1, 0, 1)),
-		MPP_VAR_FUNCTION(0x0, "gpio", NULL,      V(0, 0, 0, 1, 0)),
-		MPP_VAR_FUNCTION(0x1, "sdio", "clk",     V(1, 1, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0xa, "audio", "spdifo", V(0, 0, 0, 0, 1)),
-		MPP_VAR_FUNCTION(0xb, "spi", "mosi",     V(0, 0, 0, 0, 1)),
-		MPP_VAR_FUNCTION(0xd, "twsi1", "sda",    V(0, 0, 0, 0, 1))),
+		MPP_VAR_FUNCTION(0x0, "gpo", NULL,       V(1, 1, 1, 0, 1, 0)),
+		MPP_VAR_FUNCTION(0x0, "gpio", NULL,      V(0, 0, 0, 1, 0, 0)),
+		MPP_VAR_FUNCTION(0x1, "sdio", "clk",     V(1, 1, 1, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0xa, "audio", "spdifo", V(0, 0, 0, 0, 1, 0)),
+		MPP_VAR_FUNCTION(0xb, "spi", "mosi",     V(0, 0, 0, 0, 1, 0)),
+		MPP_VAR_FUNCTION(0xd, "twsi1", "sda",    V(0, 0, 0, 0, 1, 0))),
 	MPP_MODE(13,
-		MPP_VAR_FUNCTION(0x0, "gpio", NULL,      V(1, 1, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0x1, "sdio", "cmd",     V(1, 1, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0x3, "uart1", "txd",    V(1, 1, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0xa, "audio", "rmclk",  V(0, 0, 0, 0, 1)),
-		MPP_VAR_FUNCTION(0xb, "lcd", "pwm",      V(0, 0, 0, 0, 1))),
+		MPP_VAR_FUNCTION(0x0, "gpio", NULL,      V(1, 1, 1, 1, 1, 1)),
+		MPP_VAR_FUNCTION(0x1, "sdio", "cmd",     V(1, 1, 1, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0x3, "uart1", "txd",    V(1, 1, 1, 1, 1, 1)),
+		MPP_VAR_FUNCTION(0xa, "audio", "rmclk",  V(0, 0, 0, 0, 1, 0)),
+		MPP_VAR_FUNCTION(0xb, "lcd", "pwm",      V(0, 0, 0, 0, 1, 0))),
 	MPP_MODE(14,
-		MPP_VAR_FUNCTION(0x0, "gpio", NULL,      V(1, 1, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0x1, "sdio", "d0",      V(1, 1, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0x3, "uart1", "rxd",    V(1, 1, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0x4, "sata1", "prsnt",  V(0, 0, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0xa, "audio", "spdifi", V(0, 0, 0, 0, 1)),
-		MPP_VAR_FUNCTION(0xb, "audio-1", "sdi",  V(0, 0, 0, 0, 1)),
-		MPP_VAR_FUNCTION(0xd, "mii", "col",      V(1, 1, 1, 1, 1))),
+		MPP_VAR_FUNCTION(0x0, "gpio", NULL,      V(1, 1, 1, 1, 1, 1)),
+		MPP_VAR_FUNCTION(0x1, "sdio", "d0",      V(1, 1, 1, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0x3, "uart1", "rxd",    V(1, 1, 1, 1, 1, 1)),
+		MPP_VAR_FUNCTION(0x4, "sata1", "prsnt",  V(0, 0, 1, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0xa, "audio", "spdifi", V(0, 0, 0, 0, 1, 0)),
+		MPP_VAR_FUNCTION(0xb, "audio-1", "sdi",  V(0, 0, 0, 0, 1, 0)),
+		MPP_VAR_FUNCTION(0xd, "mii", "col",      V(1, 1, 1, 1, 1, 0))),
 	MPP_MODE(15,
-		MPP_VAR_FUNCTION(0x0, "gpio", NULL,      V(1, 1, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0x1, "sdio", "d1",      V(1, 1, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0x2, "uart0", "rts",    V(1, 1, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0x3, "uart1", "txd",    V(1, 1, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0x4, "sata0", "act",    V(0, 1, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0xb, "spi", "cs",       V(0, 0, 0, 0, 1))),
+		MPP_VAR_FUNCTION(0x0, "gpio", NULL,      V(1, 1, 1, 1, 1, 1)),
+		MPP_VAR_FUNCTION(0x1, "sdio", "d1",      V(1, 1, 1, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0x2, "uart0", "rts",    V(1, 1, 1, 1, 1, 1)),
+		MPP_VAR_FUNCTION(0x3, "uart1", "txd",    V(1, 1, 1, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0x4, "sata0", "act",    V(0, 1, 1, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0xb, "spi", "cs",       V(0, 0, 0, 0, 1, 0))),
 	MPP_MODE(16,
-		MPP_VAR_FUNCTION(0x0, "gpio", NULL,      V(1, 1, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0x1, "sdio", "d2",      V(1, 1, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0x2, "uart0", "cts",    V(1, 1, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0x3, "uart1", "rxd",    V(1, 1, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0x4, "sata1", "act",    V(0, 0, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0xb, "lcd", "extclk",   V(0, 0, 0, 0, 1)),
-		MPP_VAR_FUNCTION(0xd, "mii", "crs",      V(1, 1, 1, 1, 1))),
+		MPP_VAR_FUNCTION(0x0, "gpio", NULL,      V(1, 1, 1, 1, 1, 1)),
+		MPP_VAR_FUNCTION(0x1, "sdio", "d2",      V(1, 1, 1, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0x2, "uart0", "cts",    V(1, 1, 1, 1, 1, 1)),
+		MPP_VAR_FUNCTION(0x3, "uart1", "rxd",    V(1, 1, 1, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0x4, "sata1", "act",    V(0, 0, 1, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0xb, "lcd", "extclk",   V(0, 0, 0, 0, 1, 0)),
+		MPP_VAR_FUNCTION(0xd, "mii", "crs",      V(1, 1, 1, 1, 1, 0))),
 	MPP_MODE(17,
-		MPP_VAR_FUNCTION(0x0, "gpio", NULL,      V(1, 1, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0x1, "sdio", "d3",      V(1, 1, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0x4, "sata0", "prsnt",  V(0, 1, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0xa, "sata1", "act",    V(0, 0, 0, 0, 1)),
-		MPP_VAR_FUNCTION(0xd, "twsi1", "sck",    V(0, 0, 0, 0, 1))),
+		MPP_VAR_FUNCTION(0x0, "gpio", NULL,      V(1, 1, 1, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0x1, "sdio", "d3",      V(1, 1, 1, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0x4, "sata0", "prsnt",  V(0, 1, 1, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0xa, "sata1", "act",    V(0, 0, 0, 0, 1, 0)),
+		MPP_VAR_FUNCTION(0xd, "twsi1", "sck",    V(0, 0, 0, 0, 1, 0))),
 	MPP_MODE(18,
-		MPP_VAR_FUNCTION(0x0, "gpo", NULL,       V(1, 1, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0x1, "nand", "io0",     V(1, 1, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0x2, "pex", "clkreq",   V(0, 0, 0, 0, 1))),
+		MPP_VAR_FUNCTION(0x0, "gpo", NULL,       V(1, 1, 1, 1, 1, 1)),
+		MPP_VAR_FUNCTION(0x1, "nand", "io0",     V(1, 1, 1, 1, 1, 1)),
+		MPP_VAR_FUNCTION(0x2, "pex", "clkreq",   V(0, 0, 0, 0, 1, 0))),
 	MPP_MODE(19,
-		MPP_VAR_FUNCTION(0x0, "gpo", NULL,       V(1, 1, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0x1, "nand", "io1",     V(1, 1, 1, 1, 1))),
+		MPP_VAR_FUNCTION(0x0, "gpo", NULL,       V(1, 1, 1, 1, 1, 1)),
+		MPP_VAR_FUNCTION(0x1, "nand", "io1",     V(1, 1, 1, 1, 1, 1))),
 	MPP_MODE(20,
-		MPP_VAR_FUNCTION(0x0, "gpio", NULL,      V(1, 1, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0x1, "ts", "mp0",       V(0, 0, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0x2, "tdm", "tx0ql",    V(0, 0, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0x3, "ge1", "txd0",     V(0, 1, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0x4, "audio", "spdifi", V(0, 0, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0x5, "sata1", "act",    V(0, 0, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0xb, "lcd", "d0",       V(0, 0, 0, 0, 1)),
-		MPP_VAR_FUNCTION(0xc, "mii", "rxerr",    V(1, 0, 0, 0, 0))),
+		MPP_VAR_FUNCTION(0x0, "gpio", NULL,      V(1, 1, 1, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0x1, "ts", "mp0",       V(0, 0, 1, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0x2, "tdm", "tx0ql",    V(0, 0, 1, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0x3, "ge1", "txd0",     V(0, 1, 1, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0x4, "audio", "spdifi", V(0, 0, 1, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0x5, "sata1", "act",    V(0, 0, 1, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0xb, "lcd", "d0",       V(0, 0, 0, 0, 1, 0)),
+		MPP_VAR_FUNCTION(0xc, "mii", "rxerr",    V(1, 0, 0, 0, 0, 0))),
 	MPP_MODE(21,
-		MPP_VAR_FUNCTION(0x0, "gpio", NULL,      V(1, 1, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0x1, "ts", "mp1",       V(0, 0, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0x2, "tdm", "rx0ql",    V(0, 0, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0x3, "ge1", "txd1",     V(0, 1, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0x4, "audio", "spdifi", V(1, 0, 0, 0, 0)),
-		MPP_VAR_FUNCTION(0x4, "audio", "spdifo", V(0, 0, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0x5, "sata0", "act",    V(0, 1, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0xb, "lcd", "d1",       V(0, 0, 0, 0, 1))),
+		MPP_VAR_FUNCTION(0x0, "gpio", NULL,      V(1, 1, 1, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0x1, "ts", "mp1",       V(0, 0, 1, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0x2, "tdm", "rx0ql",    V(0, 0, 1, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0x3, "ge1", "txd1",     V(0, 1, 1, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0x4, "audio", "spdifi", V(1, 0, 0, 0, 0, 0)),
+		MPP_VAR_FUNCTION(0x4, "audio", "spdifo", V(0, 0, 1, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0x5, "sata0", "act",    V(0, 1, 1, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0xb, "lcd", "d1",       V(0, 0, 0, 0, 1, 0))),
 	MPP_MODE(22,
-		MPP_VAR_FUNCTION(0x0, "gpio", NULL,      V(1, 1, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0x1, "ts", "mp2",       V(0, 0, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0x2, "tdm", "tx2ql",    V(0, 0, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0x3, "ge1", "txd2",     V(0, 1, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0x4, "audio", "spdifo", V(1, 0, 0, 0, 0)),
-		MPP_VAR_FUNCTION(0x4, "audio", "rmclk",  V(0, 0, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0x5, "sata1", "prsnt",  V(0, 0, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0xb, "lcd", "d2",       V(0, 0, 0, 0, 1))),
+		MPP_VAR_FUNCTION(0x0, "gpio", NULL,      V(1, 1, 1, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0x1, "ts", "mp2",       V(0, 0, 1, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0x2, "tdm", "tx2ql",    V(0, 0, 1, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0x3, "ge1", "txd2",     V(0, 1, 1, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0x4, "audio", "spdifo", V(1, 0, 0, 0, 0, 0)),
+		MPP_VAR_FUNCTION(0x4, "audio", "rmclk",  V(0, 0, 1, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0x5, "sata1", "prsnt",  V(0, 0, 1, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0xb, "lcd", "d2",       V(0, 0, 0, 0, 1, 0))),
 	MPP_MODE(23,
-		MPP_VAR_FUNCTION(0x0, "gpio", NULL,      V(1, 1, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0x1, "ts", "mp3",       V(0, 0, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0x2, "tdm", "rx2ql",    V(0, 0, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0x3, "ge1", "txd3",     V(0, 1, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0x4, "audio", "rmclk",  V(1, 0, 0, 0, 0)),
-		MPP_VAR_FUNCTION(0x4, "audio", "bclk",   V(0, 0, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0x5, "sata0", "prsnt",  V(0, 1, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0xb, "lcd", "d3",       V(0, 0, 0, 0, 1))),
+		MPP_VAR_FUNCTION(0x0, "gpio", NULL,      V(1, 1, 1, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0x1, "ts", "mp3",       V(0, 0, 1, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0x2, "tdm", "rx2ql",    V(0, 0, 1, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0x3, "ge1", "txd3",     V(0, 1, 1, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0x4, "audio", "rmclk",  V(1, 0, 0, 0, 0, 0)),
+		MPP_VAR_FUNCTION(0x4, "audio", "bclk",   V(0, 0, 1, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0x5, "sata0", "prsnt",  V(0, 1, 1, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0xb, "lcd", "d3",       V(0, 0, 0, 0, 1, 0))),
 	MPP_MODE(24,
-		MPP_VAR_FUNCTION(0x0, "gpio", NULL,      V(1, 1, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0x1, "ts", "mp4",       V(0, 0, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0x2, "tdm", "spi-cs0",  V(0, 0, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0x3, "ge1", "rxd0",     V(0, 1, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0x4, "audio", "bclk",   V(1, 0, 0, 0, 0)),
-		MPP_VAR_FUNCTION(0x4, "audio", "sdo",    V(0, 0, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0xb, "lcd", "d4",       V(0, 0, 0, 0, 1))),
+		MPP_VAR_FUNCTION(0x0, "gpio", NULL,      V(1, 1, 1, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0x1, "ts", "mp4",       V(0, 0, 1, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0x2, "tdm", "spi-cs0",  V(0, 0, 1, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0x3, "ge1", "rxd0",     V(0, 1, 1, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0x4, "audio", "bclk",   V(1, 0, 0, 0, 0, 0)),
+		MPP_VAR_FUNCTION(0x4, "audio", "sdo",    V(0, 0, 1, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0xb, "lcd", "d4",       V(0, 0, 0, 0, 1, 0))),
 	MPP_MODE(25,
-		MPP_VAR_FUNCTION(0x0, "gpio", NULL,      V(1, 1, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0x1, "ts", "mp5",       V(0, 0, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0x2, "tdm", "spi-sck",  V(0, 0, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0x3, "ge1", "rxd1",     V(0, 1, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0x4, "audio", "sdo",    V(1, 0, 0, 0, 0)),
-		MPP_VAR_FUNCTION(0x4, "audio", "lrclk",  V(0, 0, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0xb, "lcd", "d5",       V(0, 0, 0, 0, 1))),
+		MPP_VAR_FUNCTION(0x0, "gpio", NULL,      V(1, 1, 1, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0x1, "ts", "mp5",       V(0, 0, 1, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0x2, "tdm", "spi-sck",  V(0, 0, 1, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0x3, "ge1", "rxd1",     V(0, 1, 1, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0x4, "audio", "sdo",    V(1, 0, 0, 0, 0, 0)),
+		MPP_VAR_FUNCTION(0x4, "audio", "lrclk",  V(0, 0, 1, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0xb, "lcd", "d5",       V(0, 0, 0, 0, 1, 0))),
 	MPP_MODE(26,
-		MPP_VAR_FUNCTION(0x0, "gpio", NULL,      V(1, 1, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0x1, "ts", "mp6",       V(0, 0, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0x2, "tdm", "spi-miso", V(0, 0, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0x3, "ge1", "rxd2",     V(0, 1, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0x4, "audio", "lrclk",  V(1, 0, 0, 0, 0)),
-		MPP_VAR_FUNCTION(0x4, "audio", "mclk",   V(0, 0, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0xb, "lcd", "d6",       V(0, 0, 0, 0, 1))),
+		MPP_VAR_FUNCTION(0x0, "gpio", NULL,      V(1, 1, 1, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0x1, "ts", "mp6",       V(0, 0, 1, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0x2, "tdm", "spi-miso", V(0, 0, 1, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0x3, "ge1", "rxd2",     V(0, 1, 1, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0x4, "audio", "lrclk",  V(1, 0, 0, 0, 0, 0)),
+		MPP_VAR_FUNCTION(0x4, "audio", "mclk",   V(0, 0, 1, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0xb, "lcd", "d6",       V(0, 0, 0, 0, 1, 0))),
 	MPP_MODE(27,
-		MPP_VAR_FUNCTION(0x0, "gpio", NULL,      V(1, 1, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0x1, "ts", "mp7",       V(0, 0, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0x2, "tdm", "spi-mosi", V(0, 0, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0x3, "ge1", "rxd3",     V(0, 1, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0x4, "audio", "mclk",   V(1, 0, 0, 0, 0)),
-		MPP_VAR_FUNCTION(0x4, "audio", "sdi",    V(0, 0, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0xb, "lcd", "d7",       V(0, 0, 0, 0, 1))),
+		MPP_VAR_FUNCTION(0x0, "gpio", NULL,      V(1, 1, 1, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0x1, "ts", "mp7",       V(0, 0, 1, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0x2, "tdm", "spi-mosi", V(0, 0, 1, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0x3, "ge1", "rxd3",     V(0, 1, 1, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0x4, "audio", "mclk",   V(1, 0, 0, 0, 0, 0)),
+		MPP_VAR_FUNCTION(0x4, "audio", "sdi",    V(0, 0, 1, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0xb, "lcd", "d7",       V(0, 0, 0, 0, 1, 0))),
 	MPP_MODE(28,
-		MPP_VAR_FUNCTION(0x0, "gpio", NULL,      V(1, 1, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0x1, "ts", "mp8",       V(0, 0, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0x2, "tdm", "int",      V(0, 0, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0x3, "ge1", "col",      V(0, 1, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0x4, "audio", "sdi",    V(1, 0, 0, 0, 0)),
-		MPP_VAR_FUNCTION(0x4, "audio", "extclk", V(0, 0, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0xb, "lcd", "d8",       V(0, 0, 0, 0, 1))),
+		MPP_VAR_FUNCTION(0x0, "gpio", NULL,      V(1, 1, 1, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0x1, "ts", "mp8",       V(0, 0, 1, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0x2, "tdm", "int",      V(0, 0, 1, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0x3, "ge1", "col",      V(0, 1, 1, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0x4, "audio", "sdi",    V(1, 0, 0, 0, 0, 0)),
+		MPP_VAR_FUNCTION(0x4, "audio", "extclk", V(0, 0, 1, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0xb, "lcd", "d8",       V(0, 0, 0, 0, 1, 0))),
 	MPP_MODE(29,
-		MPP_VAR_FUNCTION(0x0, "gpio", NULL,      V(1, 1, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0x1, "ts", "mp9",       V(0, 0, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0x2, "tdm", "rst",      V(0, 0, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0x3, "ge1", "txclk",    V(0, 1, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0x4, "audio", "extclk", V(1, 0, 0, 0, 0)),
-		MPP_VAR_FUNCTION(0xb, "lcd", "d9",       V(0, 0, 0, 0, 1))),
+		MPP_VAR_FUNCTION(0x0, "gpio", NULL,      V(1, 1, 1, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0x1, "ts", "mp9",       V(0, 0, 1, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0x2, "tdm", "rst",      V(0, 0, 1, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0x3, "ge1", "txclk",    V(0, 1, 1, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0x4, "audio", "extclk", V(1, 0, 0, 0, 0, 0)),
+		MPP_VAR_FUNCTION(0xb, "lcd", "d9",       V(0, 0, 0, 0, 1, 0))),
 	MPP_MODE(30,
-		MPP_VAR_FUNCTION(0x0, "gpio", NULL,      V(0, 1, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0x1, "ts", "mp10",      V(0, 0, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0x2, "tdm", "pclk",     V(0, 0, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0x3, "ge1", "rxctl",    V(0, 1, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0xb, "lcd", "d10",      V(0, 0, 0, 0, 1))),
+		MPP_VAR_FUNCTION(0x0, "gpio", NULL,      V(0, 1, 1, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0x1, "ts", "mp10",      V(0, 0, 1, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0x2, "tdm", "pclk",     V(0, 0, 1, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0x3, "ge1", "rxctl",    V(0, 1, 1, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0xb, "lcd", "d10",      V(0, 0, 0, 0, 1, 0))),
 	MPP_MODE(31,
-		MPP_VAR_FUNCTION(0x0, "gpio", NULL,      V(0, 1, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0x1, "ts", "mp11",      V(0, 0, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0x2, "tdm", "fs",       V(0, 0, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0x3, "ge1", "rxclk",    V(0, 1, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0xb, "lcd", "d11",      V(0, 0, 0, 0, 1))),
+		MPP_VAR_FUNCTION(0x0, "gpio", NULL,      V(0, 1, 1, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0x1, "ts", "mp11",      V(0, 0, 1, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0x2, "tdm", "fs",       V(0, 0, 1, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0x3, "ge1", "rxclk",    V(0, 1, 1, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0xb, "lcd", "d11",      V(0, 0, 0, 0, 1, 0))),
 	MPP_MODE(32,
-		MPP_VAR_FUNCTION(0x0, "gpio", NULL,      V(0, 1, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0x1, "ts", "mp12",      V(0, 0, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0x2, "tdm", "drx",      V(0, 0, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0x3, "ge1", "txclko",   V(0, 1, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0xb, "lcd", "d12",      V(0, 0, 0, 0, 1))),
+		MPP_VAR_FUNCTION(0x0, "gpio", NULL,      V(0, 1, 1, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0x1, "ts", "mp12",      V(0, 0, 1, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0x2, "tdm", "drx",      V(0, 0, 1, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0x3, "ge1", "txclko",   V(0, 1, 1, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0xb, "lcd", "d12",      V(0, 0, 0, 0, 1, 0))),
 	MPP_MODE(33,
-		MPP_VAR_FUNCTION(0x0, "gpo", NULL,       V(0, 1, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0x2, "tdm", "dtx",      V(0, 0, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0x3, "ge1", "txctl",    V(0, 1, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0xb, "lcd", "d13",      V(0, 0, 0, 0, 1))),
+		MPP_VAR_FUNCTION(0x0, "gpo", NULL,       V(0, 1, 1, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0x2, "tdm", "dtx",      V(0, 0, 1, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0x3, "ge1", "txctl",    V(0, 1, 1, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0xb, "lcd", "d13",      V(0, 0, 0, 0, 1, 0))),
 	MPP_MODE(34,
-		MPP_VAR_FUNCTION(0x0, "gpio", NULL,      V(0, 1, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0x2, "tdm", "spi-cs1",  V(0, 0, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0x3, "ge1", "txen",     V(0, 1, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0x5, "sata1", "act",    V(0, 0, 0, 1, 1)),
-		MPP_VAR_FUNCTION(0xb, "lcd", "d14",      V(0, 0, 0, 0, 1))),
+		MPP_VAR_FUNCTION(0x0, "gpio", NULL,      V(0, 1, 1, 1, 1, 1)),
+		MPP_VAR_FUNCTION(0x2, "tdm", "spi-cs1",  V(0, 0, 1, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0x3, "ge1", "txen",     V(0, 1, 1, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0x5, "sata1", "act",    V(0, 0, 0, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0xb, "lcd", "d14",      V(0, 0, 0, 0, 1, 0))),
 	MPP_MODE(35,
-		MPP_VAR_FUNCTION(0x0, "gpio", NULL,      V(0, 1, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0x2, "tdm", "tx0ql",    V(0, 0, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0x3, "ge1", "rxerr",    V(0, 1, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0x5, "sata0", "act",    V(0, 1, 1, 1, 1)),
-		MPP_VAR_FUNCTION(0xb, "lcd", "d15",      V(0, 0, 0, 0, 1)),
-		MPP_VAR_FUNCTION(0xc, "mii", "rxerr",    V(0, 1, 1, 1, 1))),
+		MPP_VAR_FUNCTION(0x0, "gpio", NULL,      V(0, 1, 1, 1, 1, 1)),
+		MPP_VAR_FUNCTION(0x2, "tdm", "tx0ql",    V(0, 0, 1, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0x3, "ge1", "rxerr",    V(0, 1, 1, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0x5, "sata0", "act",    V(0, 1, 1, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0xb, "lcd", "d15",      V(0, 0, 0, 0, 1, 0)),
+		MPP_VAR_FUNCTION(0xc, "mii", "rxerr",    V(0, 1, 1, 1, 1, 0))),
 	MPP_MODE(36,
-		MPP_VAR_FUNCTION(0x0, "gpio", NULL,      V(0, 0, 0, 1, 1)),
-		MPP_VAR_FUNCTION(0x1, "ts", "mp0",       V(0, 0, 0, 1, 1)),
-		MPP_VAR_FUNCTION(0x2, "tdm", "spi-cs1",  V(0, 0, 0, 1, 1)),
-		MPP_VAR_FUNCTION(0x4, "audio", "spdifi", V(0, 0, 0, 1, 1)),
-		MPP_VAR_FUNCTION(0xb, "twsi1", "sda",    V(0, 0, 0, 0, 1))),
+		MPP_VAR_FUNCTION(0x0, "gpio", NULL,      V(0, 0, 0, 1, 1, 1)),
+		MPP_VAR_FUNCTION(0x1, "ts", "mp0",       V(0, 0, 0, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0x2, "tdm", "spi-cs1",  V(0, 0, 0, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0x4, "audio", "spdifi", V(0, 0, 0, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0xb, "twsi1", "sda",    V(0, 0, 0, 0, 1, 0))),
 	MPP_MODE(37,
-		MPP_VAR_FUNCTION(0x0, "gpio", NULL,      V(0, 0, 0, 1, 1)),
-		MPP_VAR_FUNCTION(0x1, "ts", "mp1",       V(0, 0, 0, 1, 1)),
-		MPP_VAR_FUNCTION(0x2, "tdm", "tx2ql",    V(0, 0, 0, 1, 1)),
-		MPP_VAR_FUNCTION(0x4, "audio", "spdifo", V(0, 0, 0, 1, 1)),
-		MPP_VAR_FUNCTION(0xb, "twsi1", "sck",    V(0, 0, 0, 0, 1))),
+		MPP_VAR_FUNCTION(0x0, "gpio", NULL,      V(0, 0, 0, 1, 1, 1)),
+		MPP_VAR_FUNCTION(0x1, "ts", "mp1",       V(0, 0, 0, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0x2, "tdm", "tx2ql",    V(0, 0, 0, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0x4, "audio", "spdifo", V(0, 0, 0, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0xb, "twsi1", "sck",    V(0, 0, 0, 0, 1, 0))),
 	MPP_MODE(38,
-		MPP_VAR_FUNCTION(0x0, "gpio", NULL,      V(0, 0, 0, 1, 1)),
-		MPP_VAR_FUNCTION(0x1, "ts", "mp2",       V(0, 0, 0, 1, 1)),
-		MPP_VAR_FUNCTION(0x2, "tdm", "rx2ql",    V(0, 0, 0, 1, 1)),
-		MPP_VAR_FUNCTION(0x4, "audio", "rmclk",  V(0, 0, 0, 1, 1)),
-		MPP_VAR_FUNCTION(0xb, "lcd", "d18",      V(0, 0, 0, 0, 1))),
+		MPP_VAR_FUNCTION(0x0, "gpio", NULL,      V(0, 0, 0, 1, 1, 1)),
+		MPP_VAR_FUNCTION(0x1, "ts", "mp2",       V(0, 0, 0, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0x2, "tdm", "rx2ql",    V(0, 0, 0, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0x4, "audio", "rmclk",  V(0, 0, 0, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0xb, "lcd", "d18",      V(0, 0, 0, 0, 1, 0))),
 	MPP_MODE(39,
-		MPP_VAR_FUNCTION(0x0, "gpio", NULL,      V(0, 0, 0, 1, 1)),
-		MPP_VAR_FUNCTION(0x1, "ts", "mp3",       V(0, 0, 0, 1, 1)),
-		MPP_VAR_FUNCTION(0x2, "tdm", "spi-cs0",  V(0, 0, 0, 1, 1)),
-		MPP_VAR_FUNCTION(0x4, "audio", "bclk",   V(0, 0, 0, 1, 1)),
-		MPP_VAR_FUNCTION(0xb, "lcd", "d19",      V(0, 0, 0, 0, 1))),
+		MPP_VAR_FUNCTION(0x0, "gpio", NULL,      V(0, 0, 0, 1, 1, 1)),
+		MPP_VAR_FUNCTION(0x1, "ts", "mp3",       V(0, 0, 0, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0x2, "tdm", "spi-cs0",  V(0, 0, 0, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0x4, "audio", "bclk",   V(0, 0, 0, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0xb, "lcd", "d19",      V(0, 0, 0, 0, 1, 0))),
 	MPP_MODE(40,
-		MPP_VAR_FUNCTION(0x0, "gpio", NULL,      V(0, 0, 0, 1, 1)),
-		MPP_VAR_FUNCTION(0x1, "ts", "mp4",       V(0, 0, 0, 1, 1)),
-		MPP_VAR_FUNCTION(0x2, "tdm", "spi-sck",  V(0, 0, 0, 1, 1)),
-		MPP_VAR_FUNCTION(0x4, "audio", "sdo",    V(0, 0, 0, 1, 1)),
-		MPP_VAR_FUNCTION(0xb, "lcd", "d20",      V(0, 0, 0, 0, 1))),
+		MPP_VAR_FUNCTION(0x0, "gpio", NULL,      V(0, 0, 0, 1, 1, 1)),
+		MPP_VAR_FUNCTION(0x1, "ts", "mp4",       V(0, 0, 0, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0x2, "tdm", "spi-sck",  V(0, 0, 0, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0x4, "audio", "sdo",    V(0, 0, 0, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0xb, "lcd", "d20",      V(0, 0, 0, 0, 1, 0))),
 	MPP_MODE(41,
-		MPP_VAR_FUNCTION(0x0, "gpio", NULL,      V(0, 0, 0, 1, 1)),
-		MPP_VAR_FUNCTION(0x1, "ts", "mp5",       V(0, 0, 0, 1, 1)),
-		MPP_VAR_FUNCTION(0x2, "tdm", "spi-miso", V(0, 0, 0, 1, 1)),
-		MPP_VAR_FUNCTION(0x4, "audio", "lrclk",  V(0, 0, 0, 1, 1)),
-		MPP_VAR_FUNCTION(0xb, "lcd", "d21",      V(0, 0, 0, 0, 1))),
+		MPP_VAR_FUNCTION(0x0, "gpio", NULL,      V(0, 0, 0, 1, 1, 1)),
+		MPP_VAR_FUNCTION(0x1, "ts", "mp5",       V(0, 0, 0, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0x2, "tdm", "spi-miso", V(0, 0, 0, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0x4, "audio", "lrclk",  V(0, 0, 0, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0xb, "lcd", "d21",      V(0, 0, 0, 0, 1, 0))),
 	MPP_MODE(42,
-		MPP_VAR_FUNCTION(0x0, "gpio", NULL,      V(0, 0, 0, 1, 1)),
-		MPP_VAR_FUNCTION(0x1, "ts", "mp6",       V(0, 0, 0, 1, 1)),
-		MPP_VAR_FUNCTION(0x2, "tdm", "spi-mosi", V(0, 0, 0, 1, 1)),
-		MPP_VAR_FUNCTION(0x4, "audio", "mclk",   V(0, 0, 0, 1, 1)),
-		MPP_VAR_FUNCTION(0xb, "lcd", "d22",      V(0, 0, 0, 0, 1))),
+		MPP_VAR_FUNCTION(0x0, "gpio", NULL,      V(0, 0, 0, 1, 1, 1)),
+		MPP_VAR_FUNCTION(0x1, "ts", "mp6",       V(0, 0, 0, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0x2, "tdm", "spi-mosi", V(0, 0, 0, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0x4, "audio", "mclk",   V(0, 0, 0, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0xb, "lcd", "d22",      V(0, 0, 0, 0, 1, 0))),
 	MPP_MODE(43,
-		MPP_VAR_FUNCTION(0x0, "gpio", NULL,      V(0, 0, 0, 1, 1)),
-		MPP_VAR_FUNCTION(0x1, "ts", "mp7",       V(0, 0, 0, 1, 1)),
-		MPP_VAR_FUNCTION(0x2, "tdm", "int",      V(0, 0, 0, 1, 1)),
-		MPP_VAR_FUNCTION(0x4, "audio", "sdi",    V(0, 0, 0, 1, 1)),
-		MPP_VAR_FUNCTION(0xb, "lcd", "d23",      V(0, 0, 0, 0, 1))),
+		MPP_VAR_FUNCTION(0x0, "gpio", NULL,      V(0, 0, 0, 1, 1, 1)),
+		MPP_VAR_FUNCTION(0x1, "ts", "mp7",       V(0, 0, 0, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0x2, "tdm", "int",      V(0, 0, 0, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0x4, "audio", "sdi",    V(0, 0, 0, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0xb, "lcd", "d23",      V(0, 0, 0, 0, 1, 0))),
 	MPP_MODE(44,
-		MPP_VAR_FUNCTION(0x0, "gpio", NULL,      V(0, 0, 0, 1, 1)),
-		MPP_VAR_FUNCTION(0x1, "ts", "mp8",       V(0, 0, 0, 1, 1)),
-		MPP_VAR_FUNCTION(0x2, "tdm", "rst",      V(0, 0, 0, 1, 1)),
-		MPP_VAR_FUNCTION(0x4, "audio", "extclk", V(0, 0, 0, 1, 1)),
-		MPP_VAR_FUNCTION(0xb, "lcd", "clk",      V(0, 0, 0, 0, 1))),
+		MPP_VAR_FUNCTION(0x0, "gpio", NULL,      V(0, 0, 0, 1, 1, 1)),
+		MPP_VAR_FUNCTION(0x1, "ts", "mp8",       V(0, 0, 0, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0x2, "tdm", "rst",      V(0, 0, 0, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0x4, "audio", "extclk", V(0, 0, 0, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0xb, "lcd", "clk",      V(0, 0, 0, 0, 1, 0))),
 	MPP_MODE(45,
-		MPP_VAR_FUNCTION(0x0, "gpio", NULL,      V(0, 0, 0, 1, 1)),
-		MPP_VAR_FUNCTION(0x1, "ts", "mp9",       V(0, 0, 0, 1, 1)),
-		MPP_VAR_FUNCTION(0x2, "tdm", "pclk",     V(0, 0, 0, 1, 1)),
-		MPP_VAR_FUNCTION(0xb, "lcd", "e",        V(0, 0, 0, 0, 1))),
+		MPP_VAR_FUNCTION(0x0, "gpio", NULL,      V(0, 0, 0, 1, 1, 1)),
+		MPP_VAR_FUNCTION(0x1, "ts", "mp9",       V(0, 0, 0, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0x2, "tdm", "pclk",     V(0, 0, 0, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0xb, "lcd", "e",        V(0, 0, 0, 0, 1, 0))),
 	MPP_MODE(46,
-		MPP_VAR_FUNCTION(0x0, "gpio", NULL,      V(0, 0, 0, 1, 1)),
-		MPP_VAR_FUNCTION(0x1, "ts", "mp10",      V(0, 0, 0, 1, 1)),
-		MPP_VAR_FUNCTION(0x2, "tdm", "fs",       V(0, 0, 0, 1, 1)),
-		MPP_VAR_FUNCTION(0xb, "lcd", "hsync",    V(0, 0, 0, 0, 1))),
+		MPP_VAR_FUNCTION(0x0, "gpio", NULL,      V(0, 0, 0, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0x1, "ts", "mp10",      V(0, 0, 0, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0x2, "tdm", "fs",       V(0, 0, 0, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0xb, "lcd", "hsync",    V(0, 0, 0, 0, 1, 0))),
 	MPP_MODE(47,
-		MPP_VAR_FUNCTION(0x0, "gpio", NULL,      V(0, 0, 0, 1, 1)),
-		MPP_VAR_FUNCTION(0x1, "ts", "mp11",      V(0, 0, 0, 1, 1)),
-		MPP_VAR_FUNCTION(0x2, "tdm", "drx",      V(0, 0, 0, 1, 1)),
-		MPP_VAR_FUNCTION(0xb, "lcd", "vsync",    V(0, 0, 0, 0, 1))),
+		MPP_VAR_FUNCTION(0x0, "gpio", NULL,      V(0, 0, 0, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0x1, "ts", "mp11",      V(0, 0, 0, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0x2, "tdm", "drx",      V(0, 0, 0, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0xb, "lcd", "vsync",    V(0, 0, 0, 0, 1, 0))),
 	MPP_MODE(48,
-		MPP_VAR_FUNCTION(0x0, "gpio", NULL,      V(0, 0, 0, 1, 1)),
-		MPP_VAR_FUNCTION(0x1, "ts", "mp12",      V(0, 0, 0, 1, 1)),
-		MPP_VAR_FUNCTION(0x2, "tdm", "dtx",      V(0, 0, 0, 1, 1)),
-		MPP_VAR_FUNCTION(0xb, "lcd", "d16",      V(0, 0, 0, 0, 1))),
+		MPP_VAR_FUNCTION(0x0, "gpio", NULL,      V(0, 0, 0, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0x1, "ts", "mp12",      V(0, 0, 0, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0x2, "tdm", "dtx",      V(0, 0, 0, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0xb, "lcd", "d16",      V(0, 0, 0, 0, 1, 0))),
 	MPP_MODE(49,
-		MPP_VAR_FUNCTION(0x0, "gpio", NULL,      V(0, 0, 0, 1, 0)),
-		MPP_VAR_FUNCTION(0x0, "gpo", NULL,       V(0, 0, 0, 0, 1)),
-		MPP_VAR_FUNCTION(0x1, "ts", "mp9",       V(0, 0, 0, 1, 0)),
-		MPP_VAR_FUNCTION(0x2, "tdm", "rx0ql",    V(0, 0, 0, 1, 1)),
-		MPP_VAR_FUNCTION(0x5, "ptp", "clk",      V(0, 0, 0, 1, 0)),
-		MPP_VAR_FUNCTION(0xa, "pex", "clkreq",   V(0, 0, 0, 0, 1)),
-		MPP_VAR_FUNCTION(0xb, "lcd", "d17",      V(0, 0, 0, 0, 1))),
+		MPP_VAR_FUNCTION(0x0, "gpio", NULL,      V(0, 0, 0, 1, 0, 1)),
+		MPP_VAR_FUNCTION(0x0, "gpo", NULL,       V(0, 0, 0, 0, 1, 0)),
+		MPP_VAR_FUNCTION(0x1, "ts", "mp9",       V(0, 0, 0, 1, 0, 0)),
+		MPP_VAR_FUNCTION(0x2, "tdm", "rx0ql",    V(0, 0, 0, 1, 1, 0)),
+		MPP_VAR_FUNCTION(0x5, "ptp", "clk",      V(0, 0, 0, 1, 0, 0)),
+		MPP_VAR_FUNCTION(0xa, "pex", "clkreq",   V(0, 0, 0, 0, 1, 0)),
+		MPP_VAR_FUNCTION(0xb, "lcd", "d17",      V(0, 0, 0, 0, 1, 0))),
 };
 
 static struct mvebu_mpp_ctrl mv88f6180_mpp_controls[] = {
@@ -433,12 +434,23 @@
 	.ngpioranges = ARRAY_SIZE(mv88f628x_gpio_ranges),
 };
 
+static struct mvebu_pinctrl_soc_info mv98dx4122_info = {
+	.variant = VARIANT_MV98DX4122,
+	.controls = mv88f628x_mpp_controls,
+	.ncontrols = ARRAY_SIZE(mv88f628x_mpp_controls),
+	.modes = mv88f6xxx_mpp_modes,
+	.nmodes = ARRAY_SIZE(mv88f6xxx_mpp_modes),
+	.gpioranges = mv88f628x_gpio_ranges,
+	.ngpioranges = ARRAY_SIZE(mv88f628x_gpio_ranges),
+};
+
 static struct of_device_id kirkwood_pinctrl_of_match[] __devinitdata = {
 	{ .compatible = "marvell,88f6180-pinctrl", .data = &mv88f6180_info },
 	{ .compatible = "marvell,88f6190-pinctrl", .data = &mv88f6190_info },
 	{ .compatible = "marvell,88f6192-pinctrl", .data = &mv88f6192_info },
 	{ .compatible = "marvell,88f6281-pinctrl", .data = &mv88f6281_info },
 	{ .compatible = "marvell,88f6282-pinctrl", .data = &mv88f6282_info },
+	{ .compatible = "marvell,98dx4122-pinctrl", .data = &mv98dx4122_info },
 	{ }
 };
 
diff --git a/drivers/pinctrl/pinctrl-nomadik.c b/drivers/pinctrl/pinctrl-nomadik.c
index 8ef3e85..ef66f98 100644
--- a/drivers/pinctrl/pinctrl-nomadik.c
+++ b/drivers/pinctrl/pinctrl-nomadik.c
@@ -31,9 +31,8 @@
 /* Since we request GPIOs from ourself */
 #include <linux/pinctrl/consumer.h>
 #include <linux/platform_data/pinctrl-nomadik.h>
-
 #include <asm/mach/irq.h>
-
+#include <mach/irqs.h>
 #include "pinctrl-nomadik.h"
 
 /*
diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig
index 49a8939..b1d956d 100644
--- a/drivers/power/Kconfig
+++ b/drivers/power/Kconfig
@@ -335,6 +335,9 @@
 	help
 	  Say Y to enable battery temperature measurements using
 	  thermistor connected on BATCTRL ADC.
+
+source "drivers/power/reset/Kconfig"
+
 endif # POWER_SUPPLY
 
 source "drivers/power/avs/Kconfig"
diff --git a/drivers/power/Makefile b/drivers/power/Makefile
index b949cf8..f1d99f4 100644
--- a/drivers/power/Makefile
+++ b/drivers/power/Makefile
@@ -49,3 +49,4 @@
 obj-$(CONFIG_CHARGER_MAX8998)	+= max8998_charger.o
 obj-$(CONFIG_POWER_AVS)		+= avs/
 obj-$(CONFIG_CHARGER_SMB347)	+= smb347-charger.o
+obj-$(CONFIG_POWER_RESET)	+= reset/
diff --git a/drivers/power/avs/smartreflex.c b/drivers/power/avs/smartreflex.c
index d0fed2c..a17d084 100644
--- a/drivers/power/avs/smartreflex.c
+++ b/drivers/power/avs/smartreflex.c
@@ -130,24 +130,21 @@
 
 static void sr_set_clk_length(struct omap_sr *sr)
 {
-	struct clk *sys_ck;
-	u32 sys_clk_speed;
+	struct clk *fck;
+	u32 fclk_speed;
 
-	if (cpu_is_omap34xx())
-		sys_ck = clk_get(NULL, "sys_ck");
-	else
-		sys_ck = clk_get(NULL, "sys_clkin_ck");
+	fck = clk_get(&sr->pdev->dev, "fck");
 
-	if (IS_ERR(sys_ck)) {
-		dev_err(&sr->pdev->dev, "%s: unable to get sys clk\n",
-			__func__);
+	if (IS_ERR(fck)) {
+		dev_err(&sr->pdev->dev, "%s: unable to get fck for device %s\n",
+				__func__, dev_name(&sr->pdev->dev));
 		return;
 	}
 
-	sys_clk_speed = clk_get_rate(sys_ck);
-	clk_put(sys_ck);
+	fclk_speed = clk_get_rate(fck);
+	clk_put(fck);
 
-	switch (sys_clk_speed) {
+	switch (fclk_speed) {
 	case 12000000:
 		sr->clk_length = SRCLKLENGTH_12MHZ_SYSCLK;
 		break;
@@ -164,34 +161,12 @@
 		sr->clk_length = SRCLKLENGTH_38MHZ_SYSCLK;
 		break;
 	default:
-		dev_err(&sr->pdev->dev, "%s: Invalid sysclk value: %d\n",
-			__func__, sys_clk_speed);
+		dev_err(&sr->pdev->dev, "%s: Invalid fclk rate: %d\n",
+			__func__, fclk_speed);
 		break;
 	}
 }
 
-static void sr_set_regfields(struct omap_sr *sr)
-{
-	/*
-	 * For time being these values are defined in smartreflex.h
-	 * and populated during init. May be they can be moved to board
-	 * file or pmic specific data structure. In that case these structure
-	 * fields will have to be populated using the pdata or pmic structure.
-	 */
-	if (cpu_is_omap34xx() || cpu_is_omap44xx()) {
-		sr->err_weight = OMAP3430_SR_ERRWEIGHT;
-		sr->err_maxlimit = OMAP3430_SR_ERRMAXLIMIT;
-		sr->accum_data = OMAP3430_SR_ACCUMDATA;
-		if (!(strcmp(sr->name, "smartreflex_mpu_iva"))) {
-			sr->senn_avgweight = OMAP3430_SR1_SENNAVGWEIGHT;
-			sr->senp_avgweight = OMAP3430_SR1_SENPAVGWEIGHT;
-		} else {
-			sr->senn_avgweight = OMAP3430_SR2_SENNAVGWEIGHT;
-			sr->senp_avgweight = OMAP3430_SR2_SENPAVGWEIGHT;
-		}
-	}
-}
-
 static void sr_start_vddautocomp(struct omap_sr *sr)
 {
 	if (!sr_class || !(sr_class->enable) || !(sr_class->configure)) {
@@ -924,8 +899,14 @@
 	sr_info->nvalue_count = pdata->nvalue_count;
 	sr_info->senn_mod = pdata->senn_mod;
 	sr_info->senp_mod = pdata->senp_mod;
+	sr_info->err_weight = pdata->err_weight;
+	sr_info->err_maxlimit = pdata->err_maxlimit;
+	sr_info->accum_data = pdata->accum_data;
+	sr_info->senn_avgweight = pdata->senn_avgweight;
+	sr_info->senp_avgweight = pdata->senp_avgweight;
 	sr_info->autocomp_active = false;
 	sr_info->ip_type = pdata->ip_type;
+
 	sr_info->base = ioremap(mem->start, resource_size(mem));
 	if (!sr_info->base) {
 		dev_err(&pdev->dev, "%s: ioremap fail\n", __func__);
@@ -937,7 +918,6 @@
 		sr_info->irq = irq->start;
 
 	sr_set_clk_length(sr_info);
-	sr_set_regfields(sr_info);
 
 	list_add(&sr_info->node, &sr_list);
 
diff --git a/drivers/power/reset/Kconfig b/drivers/power/reset/Kconfig
new file mode 100644
index 0000000..6461b48
--- /dev/null
+++ b/drivers/power/reset/Kconfig
@@ -0,0 +1,15 @@
+menuconfig POWER_RESET
+	bool "Board level reset or power off"
+	help
+	  Provides a number of drivers which either reset a complete board
+	  or shut it down, by manipulating the main power supply on the board.
+
+	  Say Y here to enable board reset and power off
+
+config POWER_RESET_GPIO
+	bool "GPIO power-off driver"
+	depends on OF_GPIO && POWER_RESET
+	help
+	  This driver supports turning off your board via a GPIO line.
+	  If your board needs a GPIO high/low to power down, say Y and
+	  create a binding in your devicetree.
diff --git a/drivers/power/reset/Makefile b/drivers/power/reset/Makefile
new file mode 100644
index 0000000..751488a
--- /dev/null
+++ b/drivers/power/reset/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_POWER_RESET_GPIO) += gpio-poweroff.o
diff --git a/drivers/power/reset/gpio-poweroff.c b/drivers/power/reset/gpio-poweroff.c
new file mode 100644
index 0000000..0491e53
--- /dev/null
+++ b/drivers/power/reset/gpio-poweroff.c
@@ -0,0 +1,129 @@
+/*
+ * Toggles a GPIO pin to power down a device
+ *
+ * Jamie Lentin <jm@lentin.co.uk>
+ * Andrew Lunn <andrew@lunn.ch>
+ *
+ * Copyright (C) 2012 Jamie Lentin
+ *
+ * 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/delay.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/of_platform.h>
+#include <linux/of_gpio.h>
+#include <linux/module.h>
+
+/*
+ * Hold configuration here, cannot be more than one instance of the driver
+ * since pm_power_off itself is global.
+ */
+static int gpio_num = -1;
+static int gpio_active_low;
+
+static void gpio_poweroff_do_poweroff(void)
+{
+	BUG_ON(gpio_num == -1);
+
+	/* drive it active */
+	gpio_direction_output(gpio_num, !gpio_active_low);
+	mdelay(100);
+	/* rising edge or drive inactive */
+	gpio_set_value(gpio_num, gpio_active_low);
+	mdelay(100);
+	/* falling edge */
+	gpio_set_value(gpio_num, !gpio_active_low);
+
+	/* give it some time */
+	mdelay(3000);
+
+	WARN_ON(1);
+}
+
+static int __devinit gpio_poweroff_probe(struct platform_device *pdev)
+{
+	enum of_gpio_flags flags;
+	bool input = false;
+	int ret;
+
+	/* If a pm_power_off function has already been added, leave it alone */
+	if (pm_power_off != NULL) {
+		pr_err("%s: pm_power_off function already registered",
+		       __func__);
+		return -EBUSY;
+	}
+
+	gpio_num = of_get_gpio_flags(pdev->dev.of_node, 0, &flags);
+	if (gpio_num < 0) {
+		pr_err("%s: Could not get GPIO configuration: %d",
+		       __func__, gpio_num);
+		return -ENODEV;
+	}
+	gpio_active_low = flags & OF_GPIO_ACTIVE_LOW;
+
+	if (of_get_property(pdev->dev.of_node, "input", NULL))
+		input = true;
+
+	ret = gpio_request(gpio_num, "poweroff-gpio");
+	if (ret) {
+		pr_err("%s: Could not get GPIO %d", __func__, gpio_num);
+		return ret;
+	}
+	if (input) {
+		if (gpio_direction_input(gpio_num)) {
+			pr_err("Could not set direction of GPIO %d to input",
+			       gpio_num);
+			goto err;
+		}
+	} else {
+		if (gpio_direction_output(gpio_num, gpio_active_low)) {
+			pr_err("Could not set direction of GPIO %d", gpio_num);
+			goto err;
+		}
+	}
+
+	pm_power_off = &gpio_poweroff_do_poweroff;
+	return 0;
+
+err:
+	gpio_free(gpio_num);
+	return -ENODEV;
+}
+
+static int __devexit gpio_poweroff_remove(struct platform_device *pdev)
+{
+	if (gpio_num != -1)
+		gpio_free(gpio_num);
+	if (pm_power_off == &gpio_poweroff_do_poweroff)
+		pm_power_off = NULL;
+
+	return 0;
+}
+
+static const struct of_device_id of_gpio_poweroff_match[] = {
+	{ .compatible = "gpio-poweroff", },
+	{},
+};
+
+static struct platform_driver gpio_poweroff_driver = {
+	.probe = gpio_poweroff_probe,
+	.remove = __devexit_p(gpio_poweroff_remove),
+	.driver = {
+		   .name = "poweroff-gpio",
+		   .owner = THIS_MODULE,
+		   .of_match_table = of_gpio_poweroff_match,
+		   },
+};
+
+module_platform_driver(gpio_poweroff_driver);
+
+MODULE_AUTHOR("Jamie Lentin <jm@lentin.co.uk>");
+MODULE_DESCRIPTION("GPIO poweroff driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:poweroff-gpio");
diff --git a/drivers/regulator/88pm8607.c b/drivers/regulator/88pm8607.c
index 1c5ab01..2b55711 100644
--- a/drivers/regulator/88pm8607.c
+++ b/drivers/regulator/88pm8607.c
@@ -394,7 +394,7 @@
 #define pm8607_regulator_dt_init(x, y, z)	(-1)
 #endif
 
-static int __devinit pm8607_regulator_probe(struct platform_device *pdev)
+static int pm8607_regulator_probe(struct platform_device *pdev)
 {
 	struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent);
 	struct pm8607_regulator_info *info = NULL;
@@ -454,7 +454,7 @@
 	return 0;
 }
 
-static int __devexit pm8607_regulator_remove(struct platform_device *pdev)
+static int pm8607_regulator_remove(struct platform_device *pdev)
 {
 	struct pm8607_regulator_info *info = platform_get_drvdata(pdev);
 
@@ -481,7 +481,7 @@
 		.owner	= THIS_MODULE,
 	},
 	.probe		= pm8607_regulator_probe,
-	.remove		= __devexit_p(pm8607_regulator_remove),
+	.remove		= pm8607_regulator_remove,
 	.id_table	= pm8607_regulator_driver_ids,
 };
 
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index 67d47b59..551a22b 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -109,6 +109,16 @@
 	  This driver supports the voltage regulators of DA9052-BC and
 	  DA9053-AA/Bx PMIC.
 
+config REGULATOR_DA9055
+	tristate "Dialog Semiconductor DA9055 regulators"
+	depends on MFD_DA9055
+	help
+	  Say y here to support the BUCKs and LDOs regulators found on
+	  Dialog Semiconductor DA9055 PMIC.
+
+	  This driver can also be built as a module. If so, the module
+	  will be called da9055-regulator.
+
 config REGULATOR_FAN53555
 	tristate "Fairchild FAN53555 Regulator"
 	depends on I2C
@@ -204,6 +214,16 @@
 	  via I2C bus. Maxim 8952 has one voltage output and supports 4 DVS
 	  modes ranging from 0.77V to 1.40V by 0.01V steps.
 
+config REGULATOR_MAX8973
+	tristate "Maxim MAX8973 voltage regulator "
+	depends on I2C
+	select REGMAP_I2C
+	help
+	  The MAXIM MAX8973 high-efficiency. three phase, DC-DC step-down
+	  switching regulator delievers up to 9A of output current. Each
+	  phase operates at a 2MHz fixed frequency with a 120 deg shift
+	  from the adjacent phase, allowing the use of small magnetic component.
+
 config REGULATOR_MAX8997
 	tristate "Maxim 8997/8966 regulator"
 	depends on MFD_MAX8997
@@ -335,6 +355,17 @@
 	  on the muxing. This is handled automatically in the driver by
 	  reading the mux info from OTP.
 
+config REGULATOR_TPS51632
+	tristate "TI TPS51632 Power Regulator"
+	depends on I2C
+	select REGMAP_I2C
+	help
+	  This driver supports TPS51632 voltage regulator chip.
+	  The TPS51632 is 3-2-1 Phase D-Cap+ Step Down Driverless Controller
+	  with Serial VID control and DVFS.
+	  The voltage output can be configure through I2C interface or PWM
+	  interface.
+
 config REGULATOR_TPS6105X
 	tristate "TI TPS6105X Power regulators"
 	depends on TPS6105X
@@ -415,6 +446,15 @@
 	help
 	    This driver supports TPS65912 voltage regulator chip.
 
+config REGULATOR_TPS80031
+	tristate "TI TPS80031/TPS80032 power regualtor driver"
+	depends on MFD_TPS80031
+	help
+	  TPS80031/ TPS80032 Fully Integrated Power Management with Power
+	  Path and Battery Charger. It has 5 configurable step-down
+	  converters, 11 general purpose LDOs, VBUS generator and digital
+	  output to control regulators.
+
 config REGULATOR_TWL4030
 	bool "TI TWL4030/TWL5030/TWL6030/TPS659x0 PMIC"
 	depends on TWL4030_CORE
@@ -422,6 +462,13 @@
 	  This driver supports the voltage regulators provided by
 	  this family of companion chips.
 
+config REGULATOR_VEXPRESS
+	tristate "Versatile Express regulators"
+	depends on VEXPRESS_CONFIG
+	help
+	  This driver provides support for voltage regulators available
+	  on the ARM Ltd's Versatile Express platform.
+
 config REGULATOR_WM831X
 	tristate "Wolfson Microelectronics WM831x PMIC regulators"
 	depends on MFD_WM831X
@@ -450,5 +497,12 @@
 	  This driver provides support for the voltage regulators on the
 	  WM8994 CODEC.
 
+config REGULATOR_AS3711
+	tristate "AS3711 PMIC"
+	depends on MFD_AS3711
+	help
+	  This driver provides support for the voltage regulators on the
+	  AS3711 PMIC
+
 endif
 
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index e431eed..b802b0c 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -16,8 +16,10 @@
 obj-$(CONFIG_REGULATOR_AD5398) += ad5398.o
 obj-$(CONFIG_REGULATOR_ANATOP) += anatop-regulator.o
 obj-$(CONFIG_REGULATOR_ARIZONA) += arizona-micsupp.o arizona-ldo1.o
+obj-$(CONFIG_REGULATOR_AS3711) += as3711-regulator.o
 obj-$(CONFIG_REGULATOR_DA903X)	+= da903x.o
 obj-$(CONFIG_REGULATOR_DA9052)	+= da9052-regulator.o
+obj-$(CONFIG_REGULATOR_DA9055)	+= da9055-regulator.o
 obj-$(CONFIG_REGULATOR_DBX500_PRCMU) += dbx500-prcmu.o
 obj-$(CONFIG_REGULATOR_DB8500_PRCMU) += db8500-prcmu.o
 obj-$(CONFIG_REGULATOR_FAN53555) += fan53555.o
@@ -34,6 +36,7 @@
 obj-$(CONFIG_REGULATOR_MAX8907) += max8907-regulator.o
 obj-$(CONFIG_REGULATOR_MAX8925) += max8925-regulator.o
 obj-$(CONFIG_REGULATOR_MAX8952) += max8952.o
+obj-$(CONFIG_REGULATOR_MAX8973) += max8973-regulator.o
 obj-$(CONFIG_REGULATOR_MAX8997) += max8997.o
 obj-$(CONFIG_REGULATOR_MAX8998) += max8998.o
 obj-$(CONFIG_REGULATOR_MAX77686) += max77686.o
@@ -41,6 +44,7 @@
 obj-$(CONFIG_REGULATOR_MC13892) += mc13892-regulator.o
 obj-$(CONFIG_REGULATOR_MC13XXX_CORE) +=  mc13xxx-regulator-core.o
 obj-$(CONFIG_REGULATOR_PALMAS) += palmas-regulator.o
+obj-$(CONFIG_REGULATOR_TPS51632) += tps51632-regulator.o
 obj-$(CONFIG_REGULATOR_PCAP) += pcap-regulator.o
 obj-$(CONFIG_REGULATOR_PCF50633) += pcf50633-regulator.o
 obj-$(CONFIG_REGULATOR_RC5T583)  += rc5t583-regulator.o
@@ -56,7 +60,9 @@
 obj-$(CONFIG_REGULATOR_TPS6586X) += tps6586x-regulator.o
 obj-$(CONFIG_REGULATOR_TPS65910) += tps65910-regulator.o
 obj-$(CONFIG_REGULATOR_TPS65912) += tps65912-regulator.o
+obj-$(CONFIG_REGULATOR_TPS80031) += tps80031-regulator.o
 obj-$(CONFIG_REGULATOR_TWL4030) += twl-regulator.o
+obj-$(CONFIG_REGULATOR_VEXPRESS) += vexpress.o
 obj-$(CONFIG_REGULATOR_WM831X) += wm831x-dcdc.o
 obj-$(CONFIG_REGULATOR_WM831X) += wm831x-isink.o
 obj-$(CONFIG_REGULATOR_WM831X) += wm831x-ldo.o
diff --git a/drivers/regulator/aat2870-regulator.c b/drivers/regulator/aat2870-regulator.c
index 167c93f..8b58763 100644
--- a/drivers/regulator/aat2870-regulator.c
+++ b/drivers/regulator/aat2870-regulator.c
@@ -187,7 +187,7 @@
 	return 0;
 }
 
-static int __devexit aat2870_regulator_remove(struct platform_device *pdev)
+static int aat2870_regulator_remove(struct platform_device *pdev)
 {
 	struct regulator_dev *rdev = platform_get_drvdata(pdev);
 
@@ -201,7 +201,7 @@
 		.owner	= THIS_MODULE,
 	},
 	.probe	= aat2870_regulator_probe,
-	.remove	= __devexit_p(aat2870_regulator_remove),
+	.remove	= aat2870_regulator_remove,
 };
 
 static int __init aat2870_regulator_init(void)
diff --git a/drivers/regulator/ab3100.c b/drivers/regulator/ab3100.c
index df4ad89..111ec69 100644
--- a/drivers/regulator/ab3100.c
+++ b/drivers/regulator/ab3100.c
@@ -494,7 +494,7 @@
  * for all the different regulators.
  */
 
-static int __devinit ab3100_regulators_probe(struct platform_device *pdev)
+static int ab3100_regulators_probe(struct platform_device *pdev)
 {
 	struct ab3100_platform_data *plfdata = pdev->dev.platform_data;
 	struct regulator_config config = { };
@@ -571,7 +571,7 @@
 	return 0;
 }
 
-static int __devexit ab3100_regulators_remove(struct platform_device *pdev)
+static int ab3100_regulators_remove(struct platform_device *pdev)
 {
 	int i;
 
@@ -589,7 +589,7 @@
 		.owner = THIS_MODULE,
 	},
 	.probe = ab3100_regulators_probe,
-	.remove = __devexit_p(ab3100_regulators_remove),
+	.remove = ab3100_regulators_remove,
 };
 
 static __init int ab3100_regulators_init(void)
diff --git a/drivers/regulator/ab8500.c b/drivers/regulator/ab8500.c
index e3d1d06..09014f3 100644
--- a/drivers/regulator/ab8500.c
+++ b/drivers/regulator/ab8500.c
@@ -641,7 +641,7 @@
 	REG_INIT(AB8500_REGUCTRLDISCH2,		0x04, 0x44, 0x16),
 };
 
-static __devinit int
+static int
 ab8500_regulator_init_registers(struct platform_device *pdev, int id, int value)
 {
 	int err;
@@ -676,7 +676,7 @@
 	return 0;
 }
 
-static __devinit int ab8500_regulator_register(struct platform_device *pdev,
+static int ab8500_regulator_register(struct platform_device *pdev,
 					struct regulator_init_data *init_data,
 					int id,
 					struct device_node *np)
@@ -735,7 +735,7 @@
 	{ .name	= "ab8500_ldo_ana",     .driver_data = (void *) AB8500_LDO_ANA, },
 };
 
-static __devinit int
+static int
 ab8500_regulator_of_probe(struct platform_device *pdev, struct device_node *np)
 {
 	int err, i;
@@ -751,7 +751,7 @@
 	return 0;
 }
 
-static __devinit int ab8500_regulator_probe(struct platform_device *pdev)
+static int ab8500_regulator_probe(struct platform_device *pdev)
 {
 	struct ab8500 *ab8500 = dev_get_drvdata(pdev->dev.parent);
 	struct ab8500_platform_data *pdata;
@@ -817,7 +817,7 @@
 	return 0;
 }
 
-static __devexit int ab8500_regulator_remove(struct platform_device *pdev)
+static int ab8500_regulator_remove(struct platform_device *pdev)
 {
 	int i;
 
@@ -836,7 +836,7 @@
 
 static struct platform_driver ab8500_regulator_driver = {
 	.probe = ab8500_regulator_probe,
-	.remove = __devexit_p(ab8500_regulator_remove),
+	.remove = ab8500_regulator_remove,
 	.driver         = {
 		.name   = "ab8500-regulator",
 		.owner  = THIS_MODULE,
diff --git a/drivers/regulator/ad5398.c b/drivers/regulator/ad5398.c
index f123f7e..6b981b5 100644
--- a/drivers/regulator/ad5398.c
+++ b/drivers/regulator/ad5398.c
@@ -211,7 +211,7 @@
 };
 MODULE_DEVICE_TABLE(i2c, ad5398_id);
 
-static int __devinit ad5398_probe(struct i2c_client *client,
+static int ad5398_probe(struct i2c_client *client,
 				const struct i2c_device_id *id)
 {
 	struct regulator_init_data *init_data = client->dev.platform_data;
@@ -256,7 +256,7 @@
 	return ret;
 }
 
-static int __devexit ad5398_remove(struct i2c_client *client)
+static int ad5398_remove(struct i2c_client *client)
 {
 	struct ad5398_chip_info *chip = i2c_get_clientdata(client);
 
@@ -266,7 +266,7 @@
 
 static struct i2c_driver ad5398_driver = {
 	.probe = ad5398_probe,
-	.remove = __devexit_p(ad5398_remove),
+	.remove = ad5398_remove,
 	.driver		= {
 		.name	= "ad5398",
 	},
diff --git a/drivers/regulator/anatop-regulator.c b/drivers/regulator/anatop-regulator.c
index 1af9768..0199eee 100644
--- a/drivers/regulator/anatop-regulator.c
+++ b/drivers/regulator/anatop-regulator.c
@@ -48,36 +48,21 @@
 					unsigned selector)
 {
 	struct anatop_regulator *anatop_reg = rdev_get_drvdata(reg);
-	u32 val, mask;
 
 	if (!anatop_reg->control_reg)
 		return -ENOTSUPP;
 
-	val = anatop_reg->min_bit_val + selector;
-	dev_dbg(&reg->dev, "%s: calculated val %d\n", __func__, val);
-	mask = ((1 << anatop_reg->vol_bit_width) - 1) <<
-		anatop_reg->vol_bit_shift;
-	val <<= anatop_reg->vol_bit_shift;
-	regmap_update_bits(anatop_reg->anatop, anatop_reg->control_reg,
-				mask, val);
-
-	return 0;
+	return regulator_set_voltage_sel_regmap(reg, selector);
 }
 
 static int anatop_regmap_get_voltage_sel(struct regulator_dev *reg)
 {
 	struct anatop_regulator *anatop_reg = rdev_get_drvdata(reg);
-	u32 val, mask;
 
 	if (!anatop_reg->control_reg)
 		return -ENOTSUPP;
 
-	regmap_read(anatop_reg->anatop, anatop_reg->control_reg, &val);
-	mask = ((1 << anatop_reg->vol_bit_width) - 1) <<
-		anatop_reg->vol_bit_shift;
-	val = (val & mask) >> anatop_reg->vol_bit_shift;
-
-	return val - anatop_reg->min_bit_val;
+	return regulator_get_voltage_sel_regmap(reg);
 }
 
 static struct regulator_ops anatop_rops = {
@@ -87,7 +72,7 @@
 	.map_voltage = regulator_map_voltage_linear,
 };
 
-static int __devinit anatop_regulator_probe(struct platform_device *pdev)
+static int anatop_regulator_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
 	struct device_node *np = dev->of_node;
@@ -158,15 +143,20 @@
 		goto anatop_probe_end;
 	}
 
-	rdesc->n_voltages = (sreg->max_voltage - sreg->min_voltage)
-		/ 25000 + 1;
+	rdesc->n_voltages = (sreg->max_voltage - sreg->min_voltage) / 25000 + 1
+			    + sreg->min_bit_val;
 	rdesc->min_uV = sreg->min_voltage;
 	rdesc->uV_step = 25000;
+	rdesc->linear_min_sel = sreg->min_bit_val;
+	rdesc->vsel_reg = sreg->control_reg;
+	rdesc->vsel_mask = ((1 << sreg->vol_bit_width) - 1) <<
+			   sreg->vol_bit_shift;
 
 	config.dev = &pdev->dev;
 	config.init_data = initdata;
 	config.driver_data = sreg;
 	config.of_node = pdev->dev.of_node;
+	config.regmap = sreg->anatop;
 
 	/* register regulator */
 	rdev = regulator_register(rdesc, &config);
@@ -186,7 +176,7 @@
 	return ret;
 }
 
-static int __devexit anatop_regulator_remove(struct platform_device *pdev)
+static int anatop_regulator_remove(struct platform_device *pdev)
 {
 	struct regulator_dev *rdev = platform_get_drvdata(pdev);
 	struct anatop_regulator *sreg = rdev_get_drvdata(rdev);
@@ -210,7 +200,7 @@
 		.of_match_table = of_anatop_regulator_match_tbl,
 	},
 	.probe	= anatop_regulator_probe,
-	.remove	= __devexit_p(anatop_regulator_remove),
+	.remove	= anatop_regulator_remove,
 };
 
 static int __init anatop_regulator_init(void)
diff --git a/drivers/regulator/arizona-ldo1.c b/drivers/regulator/arizona-ldo1.c
index d184aa3..ed7beec 100644
--- a/drivers/regulator/arizona-ldo1.c
+++ b/drivers/regulator/arizona-ldo1.c
@@ -34,6 +34,108 @@
 	struct regulator_init_data init_data;
 };
 
+static int arizona_ldo1_hc_list_voltage(struct regulator_dev *rdev,
+					unsigned int selector)
+{
+	if (selector >= rdev->desc->n_voltages)
+		return -EINVAL;
+
+	if (selector == rdev->desc->n_voltages - 1)
+		return 1800000;
+	else
+		return rdev->desc->min_uV + (rdev->desc->uV_step * selector);
+}
+
+static int arizona_ldo1_hc_map_voltage(struct regulator_dev *rdev,
+				       int min_uV, int max_uV)
+{
+	int sel;
+
+	sel = DIV_ROUND_UP(min_uV - rdev->desc->min_uV, rdev->desc->uV_step);
+	if (sel >= rdev->desc->n_voltages)
+		sel = rdev->desc->n_voltages - 1;
+
+	return sel;
+}
+
+static int arizona_ldo1_hc_set_voltage_sel(struct regulator_dev *rdev,
+					   unsigned sel)
+{
+	struct arizona_ldo1 *ldo = rdev_get_drvdata(rdev);
+	struct regmap *regmap = ldo->arizona->regmap;
+	unsigned int val;
+	int ret;
+
+	if (sel == rdev->desc->n_voltages - 1)
+		val = ARIZONA_LDO1_HI_PWR;
+	else
+		val = 0;
+
+	ret = regmap_update_bits(regmap, ARIZONA_LDO1_CONTROL_2,
+				 ARIZONA_LDO1_HI_PWR, val);
+	if (ret != 0)
+		return ret;
+
+	ret = regmap_update_bits(regmap, ARIZONA_DYNAMIC_FREQUENCY_SCALING_1,
+				 ARIZONA_SUBSYS_MAX_FREQ, val);
+	if (ret != 0)
+		return ret;
+
+	if (val)
+		return 0;
+
+	val = sel << ARIZONA_LDO1_VSEL_SHIFT;
+
+	return regmap_update_bits(regmap, ARIZONA_LDO1_CONTROL_1,
+				  ARIZONA_LDO1_VSEL_MASK, val);
+}
+
+static int arizona_ldo1_hc_get_voltage_sel(struct regulator_dev *rdev)
+{
+	struct arizona_ldo1 *ldo = rdev_get_drvdata(rdev);
+	struct regmap *regmap = ldo->arizona->regmap;
+	unsigned int val;
+	int ret;
+
+	ret = regmap_read(regmap, ARIZONA_LDO1_CONTROL_2, &val);
+	if (ret != 0)
+		return ret;
+
+	if (val & ARIZONA_LDO1_HI_PWR)
+		return rdev->desc->n_voltages - 1;
+
+	ret = regmap_read(regmap, ARIZONA_LDO1_CONTROL_1, &val);
+	if (ret != 0)
+		return ret;
+
+	return (val & ARIZONA_LDO1_VSEL_MASK) >> ARIZONA_LDO1_VSEL_SHIFT;
+}
+
+static struct regulator_ops arizona_ldo1_hc_ops = {
+	.list_voltage = arizona_ldo1_hc_list_voltage,
+	.map_voltage = arizona_ldo1_hc_map_voltage,
+	.get_voltage_sel = arizona_ldo1_hc_get_voltage_sel,
+	.set_voltage_sel = arizona_ldo1_hc_set_voltage_sel,
+	.get_bypass = regulator_get_bypass_regmap,
+	.set_bypass = regulator_set_bypass_regmap,
+};
+
+static const struct regulator_desc arizona_ldo1_hc = {
+	.name = "LDO1",
+	.supply_name = "LDOVDD",
+	.type = REGULATOR_VOLTAGE,
+	.ops = &arizona_ldo1_hc_ops,
+
+	.bypass_reg = ARIZONA_LDO1_CONTROL_1,
+	.bypass_mask = ARIZONA_LDO1_BYPASS,
+	.min_uV = 900000,
+	.uV_step = 50000,
+	.n_voltages = 8,
+	.enable_time = 500,
+
+	.owner = THIS_MODULE,
+};
+
 static struct regulator_ops arizona_ldo1_ops = {
 	.list_voltage = regulator_list_voltage_linear,
 	.map_voltage = regulator_map_voltage_linear,
@@ -55,11 +157,22 @@
 	.bypass_mask = ARIZONA_LDO1_BYPASS,
 	.min_uV = 900000,
 	.uV_step = 50000,
-	.n_voltages = 6,
+	.n_voltages = 7,
+	.enable_time = 500,
 
 	.owner = THIS_MODULE,
 };
 
+static const struct regulator_init_data arizona_ldo1_dvfs = {
+	.constraints = {
+		.min_uV = 1200000,
+		.max_uV = 1800000,
+		.valid_ops_mask = REGULATOR_CHANGE_STATUS |
+				  REGULATOR_CHANGE_VOLTAGE,
+	},
+	.num_consumer_supplies = 1,
+};
+
 static const struct regulator_init_data arizona_ldo1_default = {
 	.constraints = {
 		.valid_ops_mask = REGULATOR_CHANGE_STATUS,
@@ -67,9 +180,10 @@
 	.num_consumer_supplies = 1,
 };
 
-static __devinit int arizona_ldo1_probe(struct platform_device *pdev)
+static int arizona_ldo1_probe(struct platform_device *pdev)
 {
 	struct arizona *arizona = dev_get_drvdata(pdev->dev.parent);
+	const struct regulator_desc *desc;
 	struct regulator_config config = { };
 	struct arizona_ldo1 *ldo1;
 	int ret;
@@ -87,7 +201,17 @@
 	 * default init_data for it.  This will be overridden with
 	 * platform data if provided.
 	 */
-	ldo1->init_data = arizona_ldo1_default;
+	switch (arizona->type) {
+	case WM5102:
+		desc = &arizona_ldo1_hc;
+		ldo1->init_data = arizona_ldo1_dvfs;
+		break;
+	default:
+		desc = &arizona_ldo1;
+		ldo1->init_data = arizona_ldo1_default;
+		break;
+	}
+
 	ldo1->init_data.consumer_supplies = &ldo1->supply;
 	ldo1->supply.supply = "DCVDD";
 	ldo1->supply.dev_name = dev_name(arizona->dev);
@@ -102,7 +226,7 @@
 	else
 		config.init_data = &ldo1->init_data;
 
-	ldo1->regulator = regulator_register(&arizona_ldo1, &config);
+	ldo1->regulator = regulator_register(desc, &config);
 	if (IS_ERR(ldo1->regulator)) {
 		ret = PTR_ERR(ldo1->regulator);
 		dev_err(arizona->dev, "Failed to register LDO1 supply: %d\n",
@@ -115,7 +239,7 @@
 	return 0;
 }
 
-static __devexit int arizona_ldo1_remove(struct platform_device *pdev)
+static int arizona_ldo1_remove(struct platform_device *pdev)
 {
 	struct arizona_ldo1 *ldo1 = platform_get_drvdata(pdev);
 
@@ -126,7 +250,7 @@
 
 static struct platform_driver arizona_ldo1_driver = {
 	.probe = arizona_ldo1_probe,
-	.remove = __devexit_p(arizona_ldo1_remove),
+	.remove = arizona_ldo1_remove,
 	.driver		= {
 		.name	= "arizona-ldo1",
 		.owner	= THIS_MODULE,
diff --git a/drivers/regulator/arizona-micsupp.c b/drivers/regulator/arizona-micsupp.c
index d9b1f82..a6d040c 100644
--- a/drivers/regulator/arizona-micsupp.c
+++ b/drivers/regulator/arizona-micsupp.c
@@ -101,6 +101,8 @@
 	.bypass_reg = ARIZONA_MIC_CHARGE_PUMP_1,
 	.bypass_mask = ARIZONA_CPMIC_BYPASS,
 
+	.enable_time = 3000,
+
 	.owner = THIS_MODULE,
 };
 
@@ -115,7 +117,7 @@
 	.num_consumer_supplies = 1,
 };
 
-static __devinit int arizona_micsupp_probe(struct platform_device *pdev)
+static int arizona_micsupp_probe(struct platform_device *pdev)
 {
 	struct arizona *arizona = dev_get_drvdata(pdev->dev.parent);
 	struct regulator_config config = { };
@@ -166,7 +168,7 @@
 	return 0;
 }
 
-static __devexit int arizona_micsupp_remove(struct platform_device *pdev)
+static int arizona_micsupp_remove(struct platform_device *pdev)
 {
 	struct arizona_micsupp *micsupp = platform_get_drvdata(pdev);
 
@@ -177,7 +179,7 @@
 
 static struct platform_driver arizona_micsupp_driver = {
 	.probe = arizona_micsupp_probe,
-	.remove = __devexit_p(arizona_micsupp_remove),
+	.remove = arizona_micsupp_remove,
 	.driver		= {
 		.name	= "arizona-micsupp",
 		.owner	= THIS_MODULE,
diff --git a/drivers/regulator/as3711-regulator.c b/drivers/regulator/as3711-regulator.c
new file mode 100644
index 0000000..2f1341d
--- /dev/null
+++ b/drivers/regulator/as3711-regulator.c
@@ -0,0 +1,369 @@
+/*
+ * AS3711 PMIC regulator driver, using DCDC Step Down and LDO supplies
+ *
+ * Copyright (C) 2012 Renesas Electronics Corporation
+ * Author: Guennadi Liakhovetski, <g.liakhovetski@gmx.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the version 2 of the GNU General Public License as
+ * published by the Free Software Foundation
+ */
+
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/mfd/as3711.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/regulator/driver.h>
+#include <linux/slab.h>
+
+struct as3711_regulator_info {
+	struct regulator_desc	desc;
+	unsigned int		max_uV;
+};
+
+struct as3711_regulator {
+	struct as3711_regulator_info *reg_info;
+	struct regulator_dev *rdev;
+};
+
+static int as3711_list_voltage_sd(struct regulator_dev *rdev,
+				  unsigned int selector)
+{
+	if (selector >= rdev->desc->n_voltages)
+		return -EINVAL;
+
+	if (!selector)
+		return 0;
+	if (selector < 0x41)
+		return 600000 + selector * 12500;
+	if (selector < 0x71)
+		return 1400000 + (selector - 0x40) * 25000;
+	return 2600000 + (selector - 0x70) * 50000;
+}
+
+static int as3711_list_voltage_aldo(struct regulator_dev *rdev,
+				    unsigned int selector)
+{
+	if (selector >= rdev->desc->n_voltages)
+		return -EINVAL;
+
+	if (selector < 0x10)
+		return 1200000 + selector * 50000;
+	return 1800000 + (selector - 0x10) * 100000;
+}
+
+static int as3711_list_voltage_dldo(struct regulator_dev *rdev,
+				    unsigned int selector)
+{
+	if (selector >= rdev->desc->n_voltages ||
+	    (selector > 0x10 && selector < 0x20))
+		return -EINVAL;
+
+	if (selector < 0x11)
+		return 900000 + selector * 50000;
+	return 1750000 + (selector - 0x20) * 50000;
+}
+
+static int as3711_bound_check(struct regulator_dev *rdev,
+			      int *min_uV, int *max_uV)
+{
+	struct as3711_regulator *reg = rdev_get_drvdata(rdev);
+	struct as3711_regulator_info *info = reg->reg_info;
+
+	dev_dbg(&rdev->dev, "%s(), %d, %d, %d\n", __func__,
+		*min_uV, rdev->desc->min_uV, info->max_uV);
+
+	if (*max_uV < *min_uV ||
+	    *min_uV > info->max_uV || rdev->desc->min_uV > *max_uV)
+		return -EINVAL;
+
+	if (rdev->desc->n_voltages == 1)
+		return 0;
+
+	if (*max_uV > info->max_uV)
+		*max_uV = info->max_uV;
+
+	if (*min_uV < rdev->desc->min_uV)
+		*min_uV = rdev->desc->min_uV;
+
+	return *min_uV;
+}
+
+static int as3711_sel_check(int min, int max, int bottom, int step)
+{
+	int sel, voltage;
+
+	/* Round up min, when dividing: keeps us within the range */
+	sel = DIV_ROUND_UP(min - bottom, step);
+	voltage = sel * step + bottom;
+	pr_debug("%s(): select %d..%d in %d+N*%d: %d\n", __func__,
+	       min, max, bottom, step, sel);
+	if (voltage > max)
+		return -EINVAL;
+
+	return sel;
+}
+
+static int as3711_map_voltage_sd(struct regulator_dev *rdev,
+				 int min_uV, int max_uV)
+{
+	int ret;
+
+	ret = as3711_bound_check(rdev, &min_uV, &max_uV);
+	if (ret <= 0)
+		return ret;
+
+	if (min_uV <= 1400000)
+		return as3711_sel_check(min_uV, max_uV, 600000, 12500);
+
+	if (min_uV <= 2600000)
+		return as3711_sel_check(min_uV, max_uV, 1400000, 25000) + 0x40;
+
+	return as3711_sel_check(min_uV, max_uV, 2600000, 50000) + 0x70;
+}
+
+/*
+ * The regulator API supports 4 modes of operataion: FAST, NORMAL, IDLE and
+ * STANDBY. We map them in the following way to AS3711 SD1-4 DCDC modes:
+ * FAST:	sdX_fast=1
+ * NORMAL:	low_noise=1
+ * IDLE:	low_noise=0
+ */
+
+static int as3711_set_mode_sd(struct regulator_dev *rdev, unsigned int mode)
+{
+	unsigned int fast_bit = rdev->desc->enable_mask,
+		low_noise_bit = fast_bit << 4;
+	u8 val;
+
+	switch (mode) {
+	case REGULATOR_MODE_FAST:
+		val = fast_bit | low_noise_bit;
+		break;
+	case REGULATOR_MODE_NORMAL:
+		val = low_noise_bit;
+		break;
+	case REGULATOR_MODE_IDLE:
+		val = 0;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return regmap_update_bits(rdev->regmap, AS3711_SD_CONTROL_1,
+				  low_noise_bit | fast_bit, val);
+}
+
+static unsigned int as3711_get_mode_sd(struct regulator_dev *rdev)
+{
+	unsigned int fast_bit = rdev->desc->enable_mask,
+		low_noise_bit = fast_bit << 4, mask = fast_bit | low_noise_bit;
+	unsigned int val;
+	int ret = regmap_read(rdev->regmap, AS3711_SD_CONTROL_1, &val);
+
+	if (ret < 0)
+		return ret;
+
+	if ((val & mask) == mask)
+		return REGULATOR_MODE_FAST;
+
+	if ((val & mask) == low_noise_bit)
+		return REGULATOR_MODE_NORMAL;
+
+	if (!(val & mask))
+		return REGULATOR_MODE_IDLE;
+
+	return -EINVAL;
+}
+
+static int as3711_map_voltage_aldo(struct regulator_dev *rdev,
+				  int min_uV, int max_uV)
+{
+	int ret;
+
+	ret = as3711_bound_check(rdev, &min_uV, &max_uV);
+	if (ret <= 0)
+		return ret;
+
+	if (min_uV <= 1800000)
+		return as3711_sel_check(min_uV, max_uV, 1200000, 50000);
+
+	return as3711_sel_check(min_uV, max_uV, 1800000, 100000) + 0x10;
+}
+
+static int as3711_map_voltage_dldo(struct regulator_dev *rdev,
+				  int min_uV, int max_uV)
+{
+	int ret;
+
+	ret = as3711_bound_check(rdev, &min_uV, &max_uV);
+	if (ret <= 0)
+		return ret;
+
+	if (min_uV <= 1700000)
+		return as3711_sel_check(min_uV, max_uV, 900000, 50000);
+
+	return as3711_sel_check(min_uV, max_uV, 1750000, 50000) + 0x20;
+}
+
+static struct regulator_ops as3711_sd_ops = {
+	.is_enabled		= regulator_is_enabled_regmap,
+	.enable			= regulator_enable_regmap,
+	.disable		= regulator_disable_regmap,
+	.get_voltage_sel	= regulator_get_voltage_sel_regmap,
+	.set_voltage_sel	= regulator_set_voltage_sel_regmap,
+	.list_voltage		= as3711_list_voltage_sd,
+	.map_voltage		= as3711_map_voltage_sd,
+	.get_mode		= as3711_get_mode_sd,
+	.set_mode		= as3711_set_mode_sd,
+};
+
+static struct regulator_ops as3711_aldo_ops = {
+	.is_enabled		= regulator_is_enabled_regmap,
+	.enable			= regulator_enable_regmap,
+	.disable		= regulator_disable_regmap,
+	.get_voltage_sel	= regulator_get_voltage_sel_regmap,
+	.set_voltage_sel	= regulator_set_voltage_sel_regmap,
+	.list_voltage		= as3711_list_voltage_aldo,
+	.map_voltage		= as3711_map_voltage_aldo,
+};
+
+static struct regulator_ops as3711_dldo_ops = {
+	.is_enabled		= regulator_is_enabled_regmap,
+	.enable			= regulator_enable_regmap,
+	.disable		= regulator_disable_regmap,
+	.get_voltage_sel	= regulator_get_voltage_sel_regmap,
+	.set_voltage_sel	= regulator_set_voltage_sel_regmap,
+	.list_voltage		= as3711_list_voltage_dldo,
+	.map_voltage		= as3711_map_voltage_dldo,
+};
+
+#define AS3711_REG(_id, _en_reg, _en_bit, _vmask, _vshift, _min_uV, _max_uV, _sfx)	\
+	[AS3711_REGULATOR_ ## _id] = {							\
+	.desc = {									\
+		.name = "as3711-regulator-" # _id,					\
+		.id = AS3711_REGULATOR_ ## _id,						\
+		.n_voltages = (_vmask + 1),						\
+		.ops = &as3711_ ## _sfx ## _ops,					\
+		.type = REGULATOR_VOLTAGE,						\
+		.owner = THIS_MODULE,							\
+		.vsel_reg = AS3711_ ## _id ## _VOLTAGE,					\
+		.vsel_mask = _vmask << _vshift,						\
+		.enable_reg = AS3711_ ## _en_reg,					\
+		.enable_mask = BIT(_en_bit),						\
+		.min_uV	= _min_uV,							\
+	},										\
+	.max_uV = _max_uV,								\
+}
+
+static struct as3711_regulator_info as3711_reg_info[] = {
+	AS3711_REG(SD_1, SD_CONTROL, 0, 0x7f, 0, 612500, 3350000, sd),
+	AS3711_REG(SD_2, SD_CONTROL, 1, 0x7f, 0, 612500, 3350000, sd),
+	AS3711_REG(SD_3, SD_CONTROL, 2, 0x7f, 0, 612500, 3350000, sd),
+	AS3711_REG(SD_4, SD_CONTROL, 3, 0x7f, 0, 612500, 3350000, sd),
+	AS3711_REG(LDO_1, LDO_1_VOLTAGE, 7, 0x1f, 0, 1200000, 3300000, aldo),
+	AS3711_REG(LDO_2, LDO_2_VOLTAGE, 7, 0x1f, 0, 1200000, 3300000, aldo),
+	AS3711_REG(LDO_3, LDO_3_VOLTAGE, 7, 0x3f, 0, 900000, 3300000, dldo),
+	AS3711_REG(LDO_4, LDO_4_VOLTAGE, 7, 0x3f, 0, 900000, 3300000, dldo),
+	AS3711_REG(LDO_5, LDO_5_VOLTAGE, 7, 0x3f, 0, 900000, 3300000, dldo),
+	AS3711_REG(LDO_6, LDO_6_VOLTAGE, 7, 0x3f, 0, 900000, 3300000, dldo),
+	AS3711_REG(LDO_7, LDO_7_VOLTAGE, 7, 0x3f, 0, 900000, 3300000, dldo),
+	AS3711_REG(LDO_8, LDO_8_VOLTAGE, 7, 0x3f, 0, 900000, 3300000, dldo),
+	/* StepUp output voltage depends on supplying regulator */
+};
+
+#define AS3711_REGULATOR_NUM ARRAY_SIZE(as3711_reg_info)
+
+static int as3711_regulator_probe(struct platform_device *pdev)
+{
+	struct as3711_regulator_pdata *pdata = dev_get_platdata(&pdev->dev);
+	struct as3711 *as3711 = dev_get_drvdata(pdev->dev.parent);
+	struct regulator_init_data *reg_data;
+	struct regulator_config config = {.dev = &pdev->dev,};
+	struct as3711_regulator *reg = NULL;
+	struct as3711_regulator *regs;
+	struct regulator_dev *rdev;
+	struct as3711_regulator_info *ri;
+	int ret;
+	int id;
+
+	if (!pdata)
+		dev_dbg(&pdev->dev, "No platform data...\n");
+
+	regs = devm_kzalloc(&pdev->dev, AS3711_REGULATOR_NUM *
+			sizeof(struct as3711_regulator), GFP_KERNEL);
+	if (!regs) {
+		dev_err(&pdev->dev, "Memory allocation failed exiting..\n");
+		return -ENOMEM;
+	}
+
+	for (id = 0, ri = as3711_reg_info; id < AS3711_REGULATOR_NUM; ++id, ri++) {
+		reg_data = pdata ? pdata->init_data[id] : NULL;
+
+		/* No need to register if there is no regulator data */
+		if (!ri->desc.name)
+			continue;
+
+		reg = &regs[id];
+		reg->reg_info = ri;
+
+		config.init_data = reg_data;
+		config.driver_data = reg;
+		config.regmap = as3711->regmap;
+
+		rdev = regulator_register(&ri->desc, &config);
+		if (IS_ERR(rdev)) {
+			dev_err(&pdev->dev, "Failed to register regulator %s\n",
+				ri->desc.name);
+			ret = PTR_ERR(rdev);
+			goto eregreg;
+		}
+		reg->rdev = rdev;
+	}
+	platform_set_drvdata(pdev, regs);
+	return 0;
+
+eregreg:
+	while (--id >= 0)
+		regulator_unregister(regs[id].rdev);
+
+	return ret;
+}
+
+static int as3711_regulator_remove(struct platform_device *pdev)
+{
+	struct as3711_regulator *regs = platform_get_drvdata(pdev);
+	int id;
+
+	for (id = 0; id < AS3711_REGULATOR_NUM; ++id)
+		regulator_unregister(regs[id].rdev);
+	return 0;
+}
+
+static struct platform_driver as3711_regulator_driver = {
+	.driver	= {
+		.name	= "as3711-regulator",
+		.owner	= THIS_MODULE,
+	},
+	.probe		= as3711_regulator_probe,
+	.remove		= as3711_regulator_remove,
+};
+
+static int __init as3711_regulator_init(void)
+{
+	return platform_driver_register(&as3711_regulator_driver);
+}
+subsys_initcall(as3711_regulator_init);
+
+static void __exit as3711_regulator_exit(void)
+{
+	platform_driver_unregister(&as3711_regulator_driver);
+}
+module_exit(as3711_regulator_exit);
+
+MODULE_AUTHOR("Guennadi Liakhovetski <g.liakhovetski@gmx.de>");
+MODULE_DESCRIPTION("AS3711 regulator driver");
+MODULE_ALIAS("platform:as3711-regulator");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index e872c8b..0f65b24 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -199,8 +199,11 @@
 			*min_uV = regulator->min_uV;
 	}
 
-	if (*min_uV > *max_uV)
+	if (*min_uV > *max_uV) {
+		dev_err(regulator->dev, "Restricting voltage, %u-%uuV\n",
+			regulator->min_uV, regulator->max_uV);
 		return -EINVAL;
+	}
 
 	return 0;
 }
@@ -880,7 +883,9 @@
 
 		/* final: [min_uV..max_uV] valid iff constraints valid */
 		if (max_uV < min_uV) {
-			rdev_err(rdev, "unsupportable voltage constraints\n");
+			rdev_err(rdev,
+				 "unsupportable voltage constraints %u-%uuV\n",
+				 min_uV, max_uV);
 			return -EINVAL;
 		}
 
@@ -1867,6 +1872,28 @@
 EXPORT_SYMBOL_GPL(regulator_is_enabled);
 
 /**
+ * regulator_can_change_voltage - check if regulator can change voltage
+ * @regulator: regulator source
+ *
+ * Returns positive if the regulator driver backing the source/client
+ * can change its voltage, false otherwise. Usefull for detecting fixed
+ * or dummy regulators and disabling voltage change logic in the client
+ * driver.
+ */
+int regulator_can_change_voltage(struct regulator *regulator)
+{
+	struct regulator_dev	*rdev = regulator->rdev;
+
+	if (rdev->constraints &&
+	    rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_VOLTAGE &&
+	    (rdev->desc->n_voltages - rdev->desc->linear_min_sel) > 1)
+		return 1;
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(regulator_can_change_voltage);
+
+/**
  * regulator_count_voltages - count regulator_list_voltage() selectors
  * @regulator: regulator source
  *
@@ -1897,6 +1924,10 @@
 {
 	if (selector >= rdev->desc->n_voltages)
 		return -EINVAL;
+	if (selector < rdev->desc->linear_min_sel)
+		return 0;
+
+	selector -= rdev->desc->linear_min_sel;
 
 	return rdev->desc->min_uV + (rdev->desc->uV_step * selector);
 }
@@ -1985,6 +2016,11 @@
 			return ret;
 	}
 
+	/* Any voltage within constrains range is fine? */
+	if (rdev->desc->continuous_voltage_range)
+		return min_uV >= rdev->constraints->min_uV &&
+				max_uV <= rdev->constraints->max_uV;
+
 	ret = regulator_count_voltages(regulator);
 	if (ret < 0)
 		return ret;
@@ -2120,6 +2156,8 @@
 	if (ret < 0)
 		return ret;
 
+	ret += rdev->desc->linear_min_sel;
+
 	/* Map back into a voltage to verify we're still in bounds */
 	voltage = rdev->desc->ops->list_voltage(rdev, ret);
 	if (voltage < min_uV || voltage > max_uV)
diff --git a/drivers/regulator/da903x.c b/drivers/regulator/da903x.c
index 36c5b92..2afa573 100644
--- a/drivers/regulator/da903x.c
+++ b/drivers/regulator/da903x.c
@@ -460,7 +460,7 @@
 	return NULL;
 }
 
-static int __devinit da903x_regulator_probe(struct platform_device *pdev)
+static int da903x_regulator_probe(struct platform_device *pdev)
 {
 	struct da903x_regulator_info *ri = NULL;
 	struct regulator_dev *rdev;
@@ -499,7 +499,7 @@
 	return 0;
 }
 
-static int __devexit da903x_regulator_remove(struct platform_device *pdev)
+static int da903x_regulator_remove(struct platform_device *pdev)
 {
 	struct regulator_dev *rdev = platform_get_drvdata(pdev);
 
@@ -513,7 +513,7 @@
 		.owner	= THIS_MODULE,
 	},
 	.probe		= da903x_regulator_probe,
-	.remove		= __devexit_p(da903x_regulator_remove),
+	.remove		= da903x_regulator_remove,
 };
 
 static int __init da903x_regulator_init(void)
diff --git a/drivers/regulator/da9052-regulator.c b/drivers/regulator/da9052-regulator.c
index 27355b1..d096309 100644
--- a/drivers/regulator/da9052-regulator.c
+++ b/drivers/regulator/da9052-regulator.c
@@ -129,17 +129,17 @@
 	else if (offset == 0)
 		row = 1;
 
-	if (min_uA > da9052_current_limits[row][DA9052_MAX_UA] ||
-	    max_uA < da9052_current_limits[row][DA9052_MIN_UA])
-		return -EINVAL;
-
 	for (i = DA9052_CURRENT_RANGE - 1; i >= 0; i--) {
-		if (da9052_current_limits[row][i] <= max_uA) {
+		if ((min_uA <= da9052_current_limits[row][i]) &&
+		    (da9052_current_limits[row][i] <= max_uA)) {
 			reg_val = i;
 			break;
 		}
 	}
 
+	if (i < 0)
+		return -EINVAL;
+
 	/* Determine the even or odd position of the buck current limit
 	 * register field
 	*/
@@ -365,7 +365,7 @@
 	return NULL;
 }
 
-static int __devinit da9052_regulator_probe(struct platform_device *pdev)
+static int da9052_regulator_probe(struct platform_device *pdev)
 {
 	struct regulator_config config = { };
 	struct da9052_regulator *regulator;
@@ -430,7 +430,7 @@
 	return 0;
 }
 
-static int __devexit da9052_regulator_remove(struct platform_device *pdev)
+static int da9052_regulator_remove(struct platform_device *pdev)
 {
 	struct da9052_regulator *regulator = platform_get_drvdata(pdev);
 
@@ -440,7 +440,7 @@
 
 static struct platform_driver da9052_regulator_driver = {
 	.probe = da9052_regulator_probe,
-	.remove = __devexit_p(da9052_regulator_remove),
+	.remove = da9052_regulator_remove,
 	.driver = {
 		.name = "da9052-regulator",
 		.owner = THIS_MODULE,
diff --git a/drivers/regulator/da9055-regulator.c b/drivers/regulator/da9055-regulator.c
new file mode 100644
index 0000000..a4b9cb8
--- /dev/null
+++ b/drivers/regulator/da9055-regulator.c
@@ -0,0 +1,641 @@
+/*
+* Regulator driver for DA9055 PMIC
+*
+* Copyright(c) 2012 Dialog Semiconductor Ltd.
+*
+* Author: David Dajun Chen <dchen@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/init.h>
+#include <linux/err.h>
+#include <linux/gpio.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/machine.h>
+
+#include <linux/mfd/da9055/core.h>
+#include <linux/mfd/da9055/reg.h>
+#include <linux/mfd/da9055/pdata.h>
+
+#define DA9055_MIN_UA		0
+#define DA9055_MAX_UA		3
+
+#define DA9055_LDO_MODE_SYNC	0
+#define DA9055_LDO_MODE_SLEEP	1
+
+#define DA9055_BUCK_MODE_SLEEP	1
+#define DA9055_BUCK_MODE_SYNC	2
+#define DA9055_BUCK_MODE_AUTO	3
+
+/* DA9055 REGULATOR IDs */
+#define DA9055_ID_BUCK1	0
+#define DA9055_ID_BUCK2	1
+#define DA9055_ID_LDO1		2
+#define DA9055_ID_LDO2		3
+#define DA9055_ID_LDO3		4
+#define DA9055_ID_LDO4		5
+#define DA9055_ID_LDO5		6
+#define DA9055_ID_LDO6		7
+
+/* DA9055 BUCK current limit */
+static const int da9055_current_limits[] = { 500000, 600000, 700000, 800000 };
+
+struct da9055_conf_reg {
+	int reg;
+	int sel_mask;
+	int en_mask;
+};
+
+struct da9055_volt_reg {
+	int reg_a;
+	int reg_b;
+	int sl_shift;
+	int v_mask;
+	int v_shift;
+};
+
+struct da9055_mode_reg {
+	int reg;
+	int mask;
+	int shift;
+};
+
+struct da9055_regulator_info {
+	struct regulator_desc reg_desc;
+	struct da9055_conf_reg conf;
+	struct da9055_volt_reg volt;
+	struct da9055_mode_reg mode;
+};
+
+struct da9055_regulator {
+	struct da9055 *da9055;
+	struct da9055_regulator_info *info;
+	struct regulator_dev *rdev;
+	enum gpio_select reg_rselect;
+};
+
+static unsigned int da9055_buck_get_mode(struct regulator_dev *rdev)
+{
+	struct da9055_regulator *regulator = rdev_get_drvdata(rdev);
+	struct da9055_regulator_info *info = regulator->info;
+	int ret, mode = 0;
+
+	ret = da9055_reg_read(regulator->da9055, info->mode.reg);
+	if (ret < 0)
+		return ret;
+
+	switch ((ret & info->mode.mask) >> info->mode.shift) {
+	case DA9055_BUCK_MODE_SYNC:
+		mode = REGULATOR_MODE_FAST;
+		break;
+	case DA9055_BUCK_MODE_AUTO:
+		mode = REGULATOR_MODE_NORMAL;
+		break;
+	case DA9055_BUCK_MODE_SLEEP:
+		mode = REGULATOR_MODE_STANDBY;
+		break;
+	}
+
+	return mode;
+}
+
+static int da9055_buck_set_mode(struct regulator_dev *rdev,
+					unsigned int mode)
+{
+	struct da9055_regulator *regulator = rdev_get_drvdata(rdev);
+	struct da9055_regulator_info *info = regulator->info;
+	int val = 0;
+
+	switch (mode) {
+	case REGULATOR_MODE_FAST:
+		val = DA9055_BUCK_MODE_SYNC << info->mode.shift;
+		break;
+	case REGULATOR_MODE_NORMAL:
+		val = DA9055_BUCK_MODE_AUTO << info->mode.shift;
+		break;
+	case REGULATOR_MODE_STANDBY:
+		val = DA9055_BUCK_MODE_SLEEP << info->mode.shift;
+		break;
+	}
+
+	return da9055_reg_update(regulator->da9055, info->mode.reg,
+				 info->mode.mask, val);
+}
+
+static unsigned int da9055_ldo_get_mode(struct regulator_dev *rdev)
+{
+	struct da9055_regulator *regulator = rdev_get_drvdata(rdev);
+	struct da9055_regulator_info *info = regulator->info;
+	int ret;
+
+	ret = da9055_reg_read(regulator->da9055, info->volt.reg_b);
+	if (ret < 0)
+		return ret;
+
+	if (ret >> info->volt.sl_shift)
+		return REGULATOR_MODE_STANDBY;
+	else
+		return REGULATOR_MODE_NORMAL;
+}
+
+static int da9055_ldo_set_mode(struct regulator_dev *rdev, unsigned int mode)
+{
+	struct da9055_regulator *regulator = rdev_get_drvdata(rdev);
+	struct da9055_regulator_info *info = regulator->info;
+	struct da9055_volt_reg volt = info->volt;
+	int val = 0;
+
+	switch (mode) {
+	case REGULATOR_MODE_NORMAL:
+	case REGULATOR_MODE_FAST:
+		val = DA9055_LDO_MODE_SYNC;
+		break;
+	case REGULATOR_MODE_STANDBY:
+		val = DA9055_LDO_MODE_SLEEP;
+		break;
+	}
+
+	return da9055_reg_update(regulator->da9055, volt.reg_b,
+				 1 << volt.sl_shift,
+				 val << volt.sl_shift);
+}
+
+static int da9055_buck_get_current_limit(struct regulator_dev *rdev)
+{
+	struct da9055_regulator *regulator = rdev_get_drvdata(rdev);
+	struct da9055_regulator_info *info = regulator->info;
+	int ret;
+
+	ret = da9055_reg_read(regulator->da9055, DA9055_REG_BUCK_LIM);
+	if (ret < 0)
+		return ret;
+
+	ret &= info->mode.mask;
+	return da9055_current_limits[ret >> info->mode.shift];
+}
+
+static int da9055_buck_set_current_limit(struct regulator_dev *rdev, int min_uA,
+					 int max_uA)
+{
+	struct da9055_regulator *regulator = rdev_get_drvdata(rdev);
+	struct da9055_regulator_info *info = regulator->info;
+	int i;
+
+	for (i = ARRAY_SIZE(da9055_current_limits) - 1; i >= 0; i--) {
+		if ((min_uA <= da9055_current_limits[i]) &&
+		    (da9055_current_limits[i] <= max_uA))
+			return da9055_reg_update(regulator->da9055,
+						 DA9055_REG_BUCK_LIM,
+						 info->mode.mask,
+						 i << info->mode.shift);
+	}
+
+	return -EINVAL;
+}
+
+static int da9055_regulator_get_voltage_sel(struct regulator_dev *rdev)
+{
+	struct da9055_regulator *regulator = rdev_get_drvdata(rdev);
+	struct da9055_regulator_info *info = regulator->info;
+	struct da9055_volt_reg volt = info->volt;
+	int ret, sel;
+
+	/*
+	 * There are two voltage register set A & B for voltage ramping but
+	 * either one of then can be active therefore we first determine
+	 * the active register set.
+	 */
+	ret = da9055_reg_read(regulator->da9055, info->conf.reg);
+	if (ret < 0)
+		return ret;
+
+	ret &= info->conf.sel_mask;
+
+	/* Get the voltage for the active register set A/B */
+	if (ret == DA9055_REGUALTOR_SET_A)
+		ret = da9055_reg_read(regulator->da9055, volt.reg_a);
+	else
+		ret = da9055_reg_read(regulator->da9055, volt.reg_b);
+
+	if (ret < 0)
+		return ret;
+
+	sel = (ret & volt.v_mask);
+	return sel;
+}
+
+static int da9055_regulator_set_voltage_sel(struct regulator_dev *rdev,
+					    unsigned int selector)
+{
+	struct da9055_regulator *regulator = rdev_get_drvdata(rdev);
+	struct da9055_regulator_info *info = regulator->info;
+	int ret;
+
+	/*
+	 * Regulator register set A/B is not selected through GPIO therefore
+	 * we use default register set A for voltage ramping.
+	 */
+	if (regulator->reg_rselect == NO_GPIO) {
+		/* Select register set A */
+		ret = da9055_reg_update(regulator->da9055, info->conf.reg,
+					info->conf.sel_mask, DA9055_SEL_REG_A);
+		if (ret < 0)
+			return ret;
+
+		/* Set the voltage */
+		return da9055_reg_update(regulator->da9055, info->volt.reg_a,
+					 info->volt.v_mask, selector);
+	}
+
+	/*
+	 * Here regulator register set A/B is selected through GPIO.
+	 * Therefore we first determine the selected register set A/B and
+	 * then set the desired voltage for that register set A/B.
+	 */
+	ret = da9055_reg_read(regulator->da9055, info->conf.reg);
+	if (ret < 0)
+		return ret;
+
+	ret &= info->conf.sel_mask;
+
+	/* Set the voltage */
+	if (ret == DA9055_REGUALTOR_SET_A)
+		return da9055_reg_update(regulator->da9055, info->volt.reg_a,
+					 info->volt.v_mask, selector);
+	else
+		return da9055_reg_update(regulator->da9055, info->volt.reg_b,
+					 info->volt.v_mask, selector);
+}
+
+static int da9055_regulator_set_suspend_voltage(struct regulator_dev *rdev,
+						int uV)
+{
+	struct da9055_regulator *regulator = rdev_get_drvdata(rdev);
+	struct da9055_regulator_info *info = regulator->info;
+	int ret;
+
+	/* Select register set B for suspend voltage ramping. */
+	if (regulator->reg_rselect == NO_GPIO) {
+		ret = da9055_reg_update(regulator->da9055, info->conf.reg,
+					info->conf.sel_mask, DA9055_SEL_REG_B);
+		if (ret < 0)
+			return ret;
+	}
+
+	ret = regulator_map_voltage_linear(rdev, uV, uV);
+	if (ret < 0)
+		return ret;
+
+	return da9055_reg_update(regulator->da9055, info->volt.reg_b,
+				 info->volt.v_mask, ret);
+}
+
+static int da9055_suspend_enable(struct regulator_dev *rdev)
+{
+	struct da9055_regulator *regulator = rdev_get_drvdata(rdev);
+	struct da9055_regulator_info *info = regulator->info;
+
+	/* Select register set B for voltage ramping. */
+	if (regulator->reg_rselect == NO_GPIO)
+		return da9055_reg_update(regulator->da9055, info->conf.reg,
+					info->conf.sel_mask, DA9055_SEL_REG_B);
+	else
+		return 0;
+}
+
+static int da9055_suspend_disable(struct regulator_dev *rdev)
+{
+	struct da9055_regulator *regulator = rdev_get_drvdata(rdev);
+	struct da9055_regulator_info *info = regulator->info;
+
+	/* Diselect register set B. */
+	if (regulator->reg_rselect == NO_GPIO)
+		return da9055_reg_update(regulator->da9055, info->conf.reg,
+					info->conf.sel_mask, DA9055_SEL_REG_A);
+	else
+		return 0;
+}
+
+static struct regulator_ops da9055_buck_ops = {
+	.get_mode = da9055_buck_get_mode,
+	.set_mode = da9055_buck_set_mode,
+
+	.get_current_limit = da9055_buck_get_current_limit,
+	.set_current_limit = da9055_buck_set_current_limit,
+
+	.get_voltage_sel = da9055_regulator_get_voltage_sel,
+	.set_voltage_sel = da9055_regulator_set_voltage_sel,
+	.list_voltage = regulator_list_voltage_linear,
+	.map_voltage = regulator_map_voltage_linear,
+	.is_enabled = regulator_is_enabled_regmap,
+	.enable = regulator_enable_regmap,
+	.disable = regulator_disable_regmap,
+
+	.set_suspend_voltage = da9055_regulator_set_suspend_voltage,
+	.set_suspend_enable = da9055_suspend_enable,
+	.set_suspend_disable = da9055_suspend_disable,
+	.set_suspend_mode = da9055_buck_set_mode,
+};
+
+static struct regulator_ops da9055_ldo_ops = {
+	.get_mode = da9055_ldo_get_mode,
+	.set_mode = da9055_ldo_set_mode,
+
+	.get_voltage_sel = da9055_regulator_get_voltage_sel,
+	.set_voltage_sel = da9055_regulator_set_voltage_sel,
+	.list_voltage = regulator_list_voltage_linear,
+	.map_voltage = regulator_map_voltage_linear,
+	.is_enabled = regulator_is_enabled_regmap,
+	.enable = regulator_enable_regmap,
+	.disable = regulator_disable_regmap,
+
+	.set_suspend_voltage = da9055_regulator_set_suspend_voltage,
+	.set_suspend_enable = da9055_suspend_enable,
+	.set_suspend_disable = da9055_suspend_disable,
+	.set_suspend_mode = da9055_ldo_set_mode,
+
+};
+
+#define DA9055_LDO(_id, step, min, max, vbits, voffset) \
+{\
+	.reg_desc = {\
+		.name = #_id,\
+		.ops = &da9055_ldo_ops,\
+		.type = REGULATOR_VOLTAGE,\
+		.id = DA9055_ID_##_id,\
+		.n_voltages = (max - min) / step + 1 + (voffset), \
+		.enable_reg = DA9055_REG_BCORE_CONT + DA9055_ID_##_id, \
+		.enable_mask = 1, \
+		.min_uV = (min) * 1000,\
+		.uV_step = (step) * 1000,\
+		.linear_min_sel = (voffset),\
+		.owner = THIS_MODULE,\
+	},\
+	.conf = {\
+		.reg = DA9055_REG_BCORE_CONT + DA9055_ID_##_id, \
+		.sel_mask = (1 << 4),\
+		.en_mask = 1,\
+	},\
+	.volt = {\
+		.reg_a = DA9055_REG_VBCORE_A + DA9055_ID_##_id, \
+		.reg_b = DA9055_REG_VBCORE_B + DA9055_ID_##_id, \
+		.sl_shift = 7,\
+		.v_mask = (1 << (vbits)) - 1,\
+		.v_shift = (vbits),\
+	},\
+}
+
+#define DA9055_BUCK(_id, step, min, max, vbits, voffset, mbits, sbits) \
+{\
+	.reg_desc = {\
+		.name = #_id,\
+		.ops = &da9055_buck_ops,\
+		.type = REGULATOR_VOLTAGE,\
+		.id = DA9055_ID_##_id,\
+		.n_voltages = (max - min) / step + 1 + (voffset), \
+		.enable_reg = DA9055_REG_BCORE_CONT + DA9055_ID_##_id, \
+		.enable_mask = 1,\
+		.min_uV = (min) * 1000,\
+		.uV_step = (step) * 1000,\
+		.linear_min_sel = (voffset),\
+		.owner = THIS_MODULE,\
+	},\
+	.conf = {\
+		.reg = DA9055_REG_BCORE_CONT + DA9055_ID_##_id, \
+		.sel_mask = (1 << 4),\
+		.en_mask = 1,\
+	},\
+	.volt = {\
+		.reg_a = DA9055_REG_VBCORE_A + DA9055_ID_##_id, \
+		.reg_b = DA9055_REG_VBCORE_B + DA9055_ID_##_id, \
+		.sl_shift = 7,\
+		.v_mask = (1 << (vbits)) - 1,\
+		.v_shift = (vbits),\
+	},\
+	.mode = {\
+		.reg = DA9055_REG_BCORE_MODE,\
+		.mask = (mbits),\
+		.shift = (sbits),\
+	},\
+}
+
+static struct da9055_regulator_info da9055_regulator_info[] = {
+	DA9055_BUCK(BUCK1, 25, 725, 2075, 6, 9, 0xc, 2),
+	DA9055_BUCK(BUCK2, 25, 925, 2500, 6, 0, 3, 0),
+	DA9055_LDO(LDO1, 50, 900, 3300, 6, 2),
+	DA9055_LDO(LDO2, 50, 900, 3300, 6, 3),
+	DA9055_LDO(LDO3, 50, 900, 3300, 6, 2),
+	DA9055_LDO(LDO4, 50, 900, 3300, 6, 2),
+	DA9055_LDO(LDO5, 50, 900, 2750, 6, 2),
+	DA9055_LDO(LDO6, 20, 900, 3300, 7, 0),
+};
+
+/*
+ * Configures regulator to be controlled either through GPIO 1 or 2.
+ * GPIO can control regulator state and/or select the regulator register
+ * set A/B for voltage ramping.
+ */
+static __devinit int da9055_gpio_init(struct da9055_regulator *regulator,
+				      struct regulator_config *config,
+				      struct da9055_pdata *pdata, int id)
+{
+	struct da9055_regulator_info *info = regulator->info;
+	int ret = 0;
+
+	if (pdata->gpio_ren && pdata->gpio_ren[id]) {
+		char name[18];
+		int gpio_mux = pdata->gpio_ren[id];
+
+		config->ena_gpio = pdata->ena_gpio[id];
+		config->ena_gpio_flags = GPIOF_OUT_INIT_HIGH;
+		config->ena_gpio_invert = 1;
+
+		/*
+		 * GPI pin is muxed with regulator to control the
+		 * regulator state.
+		 */
+		sprintf(name, "DA9055 GPI %d", gpio_mux);
+		ret = devm_gpio_request_one(config->dev, gpio_mux, GPIOF_DIR_IN,
+					    name);
+		if (ret < 0)
+			goto err;
+
+		/*
+		 * Let the regulator know that its state is controlled
+		 * through GPI.
+		 */
+		ret = da9055_reg_update(regulator->da9055, info->conf.reg,
+					DA9055_E_GPI_MASK,
+					pdata->reg_ren[id]
+					<< DA9055_E_GPI_SHIFT);
+		if (ret < 0)
+			goto err;
+	}
+
+	if (pdata->gpio_rsel && pdata->gpio_rsel[id]) {
+		char name[18];
+		int gpio_mux = pdata->gpio_rsel[id];
+
+		regulator->reg_rselect = pdata->reg_rsel[id];
+
+		/*
+		 * GPI pin is muxed with regulator to select the
+		 * regulator register set A/B for voltage ramping.
+		 */
+		sprintf(name, "DA9055 GPI %d", gpio_mux);
+		ret = devm_gpio_request_one(config->dev, gpio_mux, GPIOF_DIR_IN,
+					    name);
+		if (ret < 0)
+			goto err;
+
+		/*
+		 * Let the regulator know that its register set A/B
+		 * will be selected through GPI for voltage ramping.
+		 */
+		ret = da9055_reg_update(regulator->da9055, info->conf.reg,
+					DA9055_V_GPI_MASK,
+					pdata->reg_rsel[id]
+					<< DA9055_V_GPI_SHIFT);
+	}
+
+err:
+	return ret;
+}
+
+static irqreturn_t da9055_ldo5_6_oc_irq(int irq, void *data)
+{
+	struct da9055_regulator *regulator = data;
+
+	regulator_notifier_call_chain(regulator->rdev,
+				      REGULATOR_EVENT_OVER_CURRENT, NULL);
+
+	return IRQ_HANDLED;
+}
+
+static inline struct da9055_regulator_info *find_regulator_info(int id)
+{
+	struct da9055_regulator_info *info;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(da9055_regulator_info); i++) {
+		info = &da9055_regulator_info[i];
+		if (info->reg_desc.id == id)
+			return info;
+	}
+
+	return NULL;
+}
+
+static int __devinit da9055_regulator_probe(struct platform_device *pdev)
+{
+	struct regulator_config config = { };
+	struct da9055_regulator *regulator;
+	struct da9055 *da9055 = dev_get_drvdata(pdev->dev.parent);
+	struct da9055_pdata *pdata = da9055->dev->platform_data;
+	int ret, irq;
+
+	if (pdata == NULL || pdata->regulators[pdev->id] == NULL)
+		return -ENODEV;
+
+	regulator = devm_kzalloc(&pdev->dev, sizeof(struct da9055_regulator),
+				 GFP_KERNEL);
+	if (!regulator)
+		return -ENOMEM;
+
+	regulator->info = find_regulator_info(pdev->id);
+	if (regulator->info == NULL) {
+		dev_err(&pdev->dev, "invalid regulator ID specified\n");
+		return -EINVAL;
+	}
+
+	regulator->da9055 = da9055;
+	config.dev = &pdev->dev;
+	config.driver_data = regulator;
+	config.regmap = da9055->regmap;
+
+	if (pdata && pdata->regulators)
+		config.init_data = pdata->regulators[pdev->id];
+
+	ret = da9055_gpio_init(regulator, &config, pdata, pdev->id);
+	if (ret < 0)
+		return ret;
+
+	regulator->rdev = regulator_register(&regulator->info->reg_desc,
+					     &config);
+	if (IS_ERR(regulator->rdev)) {
+		dev_err(&pdev->dev, "Failed to register regulator %s\n",
+			regulator->info->reg_desc.name);
+		ret = PTR_ERR(regulator->rdev);
+		return ret;
+	}
+
+	/* Only LDO 5 and 6 has got the over current interrupt */
+	if (pdev->id == DA9055_ID_LDO5 || pdev->id ==  DA9055_ID_LDO6) {
+		irq = platform_get_irq_byname(pdev, "REGULATOR");
+		irq = regmap_irq_get_virq(da9055->irq_data, irq);
+		ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
+						da9055_ldo5_6_oc_irq,
+						IRQF_TRIGGER_HIGH |
+						IRQF_ONESHOT |
+						IRQF_PROBE_SHARED,
+						pdev->name, regulator);
+		if (ret != 0) {
+			if (ret != -EBUSY) {
+				dev_err(&pdev->dev,
+				"Failed to request Regulator IRQ %d: %d\n",
+				irq, ret);
+				goto err_regulator;
+			}
+		}
+	}
+
+	platform_set_drvdata(pdev, regulator);
+
+	return 0;
+
+err_regulator:
+	regulator_unregister(regulator->rdev);
+	return ret;
+}
+
+static int __devexit da9055_regulator_remove(struct platform_device *pdev)
+{
+	struct da9055_regulator *regulator = platform_get_drvdata(pdev);
+
+	regulator_unregister(regulator->rdev);
+
+	return 0;
+}
+
+static struct platform_driver da9055_regulator_driver = {
+	.probe = da9055_regulator_probe,
+	.remove = __devexit_p(da9055_regulator_remove),
+	.driver = {
+		.name = "da9055-regulator",
+		.owner = THIS_MODULE,
+	},
+};
+
+static int __init da9055_regulator_init(void)
+{
+	return platform_driver_register(&da9055_regulator_driver);
+}
+subsys_initcall(da9055_regulator_init);
+
+static void __exit da9055_regulator_exit(void)
+{
+	platform_driver_unregister(&da9055_regulator_driver);
+}
+module_exit(da9055_regulator_exit);
+
+MODULE_AUTHOR("David Dajun Chen <dchen@diasemi.com>");
+MODULE_DESCRIPTION("Power Regulator driver for Dialog DA9055 PMIC");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:da9055-regulator");
diff --git a/drivers/regulator/db8500-prcmu.c b/drivers/regulator/db8500-prcmu.c
index 359f8d1..219d162 100644
--- a/drivers/regulator/db8500-prcmu.c
+++ b/drivers/regulator/db8500-prcmu.c
@@ -412,7 +412,7 @@
 	},
 };
 
-static __devinit int db8500_regulator_register(struct platform_device *pdev,
+static int db8500_regulator_register(struct platform_device *pdev,
 					struct regulator_init_data *init_data,
 					int id,
 					struct device_node *np)
@@ -474,7 +474,7 @@
 	{ .name	= "db8500_esram34_ret",   .driver_data = (void *) DB8500_REGULATOR_SWITCH_ESRAM34RET, },
 };
 
-static __devinit int
+static int
 db8500_regulator_of_probe(struct platform_device *pdev,
 			struct device_node *np)
 {
@@ -491,7 +491,7 @@
 	return 0;
 }
 
-static int __devinit db8500_regulator_probe(struct platform_device *pdev)
+static int db8500_regulator_probe(struct platform_device *pdev)
 {
 	struct regulator_init_data *db8500_init_data =
 					dev_get_platdata(&pdev->dev);
diff --git a/drivers/regulator/dbx500-prcmu.c b/drivers/regulator/dbx500-prcmu.c
index f2e5ecd..261f3d2 100644
--- a/drivers/regulator/dbx500-prcmu.c
+++ b/drivers/regulator/dbx500-prcmu.c
@@ -173,7 +173,7 @@
 	return 0;
 }
 
-int __devinit
+int
 ux500_regulator_debug_init(struct platform_device *pdev,
 	struct dbx500_regulator_info *regulator_info,
 	int num_regulators)
@@ -230,7 +230,7 @@
 	return -ENOMEM;
 }
 
-int __devexit ux500_regulator_debug_exit(void)
+int ux500_regulator_debug_exit(void)
 {
 	debugfs_remove_recursive(rdebug.dir);
 	kfree(rdebug.state_after_suspend);
diff --git a/drivers/regulator/dummy.c b/drivers/regulator/dummy.c
index 03a1d7c..df9f425 100644
--- a/drivers/regulator/dummy.c
+++ b/drivers/regulator/dummy.c
@@ -37,7 +37,7 @@
 	.ops = &dummy_ops,
 };
 
-static int __devinit dummy_regulator_probe(struct platform_device *pdev)
+static int dummy_regulator_probe(struct platform_device *pdev)
 {
 	struct regulator_config config = { };
 	int ret;
diff --git a/drivers/regulator/fan53555.c b/drivers/regulator/fan53555.c
index 339f4d7..9165b0c 100644
--- a/drivers/regulator/fan53555.c
+++ b/drivers/regulator/fan53555.c
@@ -230,7 +230,7 @@
 	.val_bits = 8,
 };
 
-static int __devinit fan53555_regulator_probe(struct i2c_client *client,
+static int fan53555_regulator_probe(struct i2c_client *client,
 				const struct i2c_device_id *id)
 {
 	struct fan53555_device_info *di;
@@ -293,7 +293,7 @@
 
 }
 
-static int __devexit fan53555_regulator_remove(struct i2c_client *client)
+static int fan53555_regulator_remove(struct i2c_client *client)
 {
 	struct fan53555_device_info *di = i2c_get_clientdata(client);
 
@@ -311,7 +311,7 @@
 		.name = "fan53555-regulator",
 	},
 	.probe = fan53555_regulator_probe,
-	.remove = __devexit_p(fan53555_regulator_remove),
+	.remove = fan53555_regulator_remove,
 	.id_table = fan53555_id,
 };
 
diff --git a/drivers/regulator/fixed.c b/drivers/regulator/fixed.c
index 185468c..48d5b76 100644
--- a/drivers/regulator/fixed.c
+++ b/drivers/regulator/fixed.c
@@ -134,7 +134,7 @@
 	.list_voltage = fixed_voltage_list_voltage,
 };
 
-static int __devinit reg_fixed_voltage_probe(struct platform_device *pdev)
+static int reg_fixed_voltage_probe(struct platform_device *pdev)
 {
 	struct fixed_voltage_config *config;
 	struct fixed_voltage_data *drvdata;
@@ -234,7 +234,7 @@
 	return ret;
 }
 
-static int __devexit reg_fixed_voltage_remove(struct platform_device *pdev)
+static int reg_fixed_voltage_remove(struct platform_device *pdev)
 {
 	struct fixed_voltage_data *drvdata = platform_get_drvdata(pdev);
 
@@ -255,7 +255,7 @@
 
 static struct platform_driver regulator_fixed_voltage_driver = {
 	.probe		= reg_fixed_voltage_probe,
-	.remove		= __devexit_p(reg_fixed_voltage_remove),
+	.remove		= reg_fixed_voltage_remove,
 	.driver		= {
 		.name		= "reg-fixed-voltage",
 		.owner		= THIS_MODULE,
diff --git a/drivers/regulator/gpio-regulator.c b/drivers/regulator/gpio-regulator.c
index 8b5944f..8ae288f 100644
--- a/drivers/regulator/gpio-regulator.c
+++ b/drivers/regulator/gpio-regulator.c
@@ -28,9 +28,12 @@
 #include <linux/platform_device.h>
 #include <linux/regulator/driver.h>
 #include <linux/regulator/machine.h>
+#include <linux/regulator/of_regulator.h>
 #include <linux/regulator/gpio-regulator.h>
 #include <linux/gpio.h>
 #include <linux/slab.h>
+#include <linux/of.h>
+#include <linux/of_gpio.h>
 
 struct gpio_regulator_data {
 	struct regulator_desc desc;
@@ -79,7 +82,7 @@
 
 	for (ptr = 0; ptr < data->nr_gpios; ptr++) {
 		state = (target & (1 << ptr)) >> ptr;
-		gpio_set_value(data->gpios[ptr].gpio, state);
+		gpio_set_value_cansleep(data->gpios[ptr].gpio, state);
 	}
 	data->state = target;
 
@@ -116,7 +119,7 @@
 
 	for (ptr = 0; ptr < data->nr_gpios; ptr++) {
 		state = (target & (1 << ptr)) >> ptr;
-		gpio_set_value(data->gpios[ptr].gpio, state);
+		gpio_set_value_cansleep(data->gpios[ptr].gpio, state);
 	}
 	data->state = target;
 
@@ -129,18 +132,108 @@
 	.list_voltage = gpio_regulator_list_voltage,
 };
 
+struct gpio_regulator_config *
+of_get_gpio_regulator_config(struct device *dev, struct device_node *np)
+{
+	struct gpio_regulator_config *config;
+	struct property *prop;
+	const char *regtype;
+	int proplen, gpio, i;
+
+	config = devm_kzalloc(dev,
+			sizeof(struct gpio_regulator_config),
+			GFP_KERNEL);
+	if (!config)
+		return ERR_PTR(-ENOMEM);
+
+	config->init_data = of_get_regulator_init_data(dev, np);
+	if (!config->init_data)
+		return ERR_PTR(-EINVAL);
+
+	config->supply_name = config->init_data->constraints.name;
+
+	if (of_property_read_bool(np, "enable-active-high"))
+		config->enable_high = true;
+
+	if (of_property_read_bool(np, "enable-at-boot"))
+		config->enabled_at_boot = true;
+
+	of_property_read_u32(np, "startup-delay-us", &config->startup_delay);
+
+	config->enable_gpio = of_get_named_gpio(np, "enable-gpio", 0);
+
+	/* Fetch GPIOs. */
+	for (i = 0; ; i++)
+		if (of_get_named_gpio(np, "gpios", i) < 0)
+			break;
+	config->nr_gpios = i;
+
+	config->gpios = devm_kzalloc(dev,
+				sizeof(struct gpio) * config->nr_gpios,
+				GFP_KERNEL);
+	if (!config->gpios)
+		return ERR_PTR(-ENOMEM);
+
+	for (i = 0; i < config->nr_gpios; i++) {
+		gpio = of_get_named_gpio(np, "gpios", i);
+		if (gpio < 0)
+			break;
+		config->gpios[i].gpio = gpio;
+	}
+
+	/* Fetch states. */
+	prop = of_find_property(np, "states", NULL);
+	if (!prop) {
+		dev_err(dev, "No 'states' property found\n");
+		return ERR_PTR(-EINVAL);
+	}
+
+	proplen = prop->length / sizeof(int);
+
+	config->states = devm_kzalloc(dev,
+				sizeof(struct gpio_regulator_state)
+				* (proplen / 2),
+				GFP_KERNEL);
+	if (!config->states)
+		return ERR_PTR(-ENOMEM);
+
+	for (i = 0; i < proplen / 2; i++) {
+		config->states[i].value =
+			be32_to_cpup((int *)prop->value + (i * 2));
+		config->states[i].gpios =
+			be32_to_cpup((int *)prop->value + (i * 2 + 1));
+	}
+	config->nr_states = i;
+
+	of_property_read_string(np, "regulator-type", &regtype);
+
+	if (!strncmp("voltage", regtype, 7))
+		config->type = REGULATOR_VOLTAGE;
+	else if (!strncmp("current", regtype, 7))
+		config->type = REGULATOR_CURRENT;
+
+	return config;
+}
+
 static struct regulator_ops gpio_regulator_current_ops = {
 	.get_current_limit = gpio_regulator_get_value,
 	.set_current_limit = gpio_regulator_set_current_limit,
 };
 
-static int __devinit gpio_regulator_probe(struct platform_device *pdev)
+static int gpio_regulator_probe(struct platform_device *pdev)
 {
 	struct gpio_regulator_config *config = pdev->dev.platform_data;
+	struct device_node *np = pdev->dev.of_node;
 	struct gpio_regulator_data *drvdata;
 	struct regulator_config cfg = { };
 	int ptr, ret, state;
 
+	if (np) {
+		config = of_get_gpio_regulator_config(&pdev->dev, np);
+		if (IS_ERR(config))
+			return PTR_ERR(config);
+	}
+
 	drvdata = devm_kzalloc(&pdev->dev, sizeof(struct gpio_regulator_data),
 			       GFP_KERNEL);
 	if (drvdata == NULL) {
@@ -215,6 +308,7 @@
 	cfg.dev = &pdev->dev;
 	cfg.init_data = config->init_data;
 	cfg.driver_data = drvdata;
+	cfg.of_node = np;
 
 	if (config->enable_gpio >= 0)
 		cfg.ena_gpio = config->enable_gpio;
@@ -254,7 +348,7 @@
 	return ret;
 }
 
-static int __devexit gpio_regulator_remove(struct platform_device *pdev)
+static int gpio_regulator_remove(struct platform_device *pdev)
 {
 	struct gpio_regulator_data *drvdata = platform_get_drvdata(pdev);
 
@@ -270,12 +364,20 @@
 	return 0;
 }
 
+#if defined(CONFIG_OF)
+static const struct of_device_id regulator_gpio_of_match[] __devinitconst = {
+	{ .compatible = "regulator-gpio", },
+	{},
+};
+#endif
+
 static struct platform_driver gpio_regulator_driver = {
 	.probe		= gpio_regulator_probe,
-	.remove		= __devexit_p(gpio_regulator_remove),
+	.remove		= gpio_regulator_remove,
 	.driver		= {
 		.name		= "gpio-regulator",
 		.owner		= THIS_MODULE,
+		.of_match_table = of_match_ptr(regulator_gpio_of_match),
 	},
 };
 
diff --git a/drivers/regulator/isl6271a-regulator.c b/drivers/regulator/isl6271a-regulator.c
index d8ecf49a..d1e5bee 100644
--- a/drivers/regulator/isl6271a-regulator.c
+++ b/drivers/regulator/isl6271a-regulator.c
@@ -106,7 +106,7 @@
 	},
 };
 
-static int __devinit isl6271a_probe(struct i2c_client *i2c,
+static int isl6271a_probe(struct i2c_client *i2c,
 				     const struct i2c_device_id *id)
 {
 	struct regulator_config config = { };
@@ -151,7 +151,7 @@
 	return err;
 }
 
-static int __devexit isl6271a_remove(struct i2c_client *i2c)
+static int isl6271a_remove(struct i2c_client *i2c)
 {
 	struct isl_pmic *pmic = i2c_get_clientdata(i2c);
 	int i;
@@ -174,7 +174,7 @@
 		.owner = THIS_MODULE,
 	},
 	.probe = isl6271a_probe,
-	.remove = __devexit_p(isl6271a_remove),
+	.remove = isl6271a_remove,
 	.id_table = isl6271a_id,
 };
 
diff --git a/drivers/regulator/lp3971.c b/drivers/regulator/lp3971.c
index 7c6e3b8..5f68ff1 100644
--- a/drivers/regulator/lp3971.c
+++ b/drivers/regulator/lp3971.c
@@ -386,7 +386,7 @@
 	return ret;
 }
 
-static int __devinit setup_regulators(struct lp3971 *lp3971,
+static int setup_regulators(struct lp3971 *lp3971,
 				      struct lp3971_platform_data *pdata)
 {
 	int i, err;
@@ -429,7 +429,7 @@
 	return err;
 }
 
-static int __devinit lp3971_i2c_probe(struct i2c_client *i2c,
+static int lp3971_i2c_probe(struct i2c_client *i2c,
 			    const struct i2c_device_id *id)
 {
 	struct lp3971 *lp3971;
@@ -472,7 +472,7 @@
 	return ret;
 }
 
-static int __devexit lp3971_i2c_remove(struct i2c_client *i2c)
+static int lp3971_i2c_remove(struct i2c_client *i2c)
 {
 	struct lp3971 *lp3971 = i2c_get_clientdata(i2c);
 	int i;
@@ -498,7 +498,7 @@
 		.owner = THIS_MODULE,
 	},
 	.probe    = lp3971_i2c_probe,
-	.remove   = __devexit_p(lp3971_i2c_remove),
+	.remove   = lp3971_i2c_remove,
 	.id_table = lp3971_i2c_id,
 };
 
diff --git a/drivers/regulator/lp3972.c b/drivers/regulator/lp3972.c
index 3cdc755..69c42c3 100644
--- a/drivers/regulator/lp3972.c
+++ b/drivers/regulator/lp3972.c
@@ -481,7 +481,7 @@
 	},
 };
 
-static int __devinit setup_regulators(struct lp3972 *lp3972,
+static int setup_regulators(struct lp3972 *lp3972,
 	struct lp3972_platform_data *pdata)
 {
 	int i, err;
@@ -523,7 +523,7 @@
 	return err;
 }
 
-static int __devinit lp3972_i2c_probe(struct i2c_client *i2c,
+static int lp3972_i2c_probe(struct i2c_client *i2c,
 			    const struct i2c_device_id *id)
 {
 	struct lp3972 *lp3972;
@@ -569,7 +569,7 @@
 	return ret;
 }
 
-static int __devexit lp3972_i2c_remove(struct i2c_client *i2c)
+static int lp3972_i2c_remove(struct i2c_client *i2c)
 {
 	struct lp3972 *lp3972 = i2c_get_clientdata(i2c);
 	int i;
@@ -594,7 +594,7 @@
 		.owner = THIS_MODULE,
 	},
 	.probe    = lp3972_i2c_probe,
-	.remove   = __devexit_p(lp3972_i2c_remove),
+	.remove   = lp3972_i2c_remove,
 	.id_table = lp3972_i2c_id,
 };
 
diff --git a/drivers/regulator/lp872x.c b/drivers/regulator/lp872x.c
index 708f4b6..9289ead 100644
--- a/drivers/regulator/lp872x.c
+++ b/drivers/regulator/lp872x.c
@@ -893,7 +893,7 @@
 	return ret;
 }
 
-static int __devexit lp872x_remove(struct i2c_client *cl)
+static int lp872x_remove(struct i2c_client *cl)
 {
 	struct lp872x *lp = i2c_get_clientdata(cl);
 
@@ -914,7 +914,7 @@
 		.owner = THIS_MODULE,
 	},
 	.probe = lp872x_probe,
-	.remove = __devexit_p(lp872x_remove),
+	.remove = lp872x_remove,
 	.id_table = lp872x_ids,
 };
 
diff --git a/drivers/regulator/lp8788-buck.c b/drivers/regulator/lp8788-buck.c
index ba3e0aa..aef3f2b 100644
--- a/drivers/regulator/lp8788-buck.c
+++ b/drivers/regulator/lp8788-buck.c
@@ -429,18 +429,6 @@
 	},
 };
 
-static int _gpio_request(struct lp8788_buck *buck, int gpio, char *name)
-{
-	struct device *dev = buck->lp->dev;
-
-	if (!gpio_is_valid(gpio)) {
-		dev_err(dev, "invalid gpio: %d\n", gpio);
-		return -EINVAL;
-	}
-
-	return devm_gpio_request_one(dev, gpio, DVS_LOW, name);
-}
-
 static int lp8788_dvs_gpio_request(struct lp8788_buck *buck,
 				enum lp8788_buck_id id)
 {
@@ -452,7 +440,8 @@
 	switch (id) {
 	case BUCK1:
 		gpio = pdata->buck1_dvs->gpio;
-		ret = _gpio_request(buck, gpio, b1_name);
+		ret = devm_gpio_request_one(buck->lp->dev, gpio, DVS_LOW,
+					    b1_name);
 		if (ret)
 			return ret;
 
@@ -461,7 +450,8 @@
 	case BUCK2:
 		for (i = 0 ; i < LP8788_NUM_BUCK2_DVS ; i++) {
 			gpio = pdata->buck2_dvs->gpio[i];
-			ret = _gpio_request(buck, gpio, b2_name[i]);
+			ret = devm_gpio_request_one(buck->lp->dev, gpio,
+						    DVS_LOW, b2_name[i]);
 			if (ret)
 				return ret;
 		}
@@ -504,7 +494,7 @@
 				  default_dvs_mode[id]);
 }
 
-static __devinit int lp8788_buck_probe(struct platform_device *pdev)
+static int lp8788_buck_probe(struct platform_device *pdev)
 {
 	struct lp8788 *lp = dev_get_drvdata(pdev->dev.parent);
 	int id = pdev->id;
@@ -542,7 +532,7 @@
 	return 0;
 }
 
-static int __devexit lp8788_buck_remove(struct platform_device *pdev)
+static int lp8788_buck_remove(struct platform_device *pdev)
 {
 	struct lp8788_buck *buck = platform_get_drvdata(pdev);
 
@@ -554,7 +544,7 @@
 
 static struct platform_driver lp8788_buck_driver = {
 	.probe = lp8788_buck_probe,
-	.remove = __devexit_p(lp8788_buck_remove),
+	.remove = lp8788_buck_remove,
 	.driver = {
 		.name = LP8788_DEV_BUCK,
 		.owner = THIS_MODULE,
diff --git a/drivers/regulator/lp8788-ldo.c b/drivers/regulator/lp8788-ldo.c
index 6796eeb..3792741 100644
--- a/drivers/regulator/lp8788-ldo.c
+++ b/drivers/regulator/lp8788-ldo.c
@@ -126,7 +126,7 @@
 };
 
 /* DLDO 1, 2, 3, 9 voltage table */
-const int lp8788_dldo1239_vtbl[] = {
+static const int lp8788_dldo1239_vtbl[] = {
 	1800000, 1900000, 2000000, 2100000, 2200000, 2300000, 2400000, 2500000,
 	2600000, 2700000, 2800000, 2900000, 3000000, 2850000, 2850000, 2850000,
 	2850000, 2850000, 2850000, 2850000, 2850000, 2850000, 2850000, 2850000,
@@ -662,14 +662,6 @@
 		[EN_DLDO7]   = LP8788_EN_SEL_DLDO7_M,
 		[EN_DLDO911] = LP8788_EN_SEL_DLDO911_M,
 	};
-	u8 val[] = {
-		[EN_ALDO1]   = 0 << 5,
-		[EN_ALDO234] = 0 << 4,
-		[EN_ALDO5]   = 0 << 3,
-		[EN_ALDO7]   = 0 << 2,
-		[EN_DLDO7]   = 0 << 1,
-		[EN_DLDO911] = 0 << 0,
-	};
 
 	switch (id) {
 	case DLDO7:
@@ -708,11 +700,10 @@
 	return ret;
 
 set_default_ldo_enable_mode:
-	return lp8788_update_bits(lp, LP8788_EN_SEL, en_mask[enable_id],
-				val[enable_id]);
+	return lp8788_update_bits(lp, LP8788_EN_SEL, en_mask[enable_id], 0);
 }
 
-static __devinit int lp8788_dldo_probe(struct platform_device *pdev)
+static int lp8788_dldo_probe(struct platform_device *pdev)
 {
 	struct lp8788 *lp = dev_get_drvdata(pdev->dev.parent);
 	int id = pdev->id;
@@ -749,7 +740,7 @@
 	return 0;
 }
 
-static int __devexit lp8788_dldo_remove(struct platform_device *pdev)
+static int lp8788_dldo_remove(struct platform_device *pdev)
 {
 	struct lp8788_ldo *ldo = platform_get_drvdata(pdev);
 
@@ -761,14 +752,14 @@
 
 static struct platform_driver lp8788_dldo_driver = {
 	.probe = lp8788_dldo_probe,
-	.remove = __devexit_p(lp8788_dldo_remove),
+	.remove = lp8788_dldo_remove,
 	.driver = {
 		.name = LP8788_DEV_DLDO,
 		.owner = THIS_MODULE,
 	},
 };
 
-static __devinit int lp8788_aldo_probe(struct platform_device *pdev)
+static int lp8788_aldo_probe(struct platform_device *pdev)
 {
 	struct lp8788 *lp = dev_get_drvdata(pdev->dev.parent);
 	int id = pdev->id;
@@ -805,7 +796,7 @@
 	return 0;
 }
 
-static int __devexit lp8788_aldo_remove(struct platform_device *pdev)
+static int lp8788_aldo_remove(struct platform_device *pdev)
 {
 	struct lp8788_ldo *ldo = platform_get_drvdata(pdev);
 
@@ -817,7 +808,7 @@
 
 static struct platform_driver lp8788_aldo_driver = {
 	.probe = lp8788_aldo_probe,
-	.remove = __devexit_p(lp8788_aldo_remove),
+	.remove = lp8788_aldo_remove,
 	.driver = {
 		.name = LP8788_DEV_ALDO,
 		.owner = THIS_MODULE,
diff --git a/drivers/regulator/max1586.c b/drivers/regulator/max1586.c
index f67af3c..8c5a54f 100644
--- a/drivers/regulator/max1586.c
+++ b/drivers/regulator/max1586.c
@@ -44,6 +44,9 @@
 	unsigned int min_uV;
 	unsigned int max_uV;
 
+	unsigned int v3_curr_sel;
+	unsigned int v6_curr_sel;
+
 	struct regulator_dev *rdev[0];
 };
 
@@ -63,31 +66,60 @@
  * R24 and R25=100kOhm as described in the data sheet.
  * The gain is approximately: 1 + R24/R25 + R24/185.5kOhm
  */
+static int max1586_v3_get_voltage_sel(struct regulator_dev *rdev)
+{
+	struct max1586_data *max1586 = rdev_get_drvdata(rdev);
+
+	return max1586->v3_curr_sel;
+}
+
 static int max1586_v3_set_voltage_sel(struct regulator_dev *rdev,
 				      unsigned selector)
 {
 	struct max1586_data *max1586 = rdev_get_drvdata(rdev);
 	struct i2c_client *client = max1586->client;
+	int ret;
 	u8 v3_prog;
 
 	dev_dbg(&client->dev, "changing voltage v3 to %dmv\n",
 		regulator_list_voltage_linear(rdev, selector) / 1000);
 
 	v3_prog = I2C_V3_SELECT | (u8) selector;
-	return i2c_smbus_write_byte(client, v3_prog);
+	ret = i2c_smbus_write_byte(client, v3_prog);
+	if (ret)
+		return ret;
+
+	max1586->v3_curr_sel = selector;
+
+	return 0;
+}
+
+static int max1586_v6_get_voltage_sel(struct regulator_dev *rdev)
+{
+	struct max1586_data *max1586 = rdev_get_drvdata(rdev);
+
+	return max1586->v6_curr_sel;
 }
 
 static int max1586_v6_set_voltage_sel(struct regulator_dev *rdev,
 				      unsigned int selector)
 {
-	struct i2c_client *client = rdev_get_drvdata(rdev);
+	struct max1586_data *max1586 = rdev_get_drvdata(rdev);
+	struct i2c_client *client = max1586->client;
 	u8 v6_prog;
+	int ret;
 
 	dev_dbg(&client->dev, "changing voltage v6 to %dmv\n",
 		rdev->desc->volt_table[selector] / 1000);
 
 	v6_prog = I2C_V6_SELECT | (u8) selector;
-	return i2c_smbus_write_byte(client, v6_prog);
+	ret = i2c_smbus_write_byte(client, v6_prog);
+	if (ret)
+		return ret;
+
+	max1586->v6_curr_sel = selector;
+
+	return 0;
 }
 
 /*
@@ -95,12 +127,14 @@
  * the set up value.
  */
 static struct regulator_ops max1586_v3_ops = {
+	.get_voltage_sel = max1586_v3_get_voltage_sel,
 	.set_voltage_sel = max1586_v3_set_voltage_sel,
 	.list_voltage = regulator_list_voltage_linear,
 	.map_voltage = regulator_map_voltage_linear,
 };
 
 static struct regulator_ops max1586_v6_ops = {
+	.get_voltage_sel = max1586_v6_get_voltage_sel,
 	.set_voltage_sel = max1586_v6_set_voltage_sel,
 	.list_voltage = regulator_list_voltage_table,
 };
@@ -125,7 +159,7 @@
 	},
 };
 
-static int __devinit max1586_pmic_probe(struct i2c_client *client,
+static int max1586_pmic_probe(struct i2c_client *client,
 					const struct i2c_device_id *i2c_id)
 {
 	struct regulator_dev **rdev;
@@ -148,6 +182,10 @@
 	max1586->min_uV = MAX1586_V3_MIN_UV / 1000 * pdata->v3_gain / 1000;
 	max1586->max_uV = MAX1586_V3_MAX_UV / 1000 * pdata->v3_gain / 1000;
 
+	/* Set curr_sel to default voltage on power-up */
+	max1586->v3_curr_sel = 24; /* 1.3V */
+	max1586->v6_curr_sel = 0;
+
 	rdev = max1586->rdev;
 	for (i = 0; i < pdata->num_subdevs && i <= MAX1586_V6; i++) {
 		id = pdata->subdevs[i].id;
@@ -188,7 +226,7 @@
 	return ret;
 }
 
-static int __devexit max1586_pmic_remove(struct i2c_client *client)
+static int max1586_pmic_remove(struct i2c_client *client)
 {
 	struct max1586_data *max1586 = i2c_get_clientdata(client);
 	int i;
@@ -207,7 +245,7 @@
 
 static struct i2c_driver max1586_pmic_driver = {
 	.probe = max1586_pmic_probe,
-	.remove = __devexit_p(max1586_pmic_remove),
+	.remove = max1586_pmic_remove,
 	.driver		= {
 		.name	= "max1586",
 		.owner	= THIS_MODULE,
diff --git a/drivers/regulator/max77686.c b/drivers/regulator/max77686.c
index 2a67d08..b85040c 100644
--- a/drivers/regulator/max77686.c
+++ b/drivers/regulator/max77686.c
@@ -67,8 +67,94 @@
 
 struct max77686_data {
 	struct regulator_dev *rdev[MAX77686_REGULATORS];
+	unsigned int opmode[MAX77686_REGULATORS];
 };
 
+/* Some BUCKS supports Normal[ON/OFF] mode during suspend */
+static int max77686_buck_set_suspend_disable(struct regulator_dev *rdev)
+{
+	unsigned int val;
+	struct max77686_data *max77686 = rdev_get_drvdata(rdev);
+
+	if (rdev->desc->id == MAX77686_BUCK1)
+		val = 0x1;
+	else
+		val = 0x1 << MAX77686_OPMODE_BUCK234_SHIFT;
+
+	max77686->opmode[rdev->desc->id] = val;
+	return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
+				  rdev->desc->enable_mask,
+				  val);
+}
+
+/* Some LDOs supports [LPM/Normal]ON mode during suspend state */
+static int max77686_set_suspend_mode(struct regulator_dev *rdev,
+				     unsigned int mode)
+{
+	struct max77686_data *max77686 = rdev_get_drvdata(rdev);
+	unsigned int val;
+
+	/* BUCK[5-9] doesn't support this feature */
+	if (rdev->desc->id >= MAX77686_BUCK5)
+		return 0;
+
+	switch (mode) {
+	case REGULATOR_MODE_IDLE:			/* ON in LP Mode */
+		val = 0x2 << MAX77686_OPMODE_SHIFT;
+		break;
+	case REGULATOR_MODE_NORMAL:			/* ON in Normal Mode */
+		val = 0x3 << MAX77686_OPMODE_SHIFT;
+		break;
+	default:
+		pr_warn("%s: regulator_suspend_mode : 0x%x not supported\n",
+			rdev->desc->name, mode);
+		return -EINVAL;
+	}
+
+	max77686->opmode[rdev->desc->id] = val;
+	return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
+				  rdev->desc->enable_mask,
+				  val);
+}
+
+/* Some LDOs supports LPM-ON/OFF/Normal-ON mode during suspend state */
+static int max77686_ldo_set_suspend_mode(struct regulator_dev *rdev,
+				     unsigned int mode)
+{
+	unsigned int val;
+	struct max77686_data *max77686 = rdev_get_drvdata(rdev);
+
+	switch (mode) {
+	case REGULATOR_MODE_STANDBY:			/* switch off */
+		val = 0x1 << MAX77686_OPMODE_SHIFT;
+		break;
+	case REGULATOR_MODE_IDLE:			/* ON in LP Mode */
+		val = 0x2 << MAX77686_OPMODE_SHIFT;
+		break;
+	case REGULATOR_MODE_NORMAL:			/* ON in Normal Mode */
+		val = 0x3 << MAX77686_OPMODE_SHIFT;
+		break;
+	default:
+		pr_warn("%s: regulator_suspend_mode : 0x%x not supported\n",
+			rdev->desc->name, mode);
+		return -EINVAL;
+	}
+
+	max77686->opmode[rdev->desc->id] = val;
+	return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
+				  rdev->desc->enable_mask,
+				  val);
+}
+
+static int max77686_enable(struct regulator_dev *rdev)
+{
+	struct max77686_data *max77686 = rdev_get_drvdata(rdev);
+
+	return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
+				  rdev->desc->enable_mask,
+				  max77686->opmode[rdev->desc->id]);
+}
+
 static int max77686_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay)
 {
 	unsigned int ramp_value = RAMP_RATE_NO_CTRL;
@@ -98,23 +184,49 @@
 	.list_voltage		= regulator_list_voltage_linear,
 	.map_voltage		= regulator_map_voltage_linear,
 	.is_enabled		= regulator_is_enabled_regmap,
-	.enable			= regulator_enable_regmap,
+	.enable			= max77686_enable,
 	.disable		= regulator_disable_regmap,
 	.get_voltage_sel	= regulator_get_voltage_sel_regmap,
 	.set_voltage_sel	= regulator_set_voltage_sel_regmap,
 	.set_voltage_time_sel	= regulator_set_voltage_time_sel,
+	.set_suspend_mode	= max77686_set_suspend_mode,
+};
+
+static struct regulator_ops max77686_ldo_ops = {
+	.list_voltage		= regulator_list_voltage_linear,
+	.map_voltage		= regulator_map_voltage_linear,
+	.is_enabled		= regulator_is_enabled_regmap,
+	.enable			= max77686_enable,
+	.disable		= regulator_disable_regmap,
+	.get_voltage_sel	= regulator_get_voltage_sel_regmap,
+	.set_voltage_sel	= regulator_set_voltage_sel_regmap,
+	.set_voltage_time_sel	= regulator_set_voltage_time_sel,
+	.set_suspend_mode	= max77686_ldo_set_suspend_mode,
+};
+
+static struct regulator_ops max77686_buck1_ops = {
+	.list_voltage		= regulator_list_voltage_linear,
+	.map_voltage		= regulator_map_voltage_linear,
+	.is_enabled		= regulator_is_enabled_regmap,
+	.enable			= max77686_enable,
+	.disable		= regulator_disable_regmap,
+	.get_voltage_sel	= regulator_get_voltage_sel_regmap,
+	.set_voltage_sel	= regulator_set_voltage_sel_regmap,
+	.set_voltage_time_sel	= regulator_set_voltage_time_sel,
+	.set_suspend_disable	= max77686_buck_set_suspend_disable,
 };
 
 static struct regulator_ops max77686_buck_dvs_ops = {
 	.list_voltage		= regulator_list_voltage_linear,
 	.map_voltage		= regulator_map_voltage_linear,
 	.is_enabled		= regulator_is_enabled_regmap,
-	.enable			= regulator_enable_regmap,
+	.enable			= max77686_enable,
 	.disable		= regulator_disable_regmap,
 	.get_voltage_sel	= regulator_get_voltage_sel_regmap,
 	.set_voltage_sel	= regulator_set_voltage_sel_regmap,
 	.set_voltage_time_sel	= regulator_set_voltage_time_sel,
 	.set_ramp_delay		= max77686_set_ramp_delay,
+	.set_suspend_disable	= max77686_buck_set_suspend_disable,
 };
 
 #define regulator_desc_ldo(num)		{				\
@@ -133,9 +245,41 @@
 	.enable_mask	= MAX77686_OPMODE_MASK				\
 			<< MAX77686_OPMODE_SHIFT,			\
 }
+#define regulator_desc_lpm_ldo(num)	{				\
+	.name		= "LDO"#num,					\
+	.id		= MAX77686_LDO##num,				\
+	.ops		= &max77686_ldo_ops,				\
+	.type		= REGULATOR_VOLTAGE,				\
+	.owner		= THIS_MODULE,					\
+	.min_uV		= MAX77686_LDO_MINUV,				\
+	.uV_step	= MAX77686_LDO_UVSTEP,				\
+	.ramp_delay	= MAX77686_RAMP_DELAY,				\
+	.n_voltages	= MAX77686_VSEL_MASK + 1,			\
+	.vsel_reg	= MAX77686_REG_LDO1CTRL1 + num - 1,		\
+	.vsel_mask	= MAX77686_VSEL_MASK,				\
+	.enable_reg	= MAX77686_REG_LDO1CTRL1 + num - 1,		\
+	.enable_mask	= MAX77686_OPMODE_MASK				\
+			<< MAX77686_OPMODE_SHIFT,			\
+}
 #define regulator_desc_ldo_low(num)		{			\
 	.name		= "LDO"#num,					\
 	.id		= MAX77686_LDO##num,				\
+	.ops		= &max77686_ldo_ops,				\
+	.type		= REGULATOR_VOLTAGE,				\
+	.owner		= THIS_MODULE,					\
+	.min_uV		= MAX77686_LDO_LOW_MINUV,			\
+	.uV_step	= MAX77686_LDO_LOW_UVSTEP,			\
+	.ramp_delay	= MAX77686_RAMP_DELAY,				\
+	.n_voltages	= MAX77686_VSEL_MASK + 1,			\
+	.vsel_reg	= MAX77686_REG_LDO1CTRL1 + num - 1,		\
+	.vsel_mask	= MAX77686_VSEL_MASK,				\
+	.enable_reg	= MAX77686_REG_LDO1CTRL1 + num - 1,		\
+	.enable_mask	= MAX77686_OPMODE_MASK				\
+			<< MAX77686_OPMODE_SHIFT,			\
+}
+#define regulator_desc_ldo1_low(num)		{			\
+	.name		= "LDO"#num,					\
+	.id		= MAX77686_LDO##num,				\
 	.ops		= &max77686_ops,				\
 	.type		= REGULATOR_VOLTAGE,				\
 	.owner		= THIS_MODULE,					\
@@ -167,7 +311,7 @@
 #define regulator_desc_buck1(num)		{			\
 	.name		= "BUCK"#num,					\
 	.id		= MAX77686_BUCK##num,				\
-	.ops		= &max77686_ops,				\
+	.ops		= &max77686_buck1_ops,				\
 	.type		= REGULATOR_VOLTAGE,				\
 	.owner		= THIS_MODULE,					\
 	.min_uV		= MAX77686_BUCK_MINUV,				\
@@ -197,7 +341,7 @@
 }
 
 static struct regulator_desc regulators[] = {
-	regulator_desc_ldo_low(1),
+	regulator_desc_ldo1_low(1),
 	regulator_desc_ldo_low(2),
 	regulator_desc_ldo(3),
 	regulator_desc_ldo(4),
@@ -206,13 +350,13 @@
 	regulator_desc_ldo_low(7),
 	regulator_desc_ldo_low(8),
 	regulator_desc_ldo(9),
-	regulator_desc_ldo(10),
-	regulator_desc_ldo(11),
-	regulator_desc_ldo(12),
+	regulator_desc_lpm_ldo(10),
+	regulator_desc_lpm_ldo(11),
+	regulator_desc_lpm_ldo(12),
 	regulator_desc_ldo(13),
-	regulator_desc_ldo(14),
+	regulator_desc_lpm_ldo(14),
 	regulator_desc_ldo_low(15),
-	regulator_desc_ldo(16),
+	regulator_desc_lpm_ldo(16),
 	regulator_desc_ldo(17),
 	regulator_desc_ldo(18),
 	regulator_desc_ldo(19),
@@ -280,7 +424,7 @@
 }
 #endif /* CONFIG_OF */
 
-static __devinit int max77686_pmic_probe(struct platform_device *pdev)
+static int max77686_pmic_probe(struct platform_device *pdev)
 {
 	struct max77686_dev *iodev = dev_get_drvdata(pdev->dev.parent);
 	struct max77686_platform_data *pdata = dev_get_platdata(iodev->dev);
@@ -314,12 +458,14 @@
 
 	config.dev = &pdev->dev;
 	config.regmap = iodev->regmap;
+	config.driver_data = max77686;
 	platform_set_drvdata(pdev, max77686);
 
 	for (i = 0; i < MAX77686_REGULATORS; i++) {
 		config.init_data = pdata->regulators[i].initdata;
 		config.of_node = pdata->regulators[i].of_node;
 
+		max77686->opmode[i] = regulators[i].enable_mask;
 		max77686->rdev[i] = regulator_register(&regulators[i], &config);
 		if (IS_ERR(max77686->rdev[i])) {
 			ret = PTR_ERR(max77686->rdev[i]);
@@ -337,7 +483,7 @@
 	return ret;
 }
 
-static int __devexit max77686_pmic_remove(struct platform_device *pdev)
+static int max77686_pmic_remove(struct platform_device *pdev)
 {
 	struct max77686_data *max77686 = platform_get_drvdata(pdev);
 	int i;
@@ -360,7 +506,7 @@
 		.owner = THIS_MODULE,
 	},
 	.probe = max77686_pmic_probe,
-	.remove = __devexit_p(max77686_pmic_remove),
+	.remove = max77686_pmic_remove,
 	.id_table = max77686_pmic_id,
 };
 
diff --git a/drivers/regulator/max8649.c b/drivers/regulator/max8649.c
index 9d540cd..3ca1438 100644
--- a/drivers/regulator/max8649.c
+++ b/drivers/regulator/max8649.c
@@ -176,7 +176,7 @@
 	.val_bits = 8,
 };
 
-static int __devinit max8649_regulator_probe(struct i2c_client *client,
+static int max8649_regulator_probe(struct i2c_client *client,
 					     const struct i2c_device_id *id)
 {
 	struct max8649_platform_data *pdata = client->dev.platform_data;
@@ -271,7 +271,7 @@
 	return 0;
 }
 
-static int __devexit max8649_regulator_remove(struct i2c_client *client)
+static int max8649_regulator_remove(struct i2c_client *client)
 {
 	struct max8649_regulator_info *info = i2c_get_clientdata(client);
 
@@ -291,7 +291,7 @@
 
 static struct i2c_driver max8649_driver = {
 	.probe		= max8649_regulator_probe,
-	.remove		= __devexit_p(max8649_regulator_remove),
+	.remove		= max8649_regulator_remove,
 	.driver		= {
 		.name	= "max8649",
 	},
diff --git a/drivers/regulator/max8660.c b/drivers/regulator/max8660.c
index 8d53174..4d7c635 100644
--- a/drivers/regulator/max8660.c
+++ b/drivers/regulator/max8660.c
@@ -305,7 +305,7 @@
 	},
 };
 
-static int __devinit max8660_probe(struct i2c_client *client,
+static int max8660_probe(struct i2c_client *client,
 				   const struct i2c_device_id *i2c_id)
 {
 	struct regulator_dev **rdev;
@@ -420,7 +420,7 @@
 	return ret;
 }
 
-static int __devexit max8660_remove(struct i2c_client *client)
+static int max8660_remove(struct i2c_client *client)
 {
 	struct max8660 *max8660 = i2c_get_clientdata(client);
 	int i;
@@ -440,7 +440,7 @@
 
 static struct i2c_driver max8660_driver = {
 	.probe = max8660_probe,
-	.remove = __devexit_p(max8660_remove),
+	.remove = max8660_remove,
 	.driver		= {
 		.name	= "max8660",
 		.owner	= THIS_MODULE,
diff --git a/drivers/regulator/max8907-regulator.c b/drivers/regulator/max8907-regulator.c
index af76075..d1a7751 100644
--- a/drivers/regulator/max8907-regulator.c
+++ b/drivers/regulator/max8907-regulator.c
@@ -275,7 +275,7 @@
 }
 #endif
 
-static __devinit int max8907_regulator_probe(struct platform_device *pdev)
+static int max8907_regulator_probe(struct platform_device *pdev)
 {
 	struct max8907 *max8907 = dev_get_drvdata(pdev->dev.parent);
 	struct max8907_platform_data *pdata = dev_get_platdata(max8907->dev);
@@ -368,7 +368,7 @@
 	return ret;
 }
 
-static __devexit int max8907_regulator_remove(struct platform_device *pdev)
+static int max8907_regulator_remove(struct platform_device *pdev)
 {
 	struct max8907_regulator *pmic = platform_get_drvdata(pdev);
 	int i;
@@ -385,7 +385,7 @@
 		   .owner = THIS_MODULE,
 		   },
 	.probe = max8907_regulator_probe,
-	.remove = __devexit_p(max8907_regulator_remove),
+	.remove = max8907_regulator_remove,
 };
 
 static int __init max8907_regulator_init(void)
diff --git a/drivers/regulator/max8925-regulator.c b/drivers/regulator/max8925-regulator.c
index 9bb0be3..446a854 100644
--- a/drivers/regulator/max8925-regulator.c
+++ b/drivers/regulator/max8925-regulator.c
@@ -17,6 +17,8 @@
 #include <linux/regulator/driver.h>
 #include <linux/regulator/machine.h>
 #include <linux/mfd/max8925.h>
+#include <linux/of.h>
+#include <linux/regulator/of_regulator.h>
 
 #define SD1_DVM_VMIN		850000
 #define SD1_DVM_VMAX		1000000
@@ -187,6 +189,34 @@
 	.enable_reg	= MAX8925_LDOCTL##_id,			\
 }
 
+#ifdef CONFIG_OF
+static struct of_regulator_match max8925_regulator_matches[] = {
+	{ .name	= "SDV1",},
+	{ .name = "SDV2",},
+	{ .name = "SDV3",},
+	{ .name = "LDO1",},
+	{ .name = "LDO2",},
+	{ .name = "LDO3",},
+	{ .name = "LDO4",},
+	{ .name = "LDO5",},
+	{ .name = "LDO6",},
+	{ .name = "LDO7",},
+	{ .name = "LDO8",},
+	{ .name = "LDO9",},
+	{ .name = "LDO10",},
+	{ .name = "LDO11",},
+	{ .name = "LDO12",},
+	{ .name = "LDO13",},
+	{ .name = "LDO14",},
+	{ .name = "LDO15",},
+	{ .name = "LDO16",},
+	{ .name = "LDO17",},
+	{ .name = "LDO18",},
+	{ .name = "LDO19",},
+	{ .name = "LDO20",},
+};
+#endif
+
 static struct max8925_regulator_info max8925_regulator_info[] = {
 	MAX8925_SDV(1, 637.5, 1425, 12.5),
 	MAX8925_SDV(2,   650, 2225,   25),
@@ -214,7 +244,37 @@
 	MAX8925_LDO(20, 750, 3900, 50),
 };
 
-static int __devinit max8925_regulator_probe(struct platform_device *pdev)
+#ifdef CONFIG_OF
+static int max8925_regulator_dt_init(struct platform_device *pdev,
+				    struct max8925_regulator_info *info,
+				    struct regulator_config *config,
+				    int ridx)
+{
+	struct device_node *nproot, *np;
+	int rcount;
+	nproot = pdev->dev.parent->of_node;
+	if (!nproot)
+		return -ENODEV;
+	np = of_find_node_by_name(nproot, "regulators");
+	if (!np) {
+		dev_err(&pdev->dev, "failed to find regulators node\n");
+		return -ENODEV;
+	}
+
+	rcount = of_regulator_match(&pdev->dev, np,
+				&max8925_regulator_matches[ridx], 1);
+	if (rcount < 0)
+		return -ENODEV;
+	config->init_data =	max8925_regulator_matches[ridx].init_data;
+	config->of_node = max8925_regulator_matches[ridx].of_node;
+
+	return 0;
+}
+#else
+#define max8925_regulator_dt_init(w, x, y, z)	(-1)
+#endif
+
+static int max8925_regulator_probe(struct platform_device *pdev)
 {
 	struct max8925_chip *chip = dev_get_drvdata(pdev->dev.parent);
 	struct regulator_init_data *pdata = pdev->dev.platform_data;
@@ -222,7 +282,7 @@
 	struct max8925_regulator_info *ri;
 	struct resource *res;
 	struct regulator_dev *rdev;
-	int i;
+	int i, regulator_idx;
 
 	res = platform_get_resource(pdev, IORESOURCE_REG, 0);
 	if (!res) {
@@ -231,9 +291,12 @@
 	}
 	for (i = 0; i < ARRAY_SIZE(max8925_regulator_info); i++) {
 		ri = &max8925_regulator_info[i];
-		if (ri->vol_reg == res->start)
+		if (ri->vol_reg == res->start) {
+			regulator_idx = i;
 			break;
+		}
 	}
+
 	if (i == ARRAY_SIZE(max8925_regulator_info)) {
 		dev_err(&pdev->dev, "Failed to find regulator %llu\n",
 			(unsigned long long)res->start);
@@ -243,9 +306,12 @@
 	ri->chip = chip;
 
 	config.dev = &pdev->dev;
-	config.init_data = pdata;
 	config.driver_data = ri;
 
+	if (max8925_regulator_dt_init(pdev, ri, &config, regulator_idx))
+		if (pdata)
+			config.init_data = pdata;
+
 	rdev = regulator_register(&ri->desc, &config);
 	if (IS_ERR(rdev)) {
 		dev_err(&pdev->dev, "failed to register regulator %s\n",
@@ -257,7 +323,7 @@
 	return 0;
 }
 
-static int __devexit max8925_regulator_remove(struct platform_device *pdev)
+static int max8925_regulator_remove(struct platform_device *pdev)
 {
 	struct regulator_dev *rdev = platform_get_drvdata(pdev);
 
@@ -273,7 +339,7 @@
 		.owner	= THIS_MODULE,
 	},
 	.probe		= max8925_regulator_probe,
-	.remove		= __devexit_p(max8925_regulator_remove),
+	.remove		= max8925_regulator_remove,
 };
 
 static int __init max8925_regulator_init(void)
diff --git a/drivers/regulator/max8952.c b/drivers/regulator/max8952.c
index 355ca7b..fc7935a 100644
--- a/drivers/regulator/max8952.c
+++ b/drivers/regulator/max8952.c
@@ -126,7 +126,7 @@
 	.owner		= THIS_MODULE,
 };
 
-static int __devinit max8952_pmic_probe(struct i2c_client *client,
+static int max8952_pmic_probe(struct i2c_client *client,
 		const struct i2c_device_id *i2c_id)
 {
 	struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
@@ -247,7 +247,7 @@
 	return 0;
 }
 
-static int __devexit max8952_pmic_remove(struct i2c_client *client)
+static int max8952_pmic_remove(struct i2c_client *client)
 {
 	struct max8952_data *max8952 = i2c_get_clientdata(client);
 	struct max8952_platform_data *pdata = max8952->pdata;
@@ -268,7 +268,7 @@
 
 static struct i2c_driver max8952_pmic_driver = {
 	.probe		= max8952_pmic_probe,
-	.remove		= __devexit_p(max8952_pmic_remove),
+	.remove		= max8952_pmic_remove,
 	.driver		= {
 		.name	= "max8952",
 	},
diff --git a/drivers/regulator/max8973-regulator.c b/drivers/regulator/max8973-regulator.c
new file mode 100644
index 0000000..3ee2638
--- /dev/null
+++ b/drivers/regulator/max8973-regulator.c
@@ -0,0 +1,505 @@
+/*
+ * max8973-regulator.c -- Maxim max8973
+ *
+ * Regulator driver for MAXIM 8973 DC-DC step-down switching regulator.
+ *
+ * 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/max8973-regulator.h>
+#include <linux/gpio.h>
+#include <linux/i2c.h>
+#include <linux/slab.h>
+#include <linux/regmap.h>
+
+/* Register definitions */
+#define MAX8973_VOUT					0x0
+#define MAX8973_VOUT_DVS				0x1
+#define MAX8973_CONTROL1				0x2
+#define MAX8973_CONTROL2				0x3
+#define MAX8973_CHIPID1					0x4
+#define MAX8973_CHIPID2					0x5
+
+#define MAX8973_MAX_VOUT_REG				2
+
+/* MAX8973_VOUT */
+#define MAX8973_VOUT_ENABLE				BIT(7)
+#define MAX8973_VOUT_MASK				0x7F
+
+/* MAX8973_VOUT_DVS */
+#define MAX8973_DVS_VOUT_MASK				0x7F
+
+/* MAX8973_CONTROL1 */
+#define MAX8973_SNS_ENABLE				BIT(7)
+#define MAX8973_FPWM_EN_M				BIT(6)
+#define MAX8973_NFSR_ENABLE				BIT(5)
+#define MAX8973_AD_ENABLE				BIT(4)
+#define MAX8973_BIAS_ENABLE				BIT(3)
+#define MAX8973_FREQSHIFT_9PER				BIT(2)
+
+#define MAX8973_RAMP_12mV_PER_US			0x0
+#define MAX8973_RAMP_25mV_PER_US			0x1
+#define MAX8973_RAMP_50mV_PER_US			0x2
+#define MAX8973_RAMP_200mV_PER_US			0x3
+
+/* MAX8973_CONTROL2 */
+#define MAX8973_WDTMR_ENABLE				BIT(6)
+#define MAX8973_DISCH_ENBABLE				BIT(5)
+#define MAX8973_FT_ENABLE				BIT(4)
+
+#define MAX8973_CKKADV_TRIP_DISABLE			0xC
+#define MAX8973_CKKADV_TRIP_75mV_PER_US			0x0
+#define MAX8973_CKKADV_TRIP_150mV_PER_US		0x4
+#define MAX8973_CKKADV_TRIP_75mV_PER_US_HIST_DIS	0x8
+#define MAX8973_CONTROL_CLKADV_TRIP_MASK		0x00030000
+
+#define MAX8973_INDUCTOR_MIN_30_PER			0x0
+#define MAX8973_INDUCTOR_NOMINAL			0x1
+#define MAX8973_INDUCTOR_PLUS_30_PER			0x2
+#define MAX8973_INDUCTOR_PLUS_60_PER			0x3
+#define MAX8973_CONTROL_INDUCTOR_VALUE_MASK		0x00300000
+
+#define MAX8973_MIN_VOLATGE				606250
+#define MAX8973_MAX_VOLATGE				1400000
+#define MAX8973_VOLATGE_STEP				6250
+#define MAX8973_BUCK_N_VOLTAGE				0x80
+
+/* Maxim 8973 chip information */
+struct max8973_chip {
+	struct device *dev;
+	struct regulator_desc desc;
+	struct regulator_dev *rdev;
+	struct regmap *regmap;
+	bool enable_external_control;
+	int dvs_gpio;
+	int lru_index[MAX8973_MAX_VOUT_REG];
+	int curr_vout_val[MAX8973_MAX_VOUT_REG];
+	int curr_vout_reg;
+	int curr_gpio_val;
+	bool valid_dvs_gpio;
+};
+
+/*
+ * find_voltage_set_register: Find new voltage configuration register (VOUT).
+ * The finding of the new VOUT register will be based on the LRU mechanism.
+ * Each VOUT register will have different voltage configured . This
+ * Function will look if any of the VOUT 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 VOUT register but need to set the proper gpios to select this
+ *       VOUT register.
+ *     - If requested voltage is not found then it will use the least
+ *       recently mechanism to get new VOUT register for new configuration
+ *       and will return not_found so that caller need to set new VOUT
+ *       register and then gpios (both).
+ */
+static bool find_voltage_set_register(struct max8973_chip *tps,
+		int req_vsel, int *vout_reg, int *gpio_val)
+{
+	int i;
+	bool found = false;
+	int new_vout_reg = tps->lru_index[MAX8973_MAX_VOUT_REG - 1];
+	int found_index = MAX8973_MAX_VOUT_REG - 1;
+
+	for (i = 0; i < MAX8973_MAX_VOUT_REG; ++i) {
+		if (tps->curr_vout_val[tps->lru_index[i]] == req_vsel) {
+			new_vout_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_vout_reg;
+	*gpio_val = new_vout_reg;
+	*vout_reg = MAX8973_VOUT + new_vout_reg;
+	return found;
+}
+
+static int max8973_dcdc_get_voltage_sel(struct regulator_dev *rdev)
+{
+	struct max8973_chip *max = rdev_get_drvdata(rdev);
+	unsigned int data;
+	int ret;
+
+	ret = regmap_read(max->regmap, max->curr_vout_reg, &data);
+	if (ret < 0) {
+		dev_err(max->dev, "register %d read failed, err = %d\n",
+			max->curr_vout_reg, ret);
+		return ret;
+	}
+	return data & MAX8973_VOUT_MASK;
+}
+
+static int max8973_dcdc_set_voltage_sel(struct regulator_dev *rdev,
+	     unsigned vsel)
+{
+	struct max8973_chip *max = rdev_get_drvdata(rdev);
+	int ret;
+	bool found = false;
+	int vout_reg = max->curr_vout_reg;
+	int gpio_val = max->curr_gpio_val;
+
+	/*
+	 * If gpios are available to select the VOUT register then least
+	 * recently used register for new configuration.
+	 */
+	if (max->valid_dvs_gpio)
+		found = find_voltage_set_register(max, vsel,
+					&vout_reg, &gpio_val);
+
+	if (!found) {
+		ret = regmap_update_bits(max->regmap, vout_reg,
+					MAX8973_VOUT_MASK, vsel);
+		if (ret < 0) {
+			dev_err(max->dev, "register %d update failed, err %d\n",
+				 vout_reg, ret);
+			return ret;
+		}
+		max->curr_vout_reg = vout_reg;
+		max->curr_vout_val[gpio_val] = vsel;
+	}
+
+	/* Select proper VOUT register vio gpios */
+	if (max->valid_dvs_gpio) {
+		gpio_set_value_cansleep(max->dvs_gpio, gpio_val & 0x1);
+		max->curr_gpio_val = gpio_val;
+	}
+	return 0;
+}
+
+static int max8973_dcdc_set_mode(struct regulator_dev *rdev, unsigned int mode)
+{
+	struct max8973_chip *max = rdev_get_drvdata(rdev);
+	int ret;
+	int pwm;
+
+	/* Enable force PWM mode in FAST mode only. */
+	switch (mode) {
+	case REGULATOR_MODE_FAST:
+		pwm = MAX8973_FPWM_EN_M;
+		break;
+
+	case REGULATOR_MODE_NORMAL:
+		pwm = 0;
+		break;
+
+	default:
+		return -EINVAL;
+	}
+
+	ret = regmap_update_bits(max->regmap, MAX8973_CONTROL1,
+				MAX8973_FPWM_EN_M, pwm);
+	if (ret < 0)
+		dev_err(max->dev, "register %d update failed, err %d\n",
+				MAX8973_CONTROL1, ret);
+	return ret;
+}
+
+static unsigned int max8973_dcdc_get_mode(struct regulator_dev *rdev)
+{
+	struct max8973_chip *max = rdev_get_drvdata(rdev);
+	unsigned int data;
+	int ret;
+
+	ret = regmap_read(max->regmap, MAX8973_CONTROL1, &data);
+	if (ret < 0) {
+		dev_err(max->dev, "register %d read failed, err %d\n",
+				MAX8973_CONTROL1, ret);
+		return ret;
+	}
+	return (data & MAX8973_FPWM_EN_M) ?
+		REGULATOR_MODE_FAST : REGULATOR_MODE_NORMAL;
+}
+
+static struct regulator_ops max8973_dcdc_ops = {
+	.get_voltage_sel	= max8973_dcdc_get_voltage_sel,
+	.set_voltage_sel	= max8973_dcdc_set_voltage_sel,
+	.list_voltage		= regulator_list_voltage_linear,
+	.set_mode		= max8973_dcdc_set_mode,
+	.get_mode		= max8973_dcdc_get_mode,
+};
+
+static int __devinit max8973_init_dcdc(struct max8973_chip *max,
+		struct max8973_regulator_platform_data *pdata)
+{
+	int ret;
+	uint8_t	control1 = 0;
+	uint8_t control2 = 0;
+
+	if (pdata->control_flags & MAX8973_CONTROL_REMOTE_SENSE_ENABLE)
+		control1 |= MAX8973_SNS_ENABLE;
+
+	if (!(pdata->control_flags & MAX8973_CONTROL_FALLING_SLEW_RATE_ENABLE))
+		control1 |= MAX8973_NFSR_ENABLE;
+
+	if (pdata->control_flags & MAX8973_CONTROL_OUTPUT_ACTIVE_DISCH_ENABLE)
+		control1 |= MAX8973_AD_ENABLE;
+
+	if (pdata->control_flags & MAX8973_CONTROL_BIAS_ENABLE)
+		control1 |= MAX8973_BIAS_ENABLE;
+
+	if (pdata->control_flags & MAX8973_CONTROL_FREQ_SHIFT_9PER_ENABLE)
+		control1 |= MAX8973_FREQSHIFT_9PER;
+
+	/* Set ramp delay */
+	if (pdata->reg_init_data &&
+			pdata->reg_init_data->constraints.ramp_delay) {
+		if (pdata->reg_init_data->constraints.ramp_delay < 25000)
+			control1 = MAX8973_RAMP_12mV_PER_US;
+		else if (pdata->reg_init_data->constraints.ramp_delay < 50000)
+			control1 = MAX8973_RAMP_25mV_PER_US;
+		else if (pdata->reg_init_data->constraints.ramp_delay < 200000)
+			control1 = MAX8973_RAMP_50mV_PER_US;
+		else
+			control1 = MAX8973_RAMP_200mV_PER_US;
+	} else {
+		control1 = MAX8973_RAMP_12mV_PER_US;
+		max->desc.ramp_delay = 12500;
+	}
+
+	if (!(pdata->control_flags & MAX8973_CONTROL_PULL_DOWN_ENABLE))
+		control2 |= MAX8973_DISCH_ENBABLE;
+
+	/*  Clock advance trip configuration */
+	switch (pdata->control_flags & MAX8973_CONTROL_CLKADV_TRIP_MASK) {
+	case MAX8973_CONTROL_CLKADV_TRIP_DISABLED:
+		control2 |= MAX8973_CKKADV_TRIP_DISABLE;
+		break;
+
+	case MAX8973_CONTROL_CLKADV_TRIP_75mV_PER_US:
+		control2 |= MAX8973_CKKADV_TRIP_75mV_PER_US;
+		break;
+
+	case MAX8973_CONTROL_CLKADV_TRIP_150mV_PER_US:
+		control2 |= MAX8973_CKKADV_TRIP_150mV_PER_US;
+		break;
+
+	case MAX8973_CONTROL_CLKADV_TRIP_75mV_PER_US_HIST_DIS:
+		control2 |= MAX8973_CKKADV_TRIP_75mV_PER_US_HIST_DIS;
+		break;
+	}
+
+	/* Configure inductor value */
+	switch (pdata->control_flags & MAX8973_CONTROL_INDUCTOR_VALUE_MASK) {
+	case MAX8973_CONTROL_INDUCTOR_VALUE_NOMINAL:
+		control2 |= MAX8973_INDUCTOR_NOMINAL;
+		break;
+
+	case MAX8973_CONTROL_INDUCTOR_VALUE_MINUS_30_PER:
+		control2 |= MAX8973_INDUCTOR_MIN_30_PER;
+		break;
+
+	case MAX8973_CONTROL_INDUCTOR_VALUE_PLUS_30_PER:
+		control2 |= MAX8973_INDUCTOR_PLUS_30_PER;
+		break;
+
+	case MAX8973_CONTROL_INDUCTOR_VALUE_PLUS_60_PER:
+		control2 |= MAX8973_INDUCTOR_PLUS_60_PER;
+		break;
+	}
+
+	ret = regmap_write(max->regmap, MAX8973_CONTROL1, control1);
+	if (ret < 0) {
+		dev_err(max->dev, "register %d write failed, err = %d",
+				MAX8973_CONTROL1, ret);
+		return ret;
+	}
+
+	ret = regmap_write(max->regmap, MAX8973_CONTROL2, control2);
+	if (ret < 0) {
+		dev_err(max->dev, "register %d write failed, err = %d",
+				MAX8973_CONTROL2, ret);
+		return ret;
+	}
+
+	/* If external control is enabled then disable EN bit */
+	if (max->enable_external_control) {
+		ret = regmap_update_bits(max->regmap, MAX8973_VOUT,
+						MAX8973_VOUT_ENABLE, 0);
+		if (ret < 0)
+			dev_err(max->dev, "register %d update failed, err = %d",
+				MAX8973_VOUT, ret);
+	}
+	return ret;
+}
+
+static const struct regmap_config max8973_regmap_config = {
+	.reg_bits		= 8,
+	.val_bits		= 8,
+	.max_register		= MAX8973_CHIPID2,
+	.cache_type		= REGCACHE_RBTREE,
+};
+
+static int __devinit max8973_probe(struct i2c_client *client,
+				     const struct i2c_device_id *id)
+{
+	struct max8973_regulator_platform_data *pdata;
+	struct regulator_config config = { };
+	struct regulator_dev *rdev;
+	struct max8973_chip *max;
+	int ret;
+
+	pdata = client->dev.platform_data;
+	if (!pdata) {
+		dev_err(&client->dev, "No Platform data");
+		return -EIO;
+	}
+
+	max = devm_kzalloc(&client->dev, sizeof(*max), GFP_KERNEL);
+	if (!max) {
+		dev_err(&client->dev, "Memory allocation for max failed\n");
+		return -ENOMEM;
+	}
+
+	max->regmap = devm_regmap_init_i2c(client, &max8973_regmap_config);
+	if (IS_ERR(max->regmap)) {
+		ret = PTR_ERR(max->regmap);
+		dev_err(&client->dev, "regmap init failed, err %d\n", ret);
+		return ret;
+	}
+
+	i2c_set_clientdata(client, max);
+	max->dev = &client->dev;
+	max->desc.name = id->name;
+	max->desc.id = 0;
+	max->desc.ops = &max8973_dcdc_ops;
+	max->desc.type = REGULATOR_VOLTAGE;
+	max->desc.owner = THIS_MODULE;
+	max->desc.min_uV = MAX8973_MIN_VOLATGE;
+	max->desc.uV_step = MAX8973_VOLATGE_STEP;
+	max->desc.n_voltages = MAX8973_BUCK_N_VOLTAGE;
+
+	if (!pdata->enable_ext_control) {
+		max->desc.enable_reg = MAX8973_VOUT;
+		max->desc.enable_mask = MAX8973_VOUT_ENABLE;
+		max8973_dcdc_ops.enable = regulator_enable_regmap;
+		max8973_dcdc_ops.disable = regulator_disable_regmap;
+		max8973_dcdc_ops.is_enabled = regulator_is_enabled_regmap;
+	}
+
+	max->enable_external_control = pdata->enable_ext_control;
+	max->dvs_gpio = pdata->dvs_gpio;
+	max->curr_gpio_val = pdata->dvs_def_state;
+	max->curr_vout_reg = MAX8973_VOUT + pdata->dvs_def_state;
+	max->lru_index[0] = max->curr_vout_reg;
+	max->valid_dvs_gpio = false;
+
+	if (gpio_is_valid(max->dvs_gpio)) {
+		int gpio_flags;
+		int i;
+
+		gpio_flags = (pdata->dvs_def_state) ?
+				GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW;
+		ret = devm_gpio_request_one(&client->dev, max->dvs_gpio,
+				gpio_flags, "max8973-dvs");
+		if (ret) {
+			dev_err(&client->dev,
+				"gpio_request for gpio %d failed, err = %d\n",
+				max->dvs_gpio, ret);
+			return ret;
+		}
+		max->valid_dvs_gpio = true;
+
+		/*
+		 * Initialize the lru index with vout_reg id
+		 * The index 0 will be most recently used and
+		 * set with the max->curr_vout_reg */
+		for (i = 0; i < MAX8973_MAX_VOUT_REG; ++i)
+			max->lru_index[i] = i;
+		max->lru_index[0] = max->curr_vout_reg;
+		max->lru_index[max->curr_vout_reg] = 0;
+	}
+
+	ret = max8973_init_dcdc(max, pdata);
+	if (ret < 0) {
+		dev_err(max->dev, "Max8973 Init failed, err = %d\n", ret);
+		return ret;
+	}
+
+	config.dev = &client->dev;
+	config.init_data = pdata->reg_init_data;
+	config.driver_data = max;
+	config.of_node = client->dev.of_node;
+	config.regmap = max->regmap;
+
+	/* Register the regulators */
+	rdev = regulator_register(&max->desc, &config);
+	if (IS_ERR(rdev)) {
+		ret = PTR_ERR(rdev);
+		dev_err(max->dev, "regulator register failed, err %d\n", ret);
+		return ret;
+	}
+
+	max->rdev = rdev;
+	return 0;
+}
+
+static int __devexit max8973_remove(struct i2c_client *client)
+{
+	struct max8973_chip *max = i2c_get_clientdata(client);
+
+	regulator_unregister(max->rdev);
+	return 0;
+}
+
+static const struct i2c_device_id max8973_id[] = {
+	{.name = "max8973",},
+	{},
+};
+
+MODULE_DEVICE_TABLE(i2c, max8973_id);
+
+static struct i2c_driver max8973_i2c_driver = {
+	.driver = {
+		.name = "max8973",
+		.owner = THIS_MODULE,
+	},
+	.probe = max8973_probe,
+	.remove = __devexit_p(max8973_remove),
+	.id_table = max8973_id,
+};
+
+static int __init max8973_init(void)
+{
+	return i2c_add_driver(&max8973_i2c_driver);
+}
+subsys_initcall(max8973_init);
+
+static void __exit max8973_cleanup(void)
+{
+	i2c_del_driver(&max8973_i2c_driver);
+}
+module_exit(max8973_cleanup);
+
+MODULE_AUTHOR("Laxman Dewangan <ldewangan@nvidia.com>");
+MODULE_DESCRIPTION("MAX8973 voltage regulator driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/regulator/max8997.c b/drivers/regulator/max8997.c
index e39a0c7..df0eafb 100644
--- a/drivers/regulator/max8997.c
+++ b/drivers/regulator/max8997.c
@@ -24,6 +24,7 @@
 #include <linux/bug.h>
 #include <linux/err.h>
 #include <linux/gpio.h>
+#include <linux/of_gpio.h>
 #include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
@@ -31,6 +32,7 @@
 #include <linux/regulator/machine.h>
 #include <linux/mfd/max8997.h>
 #include <linux/mfd/max8997-private.h>
+#include <linux/regulator/of_regulator.h>
 
 struct max8997_data {
 	struct device *dev;
@@ -933,22 +935,163 @@
 				  max8997_charger_fixedstate_ops),
 };
 
-static __devinit int max8997_pmic_probe(struct platform_device *pdev)
+#ifdef CONFIG_OF
+static int max8997_pmic_dt_parse_dvs_gpio(struct max8997_dev *iodev,
+			struct max8997_platform_data *pdata,
+			struct device_node *pmic_np)
+{
+	int i, gpio;
+
+	for (i = 0; i < 3; i++) {
+		gpio = of_get_named_gpio(pmic_np,
+					"max8997,pmic-buck125-dvs-gpios", i);
+		if (!gpio_is_valid(gpio)) {
+			dev_err(iodev->dev, "invalid gpio[%d]: %d\n", i, gpio);
+			return -EINVAL;
+		}
+		pdata->buck125_gpios[i] = gpio;
+	}
+	return 0;
+}
+
+static int max8997_pmic_dt_parse_pdata(struct max8997_dev *iodev,
+					struct max8997_platform_data *pdata)
+{
+	struct device_node *pmic_np, *regulators_np, *reg_np;
+	struct max8997_regulator_data *rdata;
+	unsigned int i, dvs_voltage_nr = 1, ret;
+
+	pmic_np = iodev->dev->of_node;
+	if (!pmic_np) {
+		dev_err(iodev->dev, "could not find pmic sub-node\n");
+		return -ENODEV;
+	}
+
+	regulators_np = of_find_node_by_name(pmic_np, "regulators");
+	if (!regulators_np) {
+		dev_err(iodev->dev, "could not find regulators sub-node\n");
+		return -EINVAL;
+	}
+
+	/* count the number of regulators to be supported in pmic */
+	pdata->num_regulators = 0;
+	for_each_child_of_node(regulators_np, reg_np)
+		pdata->num_regulators++;
+
+	rdata = devm_kzalloc(iodev->dev, sizeof(*rdata) *
+				pdata->num_regulators, GFP_KERNEL);
+	if (!rdata) {
+		dev_err(iodev->dev, "could not allocate memory for "
+						"regulator data\n");
+		return -ENOMEM;
+	}
+
+	pdata->regulators = rdata;
+	for_each_child_of_node(regulators_np, reg_np) {
+		for (i = 0; i < ARRAY_SIZE(regulators); i++)
+			if (!of_node_cmp(reg_np->name, regulators[i].name))
+				break;
+
+		if (i == ARRAY_SIZE(regulators)) {
+			dev_warn(iodev->dev, "don't know how to configure "
+				"regulator %s\n", reg_np->name);
+			continue;
+		}
+
+		rdata->id = i;
+		rdata->initdata = of_get_regulator_init_data(
+						iodev->dev, reg_np);
+		rdata->reg_node = reg_np;
+		rdata++;
+	}
+
+	if (of_get_property(pmic_np, "max8997,pmic-buck1-uses-gpio-dvs", NULL))
+		pdata->buck1_gpiodvs = true;
+
+	if (of_get_property(pmic_np, "max8997,pmic-buck2-uses-gpio-dvs", NULL))
+		pdata->buck2_gpiodvs = true;
+
+	if (of_get_property(pmic_np, "max8997,pmic-buck5-uses-gpio-dvs", NULL))
+		pdata->buck5_gpiodvs = true;
+
+	if (pdata->buck1_gpiodvs || pdata->buck2_gpiodvs ||
+						pdata->buck5_gpiodvs) {
+		ret = max8997_pmic_dt_parse_dvs_gpio(iodev, pdata, pmic_np);
+		if (ret)
+			return -EINVAL;
+
+		if (of_property_read_u32(pmic_np,
+				"max8997,pmic-buck125-default-dvs-idx",
+				&pdata->buck125_default_idx)) {
+			pdata->buck125_default_idx = 0;
+		} else {
+			if (pdata->buck125_default_idx >= 8) {
+				pdata->buck125_default_idx = 0;
+				dev_info(iodev->dev, "invalid value for "
+				"default dvs index, using 0 instead\n");
+			}
+		}
+
+		if (of_get_property(pmic_np,
+			"max8997,pmic-ignore-gpiodvs-side-effect", NULL))
+			pdata->ignore_gpiodvs_side_effect = true;
+
+		dvs_voltage_nr = 8;
+	}
+
+	if (of_property_read_u32_array(pmic_np,
+				"max8997,pmic-buck1-dvs-voltage",
+				pdata->buck1_voltage, dvs_voltage_nr)) {
+		dev_err(iodev->dev, "buck1 voltages not specified\n");
+		return -EINVAL;
+	}
+
+	if (of_property_read_u32_array(pmic_np,
+				"max8997,pmic-buck2-dvs-voltage",
+				pdata->buck2_voltage, dvs_voltage_nr)) {
+		dev_err(iodev->dev, "buck2 voltages not specified\n");
+		return -EINVAL;
+	}
+
+	if (of_property_read_u32_array(pmic_np,
+				"max8997,pmic-buck5-dvs-voltage",
+				pdata->buck5_voltage, dvs_voltage_nr)) {
+		dev_err(iodev->dev, "buck5 voltages not specified\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+#else
+static int max8997_pmic_dt_parse_pdata(struct max8997_dev *iodev,
+					struct max8997_platform_data *pdata)
+{
+	return 0;
+}
+#endif /* CONFIG_OF */
+
+static int max8997_pmic_probe(struct platform_device *pdev)
 {
 	struct max8997_dev *iodev = dev_get_drvdata(pdev->dev.parent);
-	struct max8997_platform_data *pdata = dev_get_platdata(iodev->dev);
+	struct max8997_platform_data *pdata = iodev->pdata;
 	struct regulator_config config = { };
 	struct regulator_dev **rdev;
 	struct max8997_data *max8997;
 	struct i2c_client *i2c;
-	int i, ret, size;
+	int i, ret, size, nr_dvs;
 	u8 max_buck1 = 0, max_buck2 = 0, max_buck5 = 0;
 
-	if (!pdata) {
+	if (IS_ERR_OR_NULL(pdata)) {
 		dev_err(pdev->dev.parent, "No platform init data supplied.\n");
 		return -ENODEV;
 	}
 
+	if (iodev->dev->of_node) {
+		ret = max8997_pmic_dt_parse_pdata(iodev, pdata);
+		if (ret)
+			return ret;
+	}
+
 	max8997 = devm_kzalloc(&pdev->dev, sizeof(struct max8997_data),
 			       GFP_KERNEL);
 	if (!max8997)
@@ -973,7 +1116,10 @@
 	memcpy(max8997->buck125_gpios, pdata->buck125_gpios, sizeof(int) * 3);
 	max8997->ignore_gpiodvs_side_effect = pdata->ignore_gpiodvs_side_effect;
 
-	for (i = 0; i < 8; i++) {
+	nr_dvs = (pdata->buck1_gpiodvs || pdata->buck2_gpiodvs ||
+			pdata->buck5_gpiodvs) ? 8 : 1;
+
+	for (i = 0; i < nr_dvs; i++) {
 		max8997->buck1_vol[i] = ret =
 			max8997_get_voltage_proper_val(
 					&buck1245_voltage_map_desc,
@@ -1019,6 +1165,19 @@
 				max_buck5, 0x3f);
 	}
 
+	/* Initialize all the DVS related BUCK registers */
+	for (i = 0; i < nr_dvs; i++) {
+		max8997_update_reg(i2c, MAX8997_REG_BUCK1DVS1 + i,
+				max8997->buck1_vol[i],
+				0x3f);
+		max8997_update_reg(i2c, MAX8997_REG_BUCK2DVS1 + i,
+				max8997->buck2_vol[i],
+				0x3f);
+		max8997_update_reg(i2c, MAX8997_REG_BUCK5DVS1 + i,
+				max8997->buck5_vol[i],
+				0x3f);
+	}
+
 	/*
 	 * If buck 1, 2, and 5 do not care DVS GPIO settings, ignore them.
 	 * If at least one of them cares, set gpios.
@@ -1068,19 +1227,6 @@
 	max8997_update_reg(i2c, MAX8997_REG_BUCK5CTRL, (pdata->buck5_gpiodvs) ?
 			(1 << 1) : (0 << 1), 1 << 1);
 
-	/* Initialize all the DVS related BUCK registers */
-	for (i = 0; i < 8; i++) {
-		max8997_update_reg(i2c, MAX8997_REG_BUCK1DVS1 + i,
-				max8997->buck1_vol[i],
-				0x3f);
-		max8997_update_reg(i2c, MAX8997_REG_BUCK2DVS1 + i,
-				max8997->buck2_vol[i],
-				0x3f);
-		max8997_update_reg(i2c, MAX8997_REG_BUCK5DVS1 + i,
-				max8997->buck5_vol[i],
-				0x3f);
-	}
-
 	/* Misc Settings */
 	max8997->ramp_delay = 10; /* set 10mV/us, which is the default */
 	max8997_write_reg(i2c, MAX8997_REG_BUCKRAMP, (0xf << 4) | 0x9);
@@ -1101,6 +1247,7 @@
 		config.dev = max8997->dev;
 		config.init_data = pdata->regulators[i].initdata;
 		config.driver_data = max8997;
+		config.of_node = pdata->regulators[i].reg_node;
 
 		rdev[i] = regulator_register(&regulators[id], &config);
 		if (IS_ERR(rdev[i])) {
@@ -1120,7 +1267,7 @@
 	return ret;
 }
 
-static int __devexit max8997_pmic_remove(struct platform_device *pdev)
+static int max8997_pmic_remove(struct platform_device *pdev)
 {
 	struct max8997_data *max8997 = platform_get_drvdata(pdev);
 	struct regulator_dev **rdev = max8997->rdev;
@@ -1143,7 +1290,7 @@
 		.owner = THIS_MODULE,
 	},
 	.probe = max8997_pmic_probe,
-	.remove = __devexit_p(max8997_pmic_remove),
+	.remove = max8997_pmic_remove,
 	.id_table = max8997_pmic_id,
 };
 
diff --git a/drivers/regulator/max8998.c b/drivers/regulator/max8998.c
index 5dfa920..b821d08 100644
--- a/drivers/regulator/max8998.c
+++ b/drivers/regulator/max8998.c
@@ -633,7 +633,7 @@
 	}
 };
 
-static __devinit int max8998_pmic_probe(struct platform_device *pdev)
+static int max8998_pmic_probe(struct platform_device *pdev)
 {
 	struct max8998_dev *iodev = dev_get_drvdata(pdev->dev.parent);
 	struct max8998_platform_data *pdata = dev_get_platdata(iodev->dev);
@@ -818,7 +818,7 @@
 	return ret;
 }
 
-static int __devexit max8998_pmic_remove(struct platform_device *pdev)
+static int max8998_pmic_remove(struct platform_device *pdev)
 {
 	struct max8998_data *max8998 = platform_get_drvdata(pdev);
 	struct regulator_dev **rdev = max8998->rdev;
@@ -842,7 +842,7 @@
 		.owner = THIS_MODULE,
 	},
 	.probe = max8998_pmic_probe,
-	.remove = __devexit_p(max8998_pmic_remove),
+	.remove = max8998_pmic_remove,
 	.id_table = max8998_pmic_id,
 };
 
diff --git a/drivers/regulator/mc13783-regulator.c b/drivers/regulator/mc13783-regulator.c
index 0801a6d..c46c670 100644
--- a/drivers/regulator/mc13783-regulator.c
+++ b/drivers/regulator/mc13783-regulator.c
@@ -392,7 +392,7 @@
 	.set_voltage = mc13xxx_fixed_regulator_set_voltage,
 };
 
-static int __devinit mc13783_regulator_probe(struct platform_device *pdev)
+static int mc13783_regulator_probe(struct platform_device *pdev)
 {
 	struct mc13xxx_regulator_priv *priv;
 	struct mc13xxx *mc13783 = dev_get_drvdata(pdev->dev.parent);
@@ -445,7 +445,7 @@
 	return ret;
 }
 
-static int __devexit mc13783_regulator_remove(struct platform_device *pdev)
+static int mc13783_regulator_remove(struct platform_device *pdev)
 {
 	struct mc13xxx_regulator_priv *priv = platform_get_drvdata(pdev);
 	struct mc13xxx_regulator_platform_data *pdata =
@@ -465,7 +465,7 @@
 		.name	= "mc13783-regulator",
 		.owner	= THIS_MODULE,
 	},
-	.remove		= __devexit_p(mc13783_regulator_remove),
+	.remove		= mc13783_regulator_remove,
 	.probe		= mc13783_regulator_probe,
 };
 
diff --git a/drivers/regulator/mc13892-regulator.c b/drivers/regulator/mc13892-regulator.c
index 1fa6381..0d84b1f 100644
--- a/drivers/regulator/mc13892-regulator.c
+++ b/drivers/regulator/mc13892-regulator.c
@@ -486,7 +486,7 @@
 }
 
 
-static int __devinit mc13892_regulator_probe(struct platform_device *pdev)
+static int mc13892_regulator_probe(struct platform_device *pdev)
 {
 	struct mc13xxx_regulator_priv *priv;
 	struct mc13xxx *mc13892 = dev_get_drvdata(pdev->dev.parent);
@@ -588,7 +588,7 @@
 	return ret;
 }
 
-static int __devexit mc13892_regulator_remove(struct platform_device *pdev)
+static int mc13892_regulator_remove(struct platform_device *pdev)
 {
 	struct mc13xxx_regulator_priv *priv = platform_get_drvdata(pdev);
 	int i;
@@ -606,7 +606,7 @@
 		.name	= "mc13892-regulator",
 		.owner	= THIS_MODULE,
 	},
-	.remove	= __devexit_p(mc13892_regulator_remove),
+	.remove	= mc13892_regulator_remove,
 	.probe	= mc13892_regulator_probe,
 };
 
diff --git a/drivers/regulator/mc13xxx-regulator-core.c b/drivers/regulator/mc13xxx-regulator-core.c
index 88cbb83..4ed89c6 100644
--- a/drivers/regulator/mc13xxx-regulator-core.c
+++ b/drivers/regulator/mc13xxx-regulator-core.c
@@ -162,7 +162,7 @@
 EXPORT_SYMBOL_GPL(mc13xxx_fixed_regulator_ops);
 
 #ifdef CONFIG_OF
-int __devinit mc13xxx_get_num_regulators_dt(struct platform_device *pdev)
+int mc13xxx_get_num_regulators_dt(struct platform_device *pdev)
 {
 	struct device_node *parent, *child;
 	int num = 0;
@@ -179,7 +179,7 @@
 }
 EXPORT_SYMBOL_GPL(mc13xxx_get_num_regulators_dt);
 
-struct mc13xxx_regulator_init_data * __devinit mc13xxx_parse_regulators_dt(
+struct mc13xxx_regulator_init_data *mc13xxx_parse_regulators_dt(
 	struct platform_device *pdev, struct mc13xxx_regulator *regulators,
 	int num_regulators)
 {
diff --git a/drivers/regulator/palmas-regulator.c b/drivers/regulator/palmas-regulator.c
index 07aee69..e915629 100644
--- a/drivers/regulator/palmas-regulator.c
+++ b/drivers/regulator/palmas-regulator.c
@@ -309,68 +309,22 @@
 	int id = rdev_get_id(dev);
 	int mult = 1;
 
-	if (!selector)
-		return 0;
-
 	/* Read the multiplier set in VSEL register to return
 	 * the correct voltage.
 	 */
 	if (pmic->range[id])
 		mult = 2;
 
-	/* Voltage is (0.49V + (selector * 0.01V)) * RANGE
-	 * as defined in data sheet. RANGE is either x1 or x2
-	 */
-	return  (490000 + (selector * 10000)) * mult;
-}
-
-static int palmas_get_voltage_smps_sel(struct regulator_dev *dev)
-{
-	struct palmas_pmic *pmic = rdev_get_drvdata(dev);
-	int id = rdev_get_id(dev);
-	int selector;
-	unsigned int reg;
-	unsigned int addr;
-
-	addr = palmas_regs_info[id].vsel_addr;
-
-	palmas_smps_read(pmic->palmas, addr, &reg);
-
-	selector = reg & PALMAS_SMPS12_VOLTAGE_VSEL_MASK;
-
-	/* Adjust selector to match list_voltage ranges */
-	if ((selector > 0) && (selector < 6))
-		selector = 6;
-	if (!selector)
-		selector = 5;
-	if (selector > 121)
-		selector = 121;
-	selector -= 5;
-
-	return selector;
-}
-
-static int palmas_set_voltage_smps_sel(struct regulator_dev *dev,
-		unsigned selector)
-{
-	struct palmas_pmic *pmic = rdev_get_drvdata(dev);
-	int id = rdev_get_id(dev);
-	unsigned int reg = 0;
-	unsigned int addr;
-
-	addr = palmas_regs_info[id].vsel_addr;
-
-	/* Make sure we don't change the value of RANGE */
-	if (pmic->range[id])
-		reg |= PALMAS_SMPS12_VOLTAGE_RANGE;
-
-	/* Adjust the linux selector into range used in VSEL register */
-	if (selector)
-		reg |= selector + 5;
-
-	palmas_smps_write(pmic->palmas, addr, reg);
-
-	return 0;
+	if (selector == 0)
+		return 0;
+	else if (selector < 6)
+		return 500000 * mult;
+	else
+		/* Voltage is linear mapping starting from selector 6,
+		 * volt = (0.49V + ((selector - 5) * 0.01V)) * RANGE
+		 * RANGE is either x1 or x2
+		 */
+		return (490000 + ((selector - 5) * 10000)) * mult;
 }
 
 static int palmas_map_voltage_smps(struct regulator_dev *rdev,
@@ -386,11 +340,11 @@
 	if (pmic->range[id]) { /* RANGE is x2 */
 		if (min_uV < 1000000)
 			min_uV = 1000000;
-		ret = DIV_ROUND_UP(min_uV - 1000000, 20000) + 1;
+		ret = DIV_ROUND_UP(min_uV - 1000000, 20000) + 6;
 	} else {		/* RANGE is x1 */
 		if (min_uV < 500000)
 			min_uV = 500000;
-		ret = DIV_ROUND_UP(min_uV - 500000, 10000) + 1;
+		ret = DIV_ROUND_UP(min_uV - 500000, 10000) + 6;
 	}
 
 	/* Map back into a voltage to verify we're still in bounds */
@@ -407,8 +361,8 @@
 	.disable		= palmas_disable_smps,
 	.set_mode		= palmas_set_mode_smps,
 	.get_mode		= palmas_get_mode_smps,
-	.get_voltage_sel	= palmas_get_voltage_smps_sel,
-	.set_voltage_sel	= palmas_set_voltage_smps_sel,
+	.get_voltage_sel	= regulator_get_voltage_sel_regmap,
+	.set_voltage_sel	= regulator_set_voltage_sel_regmap,
 	.list_voltage		= palmas_list_voltage_smps,
 	.map_voltage		= palmas_map_voltage_smps,
 };
@@ -436,44 +390,14 @@
 	return !!(reg);
 }
 
-static int palmas_list_voltage_ldo(struct regulator_dev *dev,
-					unsigned selector)
-{
-	if (!selector)
-		return 0;
-
-	/* voltage is 0.85V + (selector * 0.05v) */
-	return  850000 + (selector * 50000);
-}
-
-static int palmas_map_voltage_ldo(struct regulator_dev *rdev,
-		int min_uV, int max_uV)
-{
-	int ret, voltage;
-
-	if (min_uV == 0)
-		return 0;
-
-	if (min_uV < 900000)
-		min_uV = 900000;
-	ret = DIV_ROUND_UP(min_uV - 900000, 50000) + 1;
-
-	/* Map back into a voltage to verify we're still in bounds */
-	voltage = palmas_list_voltage_ldo(rdev, ret);
-	if (voltage < min_uV || voltage > max_uV)
-		return -EINVAL;
-
-	return ret;
-}
-
 static struct regulator_ops palmas_ops_ldo = {
 	.is_enabled		= palmas_is_enabled_ldo,
 	.enable			= regulator_enable_regmap,
 	.disable		= regulator_disable_regmap,
 	.get_voltage_sel	= regulator_get_voltage_sel_regmap,
 	.set_voltage_sel	= regulator_set_voltage_sel_regmap,
-	.list_voltage		= palmas_list_voltage_ldo,
-	.map_voltage		= palmas_map_voltage_ldo,
+	.list_voltage		= regulator_list_voltage_linear,
+	.map_voltage		= regulator_map_voltage_linear,
 };
 
 /*
@@ -595,7 +519,7 @@
 	{ .name = "ldousb", },
 };
 
-static void __devinit palmas_dt_to_pdata(struct device *dev,
+static void palmas_dt_to_pdata(struct device *dev,
 		struct device_node *node,
 		struct palmas_pmic_platform_data *pdata)
 {
@@ -663,7 +587,7 @@
 }
 
 
-static __devinit int palmas_probe(struct platform_device *pdev)
+static int palmas_probe(struct platform_device *pdev)
 {
 	struct palmas *palmas = dev_get_drvdata(pdev->dev.parent);
 	struct palmas_pmic_platform_data *pdata = pdev->dev.platform_data;
@@ -733,6 +657,14 @@
 				continue;
 		}
 
+		/* Initialise sleep/init values from platform data */
+		if (pdata && pdata->reg_init[id]) {
+			reg_init = pdata->reg_init[id];
+			ret = palmas_smps_init(palmas, id, reg_init);
+			if (ret)
+				goto err_unregister_regulator;
+		}
+
 		/* Register the regulators */
 		pmic->desc[id].name = palmas_regs_info[id].name;
 		pmic->desc[id].id = id;
@@ -753,29 +685,11 @@
 			pmic->desc[id].uV_step = 1250000;
 			break;
 		default:
-			pmic->desc[id].ops = &palmas_ops_smps;
-			pmic->desc[id].n_voltages = PALMAS_SMPS_NUM_VOLTAGES;
-		}
-
-		pmic->desc[id].type = REGULATOR_VOLTAGE;
-		pmic->desc[id].owner = THIS_MODULE;
-
-		/* Initialise sleep/init values from platform data */
-		if (pdata) {
-			reg_init = pdata->reg_init[id];
-			if (reg_init) {
-				ret = palmas_smps_init(palmas, id, reg_init);
-				if (ret)
-					goto err_unregister_regulator;
-			}
-		}
-
-		/*
-		 * read and store the RANGE bit for later use
-		 * This must be done before regulator is probed otherwise
-		 * we error in probe with unsuportable ranges.
-		 */
-		if (id != PALMAS_REG_SMPS10) {
+			/*
+			 * Read and store the RANGE bit for later use
+			 * This must be done before regulator is probed,
+			 * otherwise we error in probe with unsupportable ranges.
+			 */
 			addr = palmas_regs_info[id].vsel_addr;
 
 			ret = palmas_smps_read(pmic->palmas, addr, &reg);
@@ -783,8 +697,19 @@
 				goto err_unregister_regulator;
 			if (reg & PALMAS_SMPS12_VOLTAGE_RANGE)
 				pmic->range[id] = 1;
+
+			pmic->desc[id].ops = &palmas_ops_smps;
+			pmic->desc[id].n_voltages = PALMAS_SMPS_NUM_VOLTAGES;
+			pmic->desc[id].vsel_reg =
+					PALMAS_BASE_TO_REG(PALMAS_SMPS_BASE,
+						palmas_regs_info[id].vsel_addr);
+			pmic->desc[id].vsel_mask =
+					PALMAS_SMPS12_VOLTAGE_VSEL_MASK;
 		}
 
+		pmic->desc[id].type = REGULATOR_VOLTAGE;
+		pmic->desc[id].owner = THIS_MODULE;
+
 		if (pdata)
 			config.init_data = pdata->reg_data[id];
 		else
@@ -821,6 +746,9 @@
 
 		pmic->desc[id].type = REGULATOR_VOLTAGE;
 		pmic->desc[id].owner = THIS_MODULE;
+		pmic->desc[id].min_uV = 900000;
+		pmic->desc[id].uV_step = 50000;
+		pmic->desc[id].linear_min_sel = 1;
 		pmic->desc[id].vsel_reg = PALMAS_BASE_TO_REG(PALMAS_LDO_BASE,
 						palmas_regs_info[id].vsel_addr);
 		pmic->desc[id].vsel_mask = PALMAS_LDO1_VOLTAGE_VSEL_MASK;
@@ -868,7 +796,7 @@
 	return ret;
 }
 
-static int __devexit palmas_remove(struct platform_device *pdev)
+static int palmas_remove(struct platform_device *pdev)
 {
 	struct palmas_pmic *pmic = platform_get_drvdata(pdev);
 	int id;
@@ -890,7 +818,7 @@
 		.owner = THIS_MODULE,
 	},
 	.probe = palmas_probe,
-	.remove = __devexit_p(palmas_remove),
+	.remove = palmas_remove,
 };
 
 static int __init palmas_init(void)
diff --git a/drivers/regulator/pcap-regulator.c b/drivers/regulator/pcap-regulator.c
index 68777ac..4899342 100644
--- a/drivers/regulator/pcap-regulator.c
+++ b/drivers/regulator/pcap-regulator.c
@@ -236,7 +236,7 @@
 	VREG(VAUX4), VREG(VSIM), VREG(VSIM2), VREG(VVIB), VREG(SW1), VREG(SW2),
 };
 
-static int __devinit pcap_regulator_probe(struct platform_device *pdev)
+static int pcap_regulator_probe(struct platform_device *pdev)
 {
 	struct regulator_dev *rdev;
 	void *pcap = dev_get_drvdata(pdev->dev.parent);
@@ -255,7 +255,7 @@
 	return 0;
 }
 
-static int __devexit pcap_regulator_remove(struct platform_device *pdev)
+static int pcap_regulator_remove(struct platform_device *pdev)
 {
 	struct regulator_dev *rdev = platform_get_drvdata(pdev);
 
@@ -271,7 +271,7 @@
 		.owner	= THIS_MODULE,
 	},
 	.probe	= pcap_regulator_probe,
-	.remove	= __devexit_p(pcap_regulator_remove),
+	.remove	= pcap_regulator_remove,
 };
 
 static int __init pcap_regulator_init(void)
diff --git a/drivers/regulator/pcf50633-regulator.c b/drivers/regulator/pcf50633-regulator.c
index 092e5cb..534075e 100644
--- a/drivers/regulator/pcf50633-regulator.c
+++ b/drivers/regulator/pcf50633-regulator.c
@@ -24,12 +24,15 @@
 #include <linux/mfd/pcf50633/core.h>
 #include <linux/mfd/pcf50633/pmic.h>
 
-#define PCF50633_REGULATOR(_name, _id, _n)			\
+#define PCF50633_REGULATOR(_name, _id, _min_uV, _uV_step, _min_sel, _n) \
 	{							\
 		.name = _name,					\
 		.id = PCF50633_REGULATOR_##_id,			\
 		.ops = &pcf50633_regulator_ops,			\
 		.n_voltages = _n,				\
+		.min_uV = _min_uV,				\
+		.uV_step = _uV_step,				\
+		.linear_min_sel = _min_sel,			\
 		.type = REGULATOR_VOLTAGE,			\
 		.owner = THIS_MODULE,				\
 		.vsel_reg = PCF50633_REG_##_id##OUT,		\
@@ -38,165 +41,42 @@
 		.enable_mask = PCF50633_REGULATOR_ON,		\
 	}
 
-/* Bits from voltage value */
-static u8 auto_voltage_bits(unsigned int millivolts)
-{
-	if (millivolts < 1800)
-		return 0x2f;
-	if (millivolts > 3800)
-		return 0xff;
-
-	millivolts -= 625;
-
-	return millivolts / 25;
-}
-
-static u8 down_voltage_bits(unsigned int millivolts)
-{
-	if (millivolts < 625)
-		return 0;
-	else if (millivolts > 3000)
-		return 0xff;
-
-	millivolts -= 625;
-
-	return millivolts / 25;
-}
-
-static u8 ldo_voltage_bits(unsigned int millivolts)
-{
-	if (millivolts < 900)
-		return 0;
-	else if (millivolts > 3600)
-		return 0x1f;
-
-	millivolts -= 900;
-	return millivolts / 100;
-}
-
-/* Obtain voltage value from bits */
-static unsigned int auto_voltage_value(u8 bits)
-{
-	/* AUTOOUT: 00000000 to 00101110 are reserved.
-	 * Return 0 for bits in reserved range, which means this selector code
-	 * can't be used on this system */
-	if (bits < 0x2f)
-		return 0;
-
-	return 625 + (bits * 25);
-}
-
-
-static unsigned int down_voltage_value(u8 bits)
-{
-	return 625 + (bits * 25);
-}
-
-
-static unsigned int ldo_voltage_value(u8 bits)
-{
-	bits &= 0x1f;
-
-	return 900 + (bits * 100);
-}
-
-static int pcf50633_regulator_map_voltage(struct regulator_dev *rdev,
-					  int min_uV, int max_uV)
-{
-	struct pcf50633 *pcf;
-	int regulator_id, millivolts;
-	u8 volt_bits;
-
-	pcf = rdev_get_drvdata(rdev);
-
-	regulator_id = rdev_get_id(rdev);
-	if (regulator_id >= PCF50633_NUM_REGULATORS)
-		return -EINVAL;
-
-	millivolts = min_uV / 1000;
-
-	switch (regulator_id) {
-	case PCF50633_REGULATOR_AUTO:
-		volt_bits = auto_voltage_bits(millivolts);
-		break;
-	case PCF50633_REGULATOR_DOWN1:
-	case PCF50633_REGULATOR_DOWN2:
-		volt_bits = down_voltage_bits(millivolts);
-		break;
-	case PCF50633_REGULATOR_LDO1:
-	case PCF50633_REGULATOR_LDO2:
-	case PCF50633_REGULATOR_LDO3:
-	case PCF50633_REGULATOR_LDO4:
-	case PCF50633_REGULATOR_LDO5:
-	case PCF50633_REGULATOR_LDO6:
-	case PCF50633_REGULATOR_HCLDO:
-	case PCF50633_REGULATOR_MEMLDO:
-		volt_bits = ldo_voltage_bits(millivolts);
-		break;
-	default:
-		return -EINVAL;
-	}
-
-	return volt_bits;
-}
-
-static int pcf50633_regulator_list_voltage(struct regulator_dev *rdev,
-						unsigned int index)
-{
-	int regulator_id = rdev_get_id(rdev);
-
-	int millivolts;
-
-	switch (regulator_id) {
-	case PCF50633_REGULATOR_AUTO:
-		millivolts = auto_voltage_value(index);
-		break;
-	case PCF50633_REGULATOR_DOWN1:
-	case PCF50633_REGULATOR_DOWN2:
-		millivolts = down_voltage_value(index);
-		break;
-	case PCF50633_REGULATOR_LDO1:
-	case PCF50633_REGULATOR_LDO2:
-	case PCF50633_REGULATOR_LDO3:
-	case PCF50633_REGULATOR_LDO4:
-	case PCF50633_REGULATOR_LDO5:
-	case PCF50633_REGULATOR_LDO6:
-	case PCF50633_REGULATOR_HCLDO:
-	case PCF50633_REGULATOR_MEMLDO:
-		millivolts = ldo_voltage_value(index);
-		break;
-	default:
-		return -EINVAL;
-	}
-
-	return millivolts * 1000;
-}
-
 static struct regulator_ops pcf50633_regulator_ops = {
 	.set_voltage_sel = regulator_set_voltage_sel_regmap,
 	.get_voltage_sel = regulator_get_voltage_sel_regmap,
-	.list_voltage = pcf50633_regulator_list_voltage,
-	.map_voltage = pcf50633_regulator_map_voltage,
+	.list_voltage = regulator_list_voltage_linear,
+	.map_voltage = regulator_map_voltage_linear,
 	.enable = regulator_enable_regmap,
 	.disable = regulator_disable_regmap,
 	.is_enabled = regulator_is_enabled_regmap,
 };
 
 static const struct regulator_desc regulators[] = {
-	[PCF50633_REGULATOR_AUTO] = PCF50633_REGULATOR("auto", AUTO, 128),
-	[PCF50633_REGULATOR_DOWN1] = PCF50633_REGULATOR("down1", DOWN1, 96),
-	[PCF50633_REGULATOR_DOWN2] = PCF50633_REGULATOR("down2", DOWN2, 96),
-	[PCF50633_REGULATOR_LDO1] = PCF50633_REGULATOR("ldo1", LDO1, 28),
-	[PCF50633_REGULATOR_LDO2] = PCF50633_REGULATOR("ldo2", LDO2, 28),
-	[PCF50633_REGULATOR_LDO3] = PCF50633_REGULATOR("ldo3", LDO3, 28),
-	[PCF50633_REGULATOR_LDO4] = PCF50633_REGULATOR("ldo4", LDO4, 28),
-	[PCF50633_REGULATOR_LDO5] = PCF50633_REGULATOR("ldo5", LDO5, 28),
-	[PCF50633_REGULATOR_LDO6] = PCF50633_REGULATOR("ldo6", LDO6, 28),
-	[PCF50633_REGULATOR_HCLDO] = PCF50633_REGULATOR("hcldo", HCLDO, 28),
-	[PCF50633_REGULATOR_MEMLDO] = PCF50633_REGULATOR("memldo", MEMLDO, 28),
+	[PCF50633_REGULATOR_AUTO] =
+		PCF50633_REGULATOR("auto", AUTO, 1800000, 25000, 0x2f, 128),
+	[PCF50633_REGULATOR_DOWN1] =
+		PCF50633_REGULATOR("down1", DOWN1, 625000, 25000, 0, 96),
+	[PCF50633_REGULATOR_DOWN2] =
+		PCF50633_REGULATOR("down2", DOWN2, 625000, 25000, 0, 96),
+	[PCF50633_REGULATOR_LDO1] =
+		PCF50633_REGULATOR("ldo1", LDO1, 900000, 100000, 0, 28),
+	[PCF50633_REGULATOR_LDO2] =
+		PCF50633_REGULATOR("ldo2", LDO2, 900000, 100000, 0, 28),
+	[PCF50633_REGULATOR_LDO3] =
+		PCF50633_REGULATOR("ldo3", LDO3, 900000, 100000, 0, 28),
+	[PCF50633_REGULATOR_LDO4] =
+		PCF50633_REGULATOR("ldo4", LDO4, 900000, 100000, 0, 28),
+	[PCF50633_REGULATOR_LDO5] =
+		PCF50633_REGULATOR("ldo5", LDO5, 900000, 100000, 0, 28),
+	[PCF50633_REGULATOR_LDO6] =
+		PCF50633_REGULATOR("ldo6", LDO6, 900000, 100000, 0, 28),
+	[PCF50633_REGULATOR_HCLDO] =
+		PCF50633_REGULATOR("hcldo", HCLDO, 900000, 100000, 0, 28),
+	[PCF50633_REGULATOR_MEMLDO] =
+		PCF50633_REGULATOR("memldo", MEMLDO, 900000, 100000, 0, 28),
 };
 
-static int __devinit pcf50633_regulator_probe(struct platform_device *pdev)
+static int pcf50633_regulator_probe(struct platform_device *pdev)
 {
 	struct regulator_dev *rdev;
 	struct pcf50633 *pcf;
@@ -222,7 +102,7 @@
 	return 0;
 }
 
-static int __devexit pcf50633_regulator_remove(struct platform_device *pdev)
+static int pcf50633_regulator_remove(struct platform_device *pdev)
 {
 	struct regulator_dev *rdev = platform_get_drvdata(pdev);
 
@@ -237,7 +117,7 @@
 		.name = "pcf50633-regltr",
 	},
 	.probe = pcf50633_regulator_probe,
-	.remove = __devexit_p(pcf50633_regulator_remove),
+	.remove = pcf50633_regulator_remove,
 };
 
 static int __init pcf50633_regulator_init(void)
diff --git a/drivers/regulator/rc5t583-regulator.c b/drivers/regulator/rc5t583-regulator.c
index 8bf4e8c9..9e6f786 100644
--- a/drivers/regulator/rc5t583-regulator.c
+++ b/drivers/regulator/rc5t583-regulator.c
@@ -119,7 +119,7 @@
 	RC5T583_REG(LDO9, LDOEN1, 1, LDODIS1, 1, 0x7F, 900, 3400, 25000, 133),
 };
 
-static int __devinit rc5t583_regulator_probe(struct platform_device *pdev)
+static int rc5t583_regulator_probe(struct platform_device *pdev)
 {
 	struct rc5t583 *rc5t583 = dev_get_drvdata(pdev->dev.parent);
 	struct rc5t583_platform_data *pdata = dev_get_platdata(rc5t583->dev);
@@ -198,7 +198,7 @@
 	return ret;
 }
 
-static int __devexit rc5t583_regulator_remove(struct platform_device *pdev)
+static int rc5t583_regulator_remove(struct platform_device *pdev)
 {
 	struct rc5t583_regulator *regs = platform_get_drvdata(pdev);
 	int id;
@@ -214,7 +214,7 @@
 		.owner	= THIS_MODULE,
 	},
 	.probe		= rc5t583_regulator_probe,
-	.remove		= __devexit_p(rc5t583_regulator_remove),
+	.remove		= rc5t583_regulator_remove,
 };
 
 static int __init rc5t583_regulator_init(void)
diff --git a/drivers/regulator/s2mps11.c b/drivers/regulator/s2mps11.c
index 926f9c8..bd062a2 100644
--- a/drivers/regulator/s2mps11.c
+++ b/drivers/regulator/s2mps11.c
@@ -231,7 +231,7 @@
 	regulator_desc_buck10,
 };
 
-static __devinit int s2mps11_pmic_probe(struct platform_device *pdev)
+static int s2mps11_pmic_probe(struct platform_device *pdev)
 {
 	struct sec_pmic_dev *iodev = dev_get_drvdata(pdev->dev.parent);
 	struct sec_platform_data *pdata = dev_get_platdata(iodev->dev);
@@ -269,16 +269,16 @@
 
 	if (ramp_enable) {
 		if (s2mps11->buck2_ramp)
-			ramp_reg |= get_ramp_delay(s2mps11->ramp_delay2) >> 6;
+			ramp_reg |= get_ramp_delay(s2mps11->ramp_delay2) << 6;
 		if (s2mps11->buck3_ramp || s2mps11->buck4_ramp)
-			ramp_reg |= get_ramp_delay(s2mps11->ramp_delay34) >> 4;
+			ramp_reg |= get_ramp_delay(s2mps11->ramp_delay34) << 4;
 		sec_reg_write(iodev, S2MPS11_REG_RAMP, ramp_reg | ramp_enable);
 	}
 
 	ramp_reg &= 0x00;
-	ramp_reg |= get_ramp_delay(s2mps11->ramp_delay5) >> 6;
-	ramp_reg |= get_ramp_delay(s2mps11->ramp_delay16) >> 4;
-	ramp_reg |= get_ramp_delay(s2mps11->ramp_delay7810) >> 2;
+	ramp_reg |= get_ramp_delay(s2mps11->ramp_delay5) << 6;
+	ramp_reg |= get_ramp_delay(s2mps11->ramp_delay16) << 4;
+	ramp_reg |= get_ramp_delay(s2mps11->ramp_delay7810) << 2;
 	ramp_reg |= get_ramp_delay(s2mps11->ramp_delay9);
 	sec_reg_write(iodev, S2MPS11_REG_RAMP_BUCK, ramp_reg);
 
@@ -307,7 +307,7 @@
 	return ret;
 }
 
-static int __devexit s2mps11_pmic_remove(struct platform_device *pdev)
+static int s2mps11_pmic_remove(struct platform_device *pdev)
 {
 	struct s2mps11_info *s2mps11 = platform_get_drvdata(pdev);
 	int i;
@@ -330,7 +330,7 @@
 		.owner = THIS_MODULE,
 	},
 	.probe = s2mps11_pmic_probe,
-	.remove = __devexit_p(s2mps11_pmic_remove),
+	.remove = s2mps11_pmic_remove,
 	.id_table = s2mps11_pmic_id,
 };
 
diff --git a/drivers/regulator/s5m8767.c b/drivers/regulator/s5m8767.c
index abe64a3..9f991f2 100644
--- a/drivers/regulator/s5m8767.c
+++ b/drivers/regulator/s5m8767.c
@@ -168,7 +168,7 @@
 static int s5m8767_get_register(struct regulator_dev *rdev, int *reg,
 				int *enable_ctrl)
 {
-	int reg_id = rdev_get_id(rdev);
+	int i, reg_id = rdev_get_id(rdev);
 	unsigned int mode;
 	struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev);
 
@@ -195,8 +195,17 @@
 		return -EINVAL;
 	}
 
-	mode = s5m8767->opmode[reg_id].mode;
-	*enable_ctrl = s5m8767_opmode_reg[reg_id][mode] << S5M8767_ENCTRL_SHIFT;
+	for (i = 0; i < s5m8767->num_regulators; i++) {
+		if (s5m8767->opmode[i].id == reg_id) {
+			mode = s5m8767->opmode[i].mode;
+			break;
+		}
+	}
+
+	if (i < s5m8767->num_regulators)
+		*enable_ctrl =
+		s5m8767_opmode_reg[reg_id][mode] << S5M8767_ENCTRL_SHIFT;
+
 	return 0;
 }
 
@@ -263,17 +272,17 @@
 		reg = S5M8767_REG_BUCK1CTRL2;
 		break;
 	case S5M8767_BUCK2:
-		reg = S5M8767_REG_BUCK2DVS2;
+		reg = S5M8767_REG_BUCK2DVS1;
 		if (s5m8767->buck2_gpiodvs)
 			reg += s5m8767->buck_gpioindex;
 		break;
 	case S5M8767_BUCK3:
-		reg = S5M8767_REG_BUCK3DVS2;
+		reg = S5M8767_REG_BUCK3DVS1;
 		if (s5m8767->buck3_gpiodvs)
 			reg += s5m8767->buck_gpioindex;
 		break;
 	case S5M8767_BUCK4:
-		reg = S5M8767_REG_BUCK4DVS2;
+		reg = S5M8767_REG_BUCK4DVS1;
 		if (s5m8767->buck4_gpiodvs)
 			reg += s5m8767->buck_gpioindex;
 		break;
@@ -499,7 +508,7 @@
 	s5m8767_regulator_desc(BUCK9),
 };
 
-static __devinit int s5m8767_pmic_probe(struct platform_device *pdev)
+static int s5m8767_pmic_probe(struct platform_device *pdev)
 {
 	struct sec_pmic_dev *iodev = dev_get_drvdata(pdev->dev.parent);
 	struct sec_platform_data *pdata = dev_get_platdata(iodev->dev);
@@ -547,7 +556,7 @@
 	rdev = s5m8767->rdev;
 	s5m8767->dev = &pdev->dev;
 	s5m8767->iodev = iodev;
-	s5m8767->num_regulators = S5M8767_REG_MAX - 2;
+	s5m8767->num_regulators = pdata->num_regulators;
 	platform_set_drvdata(pdev, s5m8767);
 
 	s5m8767->buck_gpioindex = pdata->buck_default_idx;
@@ -617,9 +626,16 @@
 		}
 	}
 
-	if (gpio_is_valid(pdata->buck_gpios[0]) &&
-		gpio_is_valid(pdata->buck_gpios[1]) &&
-		gpio_is_valid(pdata->buck_gpios[2])) {
+	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])) {
+			dev_err(&pdev->dev, "GPIO NOT VALID\n");
+			return -EINVAL;
+		}
+
 		ret = devm_gpio_request(&pdev->dev, pdata->buck_gpios[0],
 					"S5M8767 SET1");
 		if (ret)
@@ -644,10 +660,6 @@
 		/* SET3 GPIO */
 		gpio_direction_output(pdata->buck_gpios[2],
 				(s5m8767->buck_gpioindex >> 0) & 0x1);
-	} else {
-		dev_err(&pdev->dev, "GPIO NOT VALID\n");
-		ret = -EINVAL;
-		return ret;
 	}
 
 	ret = devm_gpio_request(&pdev->dev, pdata->buck_ds[0], "S5M8767 DS2");
@@ -773,7 +785,7 @@
 	return ret;
 }
 
-static int __devexit s5m8767_pmic_remove(struct platform_device *pdev)
+static int s5m8767_pmic_remove(struct platform_device *pdev)
 {
 	struct s5m8767_info *s5m8767 = platform_get_drvdata(pdev);
 	struct regulator_dev **rdev = s5m8767->rdev;
@@ -798,7 +810,7 @@
 		.owner = THIS_MODULE,
 	},
 	.probe = s5m8767_pmic_probe,
-	.remove = __devexit_p(s5m8767_pmic_remove),
+	.remove = s5m8767_pmic_remove,
 	.id_table = s5m8767_pmic_id,
 };
 
diff --git a/drivers/regulator/tps51632-regulator.c b/drivers/regulator/tps51632-regulator.c
new file mode 100644
index 0000000..ab21133
--- /dev/null
+++ b/drivers/regulator/tps51632-regulator.c
@@ -0,0 +1,342 @@
+/*
+ * tps51632-regulator.c -- TI TPS51632
+ *
+ * Regulator driver for TPS51632 3-2-1 Phase D-Cap Step Down Driverless
+ * Controller with serial VID control and DVFS.
+ *
+ * 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/err.h>
+#include <linux/i2c.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/tps51632-regulator.h>
+#include <linux/slab.h>
+
+/* Register definitions */
+#define TPS51632_VOLTAGE_SELECT_REG		0x0
+#define TPS51632_VOLTAGE_BASE_REG		0x1
+#define TPS51632_OFFSET_REG			0x2
+#define TPS51632_IMON_REG			0x3
+#define TPS51632_VMAX_REG			0x4
+#define TPS51632_DVFS_CONTROL_REG		0x5
+#define TPS51632_POWER_STATE_REG		0x6
+#define TPS51632_SLEW_REGS			0x7
+#define TPS51632_FAULT_REG			0x14
+
+#define TPS51632_MAX_REG			0x15
+
+#define TPS51632_VOUT_MASK			0x7F
+#define TPS51632_VOUT_OFFSET_MASK		0x1F
+#define TPS51632_VMAX_MASK			0x7F
+#define TPS51632_VMAX_LOCK			0x80
+
+/* TPS51632_DVFS_CONTROL_REG */
+#define TPS51632_DVFS_PWMEN			0x1
+#define TPS51632_DVFS_STEP_20			0x2
+#define TPS51632_DVFS_VMAX_PG			0x4
+#define TPS51632_DVFS_PWMRST			0x8
+#define TPS51632_DVFS_OCA_EN			0x10
+#define TPS51632_DVFS_FCCM			0x20
+
+/* TPS51632_POWER_STATE_REG */
+#define TPS51632_POWER_STATE_MASK		0x03
+#define TPS51632_POWER_STATE_MULTI_PHASE_CCM	0x0
+#define TPS51632_POWER_STATE_SINGLE_PHASE_CCM	0x1
+#define TPS51632_POWER_STATE_SINGLE_PHASE_DCM	0x2
+
+#define TPS51632_MIN_VOLATGE			500000
+#define TPS51632_MAX_VOLATGE			1520000
+#define TPS51632_VOLATGE_STEP_10mV		10000
+#define TPS51632_VOLATGE_STEP_20mV		20000
+#define TPS51632_MAX_VSEL			0x7F
+#define TPS51632_MIN_VSEL			0x19
+#define TPS51632_DEFAULT_RAMP_DELAY		6000
+#define TPS51632_VOLT_VSEL(uV)					\
+		(DIV_ROUND_UP(uV - TPS51632_MIN_VOLATGE,	\
+			TPS51632_VOLATGE_STEP_10mV) +		\
+			TPS51632_MIN_VSEL)
+
+/* TPS51632 chip information */
+struct tps51632_chip {
+	struct device *dev;
+	struct regulator_desc desc;
+	struct regulator_dev *rdev;
+	struct regmap *regmap;
+	bool enable_pwm_dvfs;
+};
+
+static int tps51632_dcdc_get_voltage_sel(struct regulator_dev *rdev)
+{
+	struct tps51632_chip *tps = rdev_get_drvdata(rdev);
+	unsigned int data;
+	int ret;
+	unsigned int reg = TPS51632_VOLTAGE_SELECT_REG;
+	int vsel;
+
+	if (tps->enable_pwm_dvfs)
+		reg = TPS51632_VOLTAGE_BASE_REG;
+
+	ret = regmap_read(tps->regmap, reg, &data);
+	if (ret < 0) {
+		dev_err(tps->dev, "reg read failed, err %d\n", ret);
+		return ret;
+	}
+
+	vsel = data & TPS51632_VOUT_MASK;
+	return vsel;
+}
+
+static int tps51632_dcdc_set_voltage_sel(struct regulator_dev *rdev,
+		unsigned selector)
+{
+	struct tps51632_chip *tps = rdev_get_drvdata(rdev);
+	int ret;
+	unsigned int reg = TPS51632_VOLTAGE_SELECT_REG;
+
+	if (tps->enable_pwm_dvfs)
+		reg = TPS51632_VOLTAGE_BASE_REG;
+
+	if (selector > TPS51632_MAX_VSEL)
+		return -EINVAL;
+
+	ret = regmap_write(tps->regmap, reg, selector);
+	if (ret < 0)
+		dev_err(tps->dev, "reg write failed, err %d\n", ret);
+	return ret;
+}
+
+static int tps51632_dcdc_set_ramp_delay(struct regulator_dev *rdev,
+		int ramp_delay)
+{
+	struct tps51632_chip *tps = rdev_get_drvdata(rdev);
+	int bit = ramp_delay/6000;
+	int ret;
+
+	if (bit)
+		bit--;
+	ret = regmap_write(tps->regmap, TPS51632_SLEW_REGS, BIT(bit));
+	if (ret < 0)
+		dev_err(tps->dev, "SLEW reg write failed, err %d\n", ret);
+	return ret;
+}
+
+static struct regulator_ops tps51632_dcdc_ops = {
+	.get_voltage_sel	= tps51632_dcdc_get_voltage_sel,
+	.set_voltage_sel	= tps51632_dcdc_set_voltage_sel,
+	.list_voltage		= regulator_list_voltage_linear,
+	.set_voltage_time_sel	= regulator_set_voltage_time_sel,
+	.set_ramp_delay		= tps51632_dcdc_set_ramp_delay,
+};
+
+static int tps51632_init_dcdc(struct tps51632_chip *tps,
+		struct tps51632_regulator_platform_data *pdata)
+{
+	int ret;
+	uint8_t	control = 0;
+	int vsel;
+
+	if (!pdata->enable_pwm_dvfs)
+		goto skip_pwm_config;
+
+	control |= TPS51632_DVFS_PWMEN;
+	tps->enable_pwm_dvfs = pdata->enable_pwm_dvfs;
+	vsel = TPS51632_VOLT_VSEL(pdata->base_voltage_uV);
+	ret = regmap_write(tps->regmap, TPS51632_VOLTAGE_BASE_REG, vsel);
+	if (ret < 0) {
+		dev_err(tps->dev, "BASE reg write failed, err %d\n", ret);
+		return ret;
+	}
+
+	if (pdata->dvfs_step_20mV)
+		control |= TPS51632_DVFS_STEP_20;
+
+	if (pdata->max_voltage_uV) {
+		unsigned int vmax;
+		/**
+		 * TPS51632 hw behavior: VMAX register can be write only
+		 * once as it get locked after first write. The lock get
+		 * reset only when device is power-reset.
+		 * Write register only when lock bit is not enabled.
+		 */
+		ret = regmap_read(tps->regmap, TPS51632_VMAX_REG, &vmax);
+		if (ret < 0) {
+			dev_err(tps->dev, "VMAX read failed, err %d\n", ret);
+			return ret;
+		}
+		if (!(vmax & TPS51632_VMAX_LOCK)) {
+			vsel = TPS51632_VOLT_VSEL(pdata->max_voltage_uV);
+			ret = regmap_write(tps->regmap, TPS51632_VMAX_REG,
+					vsel);
+			if (ret < 0) {
+				dev_err(tps->dev,
+					"VMAX write failed, err %d\n", ret);
+				return ret;
+			}
+		}
+	}
+
+skip_pwm_config:
+	ret = regmap_write(tps->regmap, TPS51632_DVFS_CONTROL_REG, control);
+	if (ret < 0)
+		dev_err(tps->dev, "DVFS reg write failed, err %d\n", ret);
+	return ret;
+}
+
+static bool rd_wr_reg(struct device *dev, unsigned int reg)
+{
+	if ((reg >= 0x8) && (reg <= 0x10))
+		return false;
+	return true;
+}
+
+static const struct regmap_config tps51632_regmap_config = {
+	.reg_bits		= 8,
+	.val_bits		= 8,
+	.writeable_reg		= rd_wr_reg,
+	.readable_reg		= rd_wr_reg,
+	.max_register		= TPS51632_MAX_REG - 1,
+	.cache_type		= REGCACHE_RBTREE,
+};
+
+static int tps51632_probe(struct i2c_client *client,
+				const struct i2c_device_id *id)
+{
+	struct tps51632_regulator_platform_data *pdata;
+	struct regulator_dev *rdev;
+	struct tps51632_chip *tps;
+	int ret;
+	struct regulator_config config = { };
+
+	pdata = client->dev.platform_data;
+	if (!pdata) {
+		dev_err(&client->dev, "No Platform data\n");
+		return -EINVAL;
+	}
+
+	if (pdata->enable_pwm_dvfs) {
+		if ((pdata->base_voltage_uV < TPS51632_MIN_VOLATGE) ||
+		    (pdata->base_voltage_uV > TPS51632_MAX_VOLATGE)) {
+			dev_err(&client->dev, "Invalid base_voltage_uV setting\n");
+			return -EINVAL;
+		}
+
+		if ((pdata->max_voltage_uV) &&
+		    ((pdata->max_voltage_uV < TPS51632_MIN_VOLATGE) ||
+		     (pdata->max_voltage_uV > TPS51632_MAX_VOLATGE))) {
+			dev_err(&client->dev, "Invalid max_voltage_uV setting\n");
+			return -EINVAL;
+		}
+	}
+
+	tps = devm_kzalloc(&client->dev, sizeof(*tps), GFP_KERNEL);
+	if (!tps) {
+		dev_err(&client->dev, "Memory allocation failed\n");
+		return -ENOMEM;
+	}
+
+	tps->dev = &client->dev;
+	tps->desc.name = id->name;
+	tps->desc.id = 0;
+	tps->desc.ramp_delay = TPS51632_DEFAULT_RAMP_DELAY;
+	tps->desc.min_uV = TPS51632_MIN_VOLATGE;
+	tps->desc.uV_step = TPS51632_VOLATGE_STEP_10mV;
+	tps->desc.linear_min_sel = TPS51632_MIN_VSEL;
+	tps->desc.n_voltages = TPS51632_MAX_VSEL + 1;
+	tps->desc.ops = &tps51632_dcdc_ops;
+	tps->desc.type = REGULATOR_VOLTAGE;
+	tps->desc.owner = THIS_MODULE;
+
+	tps->regmap = devm_regmap_init_i2c(client, &tps51632_regmap_config);
+	if (IS_ERR(tps->regmap)) {
+		ret = PTR_ERR(tps->regmap);
+		dev_err(&client->dev, "regmap init failed, err %d\n", ret);
+		return ret;
+	}
+	i2c_set_clientdata(client, tps);
+
+	ret = tps51632_init_dcdc(tps, pdata);
+	if (ret < 0) {
+		dev_err(tps->dev, "Init failed, err = %d\n", ret);
+		return ret;
+	}
+
+	/* Register the regulators */
+	config.dev = &client->dev;
+	config.init_data = pdata->reg_init_data;
+	config.driver_data = tps;
+	config.regmap = tps->regmap;
+	config.of_node = client->dev.of_node;
+
+	rdev = regulator_register(&tps->desc, &config);
+	if (IS_ERR(rdev)) {
+		dev_err(tps->dev, "regulator register failed\n");
+		return PTR_ERR(rdev);
+	}
+
+	tps->rdev = rdev;
+	return 0;
+}
+
+static int tps51632_remove(struct i2c_client *client)
+{
+	struct tps51632_chip *tps = i2c_get_clientdata(client);
+
+	regulator_unregister(tps->rdev);
+	return 0;
+}
+
+static const struct i2c_device_id tps51632_id[] = {
+	{.name = "tps51632",},
+	{},
+};
+
+MODULE_DEVICE_TABLE(i2c, tps51632_id);
+
+static struct i2c_driver tps51632_i2c_driver = {
+	.driver = {
+		.name = "tps51632",
+		.owner = THIS_MODULE,
+	},
+	.probe = tps51632_probe,
+	.remove = tps51632_remove,
+	.id_table = tps51632_id,
+};
+
+static int __init tps51632_init(void)
+{
+	return i2c_add_driver(&tps51632_i2c_driver);
+}
+subsys_initcall(tps51632_init);
+
+static void __exit tps51632_cleanup(void)
+{
+	i2c_del_driver(&tps51632_i2c_driver);
+}
+module_exit(tps51632_cleanup);
+
+MODULE_AUTHOR("Laxman Dewangan <ldewangan@nvidia.com>");
+MODULE_DESCRIPTION("TPS51632 voltage regulator driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/regulator/tps6105x-regulator.c b/drivers/regulator/tps6105x-regulator.c
index 1378409..ec9453f 100644
--- a/drivers/regulator/tps6105x-regulator.c
+++ b/drivers/regulator/tps6105x-regulator.c
@@ -127,7 +127,7 @@
 /*
  * Registers the chip as a voltage regulator
  */
-static int __devinit tps6105x_regulator_probe(struct platform_device *pdev)
+static int tps6105x_regulator_probe(struct platform_device *pdev)
 {
 	struct tps6105x *tps6105x = dev_get_platdata(&pdev->dev);
 	struct tps6105x_platform_data *pdata = tps6105x->pdata;
@@ -159,7 +159,7 @@
 	return 0;
 }
 
-static int __devexit tps6105x_regulator_remove(struct platform_device *pdev)
+static int tps6105x_regulator_remove(struct platform_device *pdev)
 {
 	struct tps6105x *tps6105x = dev_get_platdata(&pdev->dev);
 	regulator_unregister(tps6105x->regulator);
@@ -172,7 +172,7 @@
 		.owner = THIS_MODULE,
 	},
 	.probe = tps6105x_regulator_probe,
-	.remove = __devexit_p(tps6105x_regulator_remove),
+	.remove = tps6105x_regulator_remove,
 };
 
 static __init int tps6105x_regulator_init(void)
diff --git a/drivers/regulator/tps62360-regulator.c b/drivers/regulator/tps62360-regulator.c
index 68729a7..acbd63f 100644
--- a/drivers/regulator/tps62360-regulator.c
+++ b/drivers/regulator/tps62360-regulator.c
@@ -243,7 +243,7 @@
 	.get_mode		= tps62360_get_mode,
 };
 
-static int __devinit tps62360_init_dcdc(struct tps62360_chip *tps,
+static int tps62360_init_dcdc(struct tps62360_chip *tps,
 		struct tps62360_regulator_platform_data *pdata)
 {
 	int ret;
@@ -339,7 +339,7 @@
 MODULE_DEVICE_TABLE(of, tps62360_of_match);
 #endif
 
-static int __devinit tps62360_probe(struct i2c_client *client,
+static int tps62360_probe(struct i2c_client *client,
 				     const struct i2c_device_id *id)
 {
 	struct regulator_config config = { };
@@ -490,7 +490,7 @@
  *
  * Unregister TPS driver as an i2c client device driver
  */
-static int __devexit tps62360_remove(struct i2c_client *client)
+static int tps62360_remove(struct i2c_client *client)
 {
 	struct tps62360_chip *tps = i2c_get_clientdata(client);
 
@@ -531,7 +531,7 @@
 		.of_match_table = of_match_ptr(tps62360_of_match),
 	},
 	.probe = tps62360_probe,
-	.remove = __devexit_p(tps62360_remove),
+	.remove = tps62360_remove,
 	.shutdown = tps62360_shutdown,
 	.id_table = tps62360_id,
 };
diff --git a/drivers/regulator/tps65023-regulator.c b/drivers/regulator/tps65023-regulator.c
index 6998d57..9b9af6d 100644
--- a/drivers/regulator/tps65023-regulator.c
+++ b/drivers/regulator/tps65023-regulator.c
@@ -219,7 +219,7 @@
 	.val_bits = 8,
 };
 
-static int __devinit tps_65023_probe(struct i2c_client *client,
+static int tps_65023_probe(struct i2c_client *client,
 				     const struct i2c_device_id *id)
 {
 	const struct tps_driver_data *drv_data = (void *)id->driver_data;
@@ -319,7 +319,7 @@
 	return error;
 }
 
-static int __devexit tps_65023_remove(struct i2c_client *client)
+static int tps_65023_remove(struct i2c_client *client)
 {
 	struct tps_pmic *tps = i2c_get_clientdata(client);
 	int i;
@@ -446,7 +446,7 @@
 		.owner = THIS_MODULE,
 	},
 	.probe = tps_65023_probe,
-	.remove = __devexit_p(tps_65023_remove),
+	.remove = tps_65023_remove,
 	.id_table = tps_65023_id,
 };
 
diff --git a/drivers/regulator/tps6507x-regulator.c b/drivers/regulator/tps6507x-regulator.c
index 07d01cc..0233cfb 100644
--- a/drivers/regulator/tps6507x-regulator.c
+++ b/drivers/regulator/tps6507x-regulator.c
@@ -356,7 +356,7 @@
 	.list_voltage = regulator_list_voltage_table,
 };
 
-static __devinit int tps6507x_pmic_probe(struct platform_device *pdev)
+static int tps6507x_pmic_probe(struct platform_device *pdev)
 {
 	struct tps6507x_dev *tps6507x_dev = dev_get_drvdata(pdev->dev.parent);
 	struct tps_info *info = &tps6507x_pmic_regs[0];
@@ -439,7 +439,7 @@
 	return error;
 }
 
-static int __devexit tps6507x_pmic_remove(struct platform_device *pdev)
+static int tps6507x_pmic_remove(struct platform_device *pdev)
 {
 	struct tps6507x_dev *tps6507x_dev = platform_get_drvdata(pdev);
 	struct tps6507x_pmic *tps = tps6507x_dev->pmic;
@@ -456,7 +456,7 @@
 		.owner = THIS_MODULE,
 	},
 	.probe = tps6507x_pmic_probe,
-	.remove = __devexit_p(tps6507x_pmic_remove),
+	.remove = tps6507x_pmic_remove,
 };
 
 static int __init tps6507x_pmic_init(void)
diff --git a/drivers/regulator/tps65090-regulator.c b/drivers/regulator/tps65090-regulator.c
index 001ad55..41c3917 100644
--- a/drivers/regulator/tps65090-regulator.c
+++ b/drivers/regulator/tps65090-regulator.c
@@ -18,119 +18,240 @@
 
 #include <linux/module.h>
 #include <linux/init.h>
+#include <linux/gpio.h>
 #include <linux/slab.h>
 #include <linux/err.h>
 #include <linux/platform_device.h>
 #include <linux/regulator/driver.h>
 #include <linux/regulator/machine.h>
 #include <linux/mfd/tps65090.h>
-#include <linux/regulator/tps65090-regulator.h>
 
 struct tps65090_regulator {
-	int		id;
-	/* used by regulator core */
-	struct regulator_desc	desc;
-
-	/* Device */
 	struct device		*dev;
+	struct regulator_desc	*desc;
+	struct regulator_dev	*rdev;
 };
 
-static struct regulator_ops tps65090_ops = {
-	.enable = regulator_enable_regmap,
-	.disable = regulator_disable_regmap,
-	.is_enabled = regulator_is_enabled_regmap,
+static struct regulator_ops tps65090_ext_control_ops = {
 };
 
-#define tps65090_REG(_id)				\
+static struct regulator_ops tps65090_reg_contol_ops = {
+	.enable		= regulator_enable_regmap,
+	.disable	= regulator_disable_regmap,
+	.is_enabled	= regulator_is_enabled_regmap,
+};
+
+static struct regulator_ops tps65090_ldo_ops = {
+};
+
+#define tps65090_REG_DESC(_id, _sname, _en_reg, _ops)	\
 {							\
-	.id		= TPS65090_ID_##_id,		\
-	.desc = {					\
-		.name = tps65090_rails(_id),		\
-		.id = TPS65090_ID_##_id,		\
-		.ops = &tps65090_ops,			\
-		.type = REGULATOR_VOLTAGE,		\
-		.owner = THIS_MODULE,			\
-		.enable_reg = (TPS65090_ID_##_id) + 12,	\
-		.enable_mask = BIT(0),			\
-	},						\
+	.name = "TPS65090_RAILS"#_id,			\
+	.supply_name = _sname,				\
+	.id = TPS65090_REGULATOR_##_id,			\
+	.ops = &_ops,					\
+	.enable_reg = _en_reg,				\
+	.enable_mask = BIT(0),				\
+	.type = REGULATOR_VOLTAGE,			\
+	.owner = THIS_MODULE,				\
 }
 
-static struct tps65090_regulator TPS65090_regulator[] = {
-	tps65090_REG(DCDC1),
-	tps65090_REG(DCDC2),
-	tps65090_REG(DCDC3),
-	tps65090_REG(FET1),
-	tps65090_REG(FET2),
-	tps65090_REG(FET3),
-	tps65090_REG(FET4),
-	tps65090_REG(FET5),
-	tps65090_REG(FET6),
-	tps65090_REG(FET7),
+static struct regulator_desc tps65090_regulator_desc[] = {
+	tps65090_REG_DESC(DCDC1, "vsys1",   0x0C, tps65090_reg_contol_ops),
+	tps65090_REG_DESC(DCDC2, "vsys2",   0x0D, tps65090_reg_contol_ops),
+	tps65090_REG_DESC(DCDC3, "vsys3",   0x0E, tps65090_reg_contol_ops),
+	tps65090_REG_DESC(FET1,  "infet1",  0x0F, tps65090_reg_contol_ops),
+	tps65090_REG_DESC(FET2,  "infet2",  0x10, tps65090_reg_contol_ops),
+	tps65090_REG_DESC(FET3,  "infet3",  0x11, tps65090_reg_contol_ops),
+	tps65090_REG_DESC(FET4,  "infet4",  0x12, tps65090_reg_contol_ops),
+	tps65090_REG_DESC(FET5,  "infet5",  0x13, tps65090_reg_contol_ops),
+	tps65090_REG_DESC(FET6,  "infet6",  0x14, tps65090_reg_contol_ops),
+	tps65090_REG_DESC(FET7,  "infet7",  0x15, tps65090_reg_contol_ops),
+	tps65090_REG_DESC(LDO1,  "vsys_l1", 0,    tps65090_ldo_ops),
+	tps65090_REG_DESC(LDO2,  "vsys_l2", 0,    tps65090_ldo_ops),
 };
 
-static inline struct tps65090_regulator *find_regulator_info(int id)
+static inline bool is_dcdc(int id)
 {
-	struct tps65090_regulator *ri;
-	int i;
-
-	for (i = 0; i < ARRAY_SIZE(TPS65090_regulator); i++) {
-		ri = &TPS65090_regulator[i];
-		if (ri->desc.id == id)
-			return ri;
+	switch (id) {
+	case TPS65090_REGULATOR_DCDC1:
+	case TPS65090_REGULATOR_DCDC2:
+	case TPS65090_REGULATOR_DCDC3:
+		return true;
+	default:
+		return false;
 	}
-	return NULL;
 }
 
-static int __devinit tps65090_regulator_probe(struct platform_device *pdev)
+static int tps65090_config_ext_control(
+	struct tps65090_regulator *ri, bool enable)
+{
+	int ret;
+	struct device *parent = ri->dev->parent;
+	unsigned int reg_en_reg = ri->desc->enable_reg;
+
+	if (enable)
+		ret = tps65090_set_bits(parent, reg_en_reg, 1);
+	else
+		ret =  tps65090_clr_bits(parent, reg_en_reg, 1);
+	if (ret < 0)
+		dev_err(ri->dev, "Error in updating reg 0x%x\n", reg_en_reg);
+	return ret;
+}
+
+static int tps65090_regulator_disable_ext_control(
+		struct tps65090_regulator *ri,
+		struct tps65090_regulator_plat_data *tps_pdata)
+{
+	int ret = 0;
+	struct device *parent = ri->dev->parent;
+	unsigned int reg_en_reg = ri->desc->enable_reg;
+
+	/*
+	 * First enable output for internal control if require.
+	 * And then disable external control.
+	 */
+	if (tps_pdata->reg_init_data->constraints.always_on ||
+			tps_pdata->reg_init_data->constraints.boot_on) {
+		ret =  tps65090_set_bits(parent, reg_en_reg, 0);
+		if (ret < 0) {
+			dev_err(ri->dev, "Error in set reg 0x%x\n", reg_en_reg);
+			return ret;
+		}
+	}
+	return tps65090_config_ext_control(ri, false);
+}
+
+static void tps65090_configure_regulator_config(
+		struct tps65090_regulator_plat_data *tps_pdata,
+		struct regulator_config *config)
+{
+	if (gpio_is_valid(tps_pdata->gpio)) {
+		int gpio_flag = GPIOF_OUT_INIT_LOW;
+
+		if (tps_pdata->reg_init_data->constraints.always_on ||
+				tps_pdata->reg_init_data->constraints.boot_on)
+			gpio_flag = GPIOF_OUT_INIT_HIGH;
+
+		config->ena_gpio = tps_pdata->gpio;
+		config->ena_gpio_flags = gpio_flag;
+	}
+}
+
+static int tps65090_regulator_probe(struct platform_device *pdev)
 {
 	struct tps65090 *tps65090_mfd = dev_get_drvdata(pdev->dev.parent);
 	struct tps65090_regulator *ri = NULL;
 	struct regulator_config config = { };
 	struct regulator_dev *rdev;
-	struct tps65090_regulator_platform_data *tps_pdata;
-	int id = pdev->id;
+	struct tps65090_regulator_plat_data *tps_pdata;
+	struct tps65090_regulator *pmic;
+	struct tps65090_platform_data *tps65090_pdata;
+	int num;
+	int ret;
 
-	dev_dbg(&pdev->dev, "Probing regulator %d\n", id);
+	dev_dbg(&pdev->dev, "Probing regulator\n");
 
-	ri = find_regulator_info(id);
-	if (ri == NULL) {
-		dev_err(&pdev->dev, "invalid regulator ID specified\n");
+	tps65090_pdata = dev_get_platdata(pdev->dev.parent);
+	if (!tps65090_pdata) {
+		dev_err(&pdev->dev, "Platform data missing\n");
 		return -EINVAL;
 	}
-	tps_pdata = pdev->dev.platform_data;
-	ri->dev = &pdev->dev;
 
-	config.dev = &pdev->dev;
-	config.init_data = &tps_pdata->regulator;
-	config.driver_data = ri;
-	config.regmap = tps65090_mfd->rmap;
-
-	rdev = regulator_register(&ri->desc, &config);
-	if (IS_ERR(rdev)) {
-		dev_err(&pdev->dev, "failed to register regulator %s\n",
-				ri->desc.name);
-		return PTR_ERR(rdev);
+	pmic = devm_kzalloc(&pdev->dev, TPS65090_REGULATOR_MAX * sizeof(*pmic),
+			GFP_KERNEL);
+	if (!pmic) {
+		dev_err(&pdev->dev, "mem alloc for pmic failed\n");
+		return -ENOMEM;
 	}
 
-	platform_set_drvdata(pdev, rdev);
+	for (num = 0; num < TPS65090_REGULATOR_MAX; num++) {
+		tps_pdata = tps65090_pdata->reg_pdata[num];
+
+		ri = &pmic[num];
+		ri->dev = &pdev->dev;
+		ri->desc = &tps65090_regulator_desc[num];
+
+		/*
+		 * TPS5090 DCDC support the control from external digital input.
+		 * Configure it as per platform data.
+		 */
+		if (tps_pdata && is_dcdc(num) && tps_pdata->reg_init_data) {
+			if (tps_pdata->enable_ext_control) {
+				tps65090_configure_regulator_config(
+						tps_pdata, &config);
+				ri->desc->ops = &tps65090_ext_control_ops;
+			} else {
+				ret = tps65090_regulator_disable_ext_control(
+						ri, tps_pdata);
+				if (ret < 0) {
+					dev_err(&pdev->dev,
+						"failed disable ext control\n");
+					goto scrub;
+				}
+			}
+		}
+
+		config.dev = &pdev->dev;
+		config.driver_data = ri;
+		config.regmap = tps65090_mfd->rmap;
+		if (tps_pdata)
+			config.init_data = tps_pdata->reg_init_data;
+		else
+			config.init_data = NULL;
+
+		rdev = regulator_register(ri->desc, &config);
+		if (IS_ERR(rdev)) {
+			dev_err(&pdev->dev, "failed to register regulator %s\n",
+				ri->desc->name);
+			ret = PTR_ERR(rdev);
+			goto scrub;
+		}
+		ri->rdev = rdev;
+
+		/* Enable external control if it is require */
+		if (tps_pdata && is_dcdc(num) && tps_pdata->reg_init_data &&
+				tps_pdata->enable_ext_control) {
+			ret = tps65090_config_ext_control(ri, true);
+			if (ret < 0) {
+				/* Increment num to get unregister rdev */
+				num++;
+				goto scrub;
+			}
+		}
+	}
+
+	platform_set_drvdata(pdev, pmic);
 	return 0;
+
+scrub:
+	while (--num >= 0) {
+		ri = &pmic[num];
+		regulator_unregister(ri->rdev);
+	}
+	return ret;
 }
 
-static int __devexit tps65090_regulator_remove(struct platform_device *pdev)
+static int tps65090_regulator_remove(struct platform_device *pdev)
 {
-	struct regulator_dev *rdev = platform_get_drvdata(pdev);
+	struct tps65090_regulator *pmic = platform_get_drvdata(pdev);
+	struct tps65090_regulator *ri;
+	int num;
 
-	regulator_unregister(rdev);
+	for (num = 0; num < TPS65090_REGULATOR_MAX; ++num) {
+		ri = &pmic[num];
+		regulator_unregister(ri->rdev);
+	}
 	return 0;
 }
 
 static struct platform_driver tps65090_regulator_driver = {
 	.driver	= {
-		.name	= "tps65090-regulator",
+		.name	= "tps65090-pmic",
 		.owner	= THIS_MODULE,
 	},
 	.probe		= tps65090_regulator_probe,
-	.remove		= __devexit_p(tps65090_regulator_remove),
+	.remove		= tps65090_regulator_remove,
 };
 
 static int __init tps65090_regulator_init(void)
@@ -148,3 +269,4 @@
 MODULE_DESCRIPTION("tps65090 regulator driver");
 MODULE_AUTHOR("Venu Byravarasu <vbyravarasu@nvidia.com>");
 MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:tps65090-pmic");
diff --git a/drivers/regulator/tps65217-regulator.c b/drivers/regulator/tps65217-regulator.c
index ab00cab..73dce76 100644
--- a/drivers/regulator/tps65217-regulator.c
+++ b/drivers/regulator/tps65217-regulator.c
@@ -332,7 +332,7 @@
 }
 #endif
 
-static int __devinit tps65217_regulator_probe(struct platform_device *pdev)
+static int tps65217_regulator_probe(struct platform_device *pdev)
 {
 	struct tps65217 *tps = dev_get_drvdata(pdev->dev.parent);
 	struct tps65217_board *pdata = dev_get_platdata(tps->dev);
@@ -397,7 +397,7 @@
 	return ret;
 }
 
-static int __devexit tps65217_regulator_remove(struct platform_device *pdev)
+static int tps65217_regulator_remove(struct platform_device *pdev)
 {
 	struct tps65217 *tps = platform_get_drvdata(pdev);
 	unsigned int i;
@@ -415,7 +415,7 @@
 		.name = "tps65217-pmic",
 	},
 	.probe = tps65217_regulator_probe,
-	.remove = __devexit_p(tps65217_regulator_remove),
+	.remove = tps65217_regulator_remove,
 };
 
 static int __init tps65217_regulator_init(void)
diff --git a/drivers/regulator/tps6524x-regulator.c b/drivers/regulator/tps6524x-regulator.c
index 058d2f2..843ee0a 100644
--- a/drivers/regulator/tps6524x-regulator.c
+++ b/drivers/regulator/tps6524x-regulator.c
@@ -592,7 +592,7 @@
 	return 0;
 }
 
-static int __devinit pmic_probe(struct spi_device *spi)
+static int pmic_probe(struct spi_device *spi)
 {
 	struct tps6524x *hw;
 	struct device *dev = &spi->dev;
@@ -649,7 +649,7 @@
 
 static struct spi_driver pmic_driver = {
 	.probe		= pmic_probe,
-	.remove		= __devexit_p(pmic_remove),
+	.remove		= pmic_remove,
 	.driver		= {
 		.name	= "tps6524x",
 		.owner	= THIS_MODULE,
diff --git a/drivers/regulator/tps6586x-regulator.c b/drivers/regulator/tps6586x-regulator.c
index ce1e7cb..f86da67 100644
--- a/drivers/regulator/tps6586x-regulator.c
+++ b/drivers/regulator/tps6586x-regulator.c
@@ -17,10 +17,12 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/err.h>
+#include <linux/of.h>
 #include <linux/slab.h>
 #include <linux/platform_device.h>
 #include <linux/regulator/driver.h>
 #include <linux/regulator/machine.h>
+#include <linux/regulator/of_regulator.h>
 #include <linux/mfd/tps6586x.h>
 
 /* supply control and voltage setting  */
@@ -255,10 +257,10 @@
 				 1 << ri->enable_bit[1]);
 }
 
-static int tps6586x_regulator_set_slew_rate(struct platform_device *pdev)
+static int tps6586x_regulator_set_slew_rate(struct platform_device *pdev,
+			int id, struct regulator_init_data *p)
 {
 	struct device *parent = pdev->dev.parent;
-	struct regulator_init_data *p = pdev->dev.platform_data;
 	struct tps6586x_settings *setting = p->driver_data;
 	uint8_t reg;
 
@@ -269,7 +271,7 @@
 		return 0;
 
 	/* only SM0 and SM1 can have the slew rate settings */
-	switch (pdev->id) {
+	switch (id) {
 	case TPS6586X_ID_SM_0:
 		reg = TPS6586X_SM0SL;
 		break;
@@ -298,58 +300,185 @@
 	return NULL;
 }
 
-static int __devinit tps6586x_regulator_probe(struct platform_device *pdev)
+#ifdef CONFIG_OF
+static struct of_regulator_match tps6586x_matches[] = {
+	{ .name = "sys",     .driver_data = (void *)TPS6586X_ID_SYS     },
+	{ .name = "sm0",     .driver_data = (void *)TPS6586X_ID_SM_0    },
+	{ .name = "sm1",     .driver_data = (void *)TPS6586X_ID_SM_1    },
+	{ .name = "sm2",     .driver_data = (void *)TPS6586X_ID_SM_2    },
+	{ .name = "ldo0",    .driver_data = (void *)TPS6586X_ID_LDO_0   },
+	{ .name = "ldo1",    .driver_data = (void *)TPS6586X_ID_LDO_1   },
+	{ .name = "ldo2",    .driver_data = (void *)TPS6586X_ID_LDO_2   },
+	{ .name = "ldo3",    .driver_data = (void *)TPS6586X_ID_LDO_3   },
+	{ .name = "ldo4",    .driver_data = (void *)TPS6586X_ID_LDO_4   },
+	{ .name = "ldo5",    .driver_data = (void *)TPS6586X_ID_LDO_5   },
+	{ .name = "ldo6",    .driver_data = (void *)TPS6586X_ID_LDO_6   },
+	{ .name = "ldo7",    .driver_data = (void *)TPS6586X_ID_LDO_7   },
+	{ .name = "ldo8",    .driver_data = (void *)TPS6586X_ID_LDO_8   },
+	{ .name = "ldo9",    .driver_data = (void *)TPS6586X_ID_LDO_9   },
+	{ .name = "ldo_rtc", .driver_data = (void *)TPS6586X_ID_LDO_RTC },
+};
+
+static struct tps6586x_platform_data *tps6586x_parse_regulator_dt(
+		struct platform_device *pdev,
+		struct of_regulator_match **tps6586x_reg_matches)
+{
+	const unsigned int num = ARRAY_SIZE(tps6586x_matches);
+	struct device_node *np = pdev->dev.parent->of_node;
+	struct device_node *regs;
+	const char *sys_rail = NULL;
+	unsigned int i;
+	struct tps6586x_platform_data *pdata;
+	int err;
+
+	regs = of_find_node_by_name(np, "regulators");
+	if (!regs) {
+		dev_err(&pdev->dev, "regulator node not found\n");
+		return NULL;
+	}
+
+	err = of_regulator_match(&pdev->dev, regs, tps6586x_matches, num);
+	if (err < 0) {
+		dev_err(&pdev->dev, "Regulator match failed, e %d\n", err);
+		of_node_put(regs);
+		return NULL;
+	}
+
+	of_node_put(regs);
+
+	pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
+	if (!pdata) {
+		dev_err(&pdev->dev, "Memory alloction failed\n");
+		return NULL;
+	}
+
+	for (i = 0; i < num; i++) {
+		int id;
+		if (!tps6586x_matches[i].init_data)
+			continue;
+
+		pdata->reg_init_data[i] = tps6586x_matches[i].init_data;
+		id = (int)tps6586x_matches[i].driver_data;
+		if (id == TPS6586X_ID_SYS)
+			sys_rail = pdata->reg_init_data[i]->constraints.name;
+
+		if ((id == TPS6586X_ID_LDO_5) || (id == TPS6586X_ID_LDO_RTC))
+			pdata->reg_init_data[i]->supply_regulator = sys_rail;
+	}
+	*tps6586x_reg_matches = tps6586x_matches;
+	return pdata;
+}
+#else
+static struct tps6586x_platform_data *tps6586x_parse_regulator_dt(
+		struct platform_device *pdev,
+		struct of_regulator_match **tps6586x_reg_matches)
+{
+	*tps6586x_reg_matches = NULL;
+	return NULL;
+}
+#endif
+
+static int tps6586x_regulator_probe(struct platform_device *pdev)
 {
 	struct tps6586x_regulator *ri = NULL;
 	struct regulator_config config = { };
-	struct regulator_dev *rdev;
-	int id = pdev->id;
+	struct regulator_dev **rdev;
+	struct regulator_init_data *reg_data;
+	struct tps6586x_platform_data *pdata;
+	struct of_regulator_match *tps6586x_reg_matches = NULL;
+	int id;
 	int err;
 
-	dev_dbg(&pdev->dev, "Probing regulator %d\n", id);
+	dev_dbg(&pdev->dev, "Probing regulator\n");
 
-	ri = find_regulator_info(id);
-	if (ri == NULL) {
-		dev_err(&pdev->dev, "invalid regulator ID specified\n");
-		return -EINVAL;
+	pdata = dev_get_platdata(pdev->dev.parent);
+	if ((!pdata) && (pdev->dev.parent->of_node))
+		pdata = tps6586x_parse_regulator_dt(pdev,
+					&tps6586x_reg_matches);
+
+	if (!pdata) {
+		dev_err(&pdev->dev, "Platform data not available, exiting\n");
+		return -ENODEV;
 	}
 
-	err = tps6586x_regulator_preinit(pdev->dev.parent, ri);
-	if (err)
-		return err;
+	rdev = devm_kzalloc(&pdev->dev, TPS6586X_ID_MAX_REGULATOR *
+				sizeof(*rdev), GFP_KERNEL);
+	if (!rdev) {
+		dev_err(&pdev->dev, "Mmemory alloc failed\n");
+		return -ENOMEM;
+	}
 
-	config.dev = pdev->dev.parent;
-	config.of_node = pdev->dev.of_node;
-	config.init_data = pdev->dev.platform_data;
-	config.driver_data = ri;
+	for (id = 0; id < TPS6586X_ID_MAX_REGULATOR; ++id) {
+		reg_data = pdata->reg_init_data[id];
 
-	rdev = regulator_register(&ri->desc, &config);
-	if (IS_ERR(rdev)) {
-		dev_err(&pdev->dev, "failed to register regulator %s\n",
-				ri->desc.name);
-		return PTR_ERR(rdev);
+		ri = find_regulator_info(id);
+		if (!ri) {
+			dev_err(&pdev->dev, "invalid regulator ID specified\n");
+			err = -EINVAL;
+			goto fail;
+		}
+
+		err = tps6586x_regulator_preinit(pdev->dev.parent, ri);
+		if (err) {
+			dev_err(&pdev->dev,
+				"regulator %d preinit failed, e %d\n", id, err);
+			goto fail;
+		}
+
+		config.dev = pdev->dev.parent;
+		config.init_data = reg_data;
+		config.driver_data = ri;
+
+		if (tps6586x_reg_matches)
+			config.of_node = tps6586x_reg_matches[id].of_node;
+
+		rdev[id] = regulator_register(&ri->desc, &config);
+		if (IS_ERR(rdev[id])) {
+			dev_err(&pdev->dev, "failed to register regulator %s\n",
+					ri->desc.name);
+			err = PTR_ERR(rdev[id]);
+			goto fail;
+		}
+
+		if (reg_data) {
+			err = tps6586x_regulator_set_slew_rate(pdev, id,
+					reg_data);
+			if (err < 0) {
+				dev_err(&pdev->dev,
+					"Slew rate config failed, e %d\n", err);
+				regulator_unregister(rdev[id]);
+				goto fail;
+			}
+		}
 	}
 
 	platform_set_drvdata(pdev, rdev);
+	return 0;
 
-	return tps6586x_regulator_set_slew_rate(pdev);
+fail:
+	while (--id >= 0)
+		regulator_unregister(rdev[id]);
+	return err;
 }
 
-static int __devexit tps6586x_regulator_remove(struct platform_device *pdev)
+static int tps6586x_regulator_remove(struct platform_device *pdev)
 {
-	struct regulator_dev *rdev = platform_get_drvdata(pdev);
+	struct regulator_dev **rdev = platform_get_drvdata(pdev);
+	int id = TPS6586X_ID_MAX_REGULATOR;
 
-	regulator_unregister(rdev);
+	while (--id >= 0)
+		regulator_unregister(rdev[id]);
+
 	return 0;
 }
 
 static struct platform_driver tps6586x_regulator_driver = {
 	.driver	= {
-		.name	= "tps6586x-regulator",
+		.name	= "tps6586x-pmic",
 		.owner	= THIS_MODULE,
 	},
 	.probe		= tps6586x_regulator_probe,
-	.remove		= __devexit_p(tps6586x_regulator_remove),
+	.remove		= tps6586x_regulator_remove,
 };
 
 static int __init tps6586x_regulator_init(void)
diff --git a/drivers/regulator/tps65910-regulator.c b/drivers/regulator/tps65910-regulator.c
index 793adda..59c3770 100644
--- a/drivers/regulator/tps65910-regulator.c
+++ b/drivers/regulator/tps65910-regulator.c
@@ -38,6 +38,11 @@
 
 /* VSEL tables for TPS65910 specific LDOs and dcdc's */
 
+/* supported VRTC voltages in microvolts */
+static const unsigned int VRTC_VSEL_table[] = {
+	1800000,
+};
+
 /* supported VDD3 voltages in microvolts */
 static const unsigned int VDD3_VSEL_table[] = {
 	5000000,
@@ -95,6 +100,8 @@
 	{
 		.name = "vrtc",
 		.vin_name = "vcc7",
+		.n_voltages = ARRAY_SIZE(VRTC_VSEL_table),
+		.voltage_table = VRTC_VSEL_table,
 		.enable_time_us = 2200,
 	},
 	{
@@ -1026,7 +1033,7 @@
 }
 #endif
 
-static __devinit int tps65910_probe(struct platform_device *pdev)
+static int tps65910_probe(struct platform_device *pdev)
 {
 	struct tps65910 *tps65910 = dev_get_drvdata(pdev->dev.parent);
 	struct regulator_config config = { };
@@ -1184,7 +1191,7 @@
 	return err;
 }
 
-static int __devexit tps65910_remove(struct platform_device *pdev)
+static int tps65910_remove(struct platform_device *pdev)
 {
 	struct tps65910_reg *pmic = platform_get_drvdata(pdev);
 	int i;
@@ -1231,7 +1238,7 @@
 		.owner = THIS_MODULE,
 	},
 	.probe = tps65910_probe,
-	.remove = __devexit_p(tps65910_remove),
+	.remove = tps65910_remove,
 	.shutdown = tps65910_shutdown,
 };
 
diff --git a/drivers/regulator/tps65912-regulator.c b/drivers/regulator/tps65912-regulator.c
index 18b2a1d..17e994e 100644
--- a/drivers/regulator/tps65912-regulator.c
+++ b/drivers/regulator/tps65912-regulator.c
@@ -459,7 +459,7 @@
 	.list_voltage = tps65912_list_voltage,
 };
 
-static __devinit int tps65912_probe(struct platform_device *pdev)
+static int tps65912_probe(struct platform_device *pdev)
 {
 	struct tps65912 *tps65912 = dev_get_drvdata(pdev->dev.parent);
 	struct regulator_config config = { };
@@ -525,7 +525,7 @@
 	return err;
 }
 
-static int __devexit tps65912_remove(struct platform_device *pdev)
+static int tps65912_remove(struct platform_device *pdev)
 {
 	struct tps65912_reg *tps65912_reg = platform_get_drvdata(pdev);
 	int i;
@@ -541,7 +541,7 @@
 		.owner = THIS_MODULE,
 	},
 	.probe = tps65912_probe,
-	.remove = __devexit_p(tps65912_remove),
+	.remove = tps65912_remove,
 };
 
 static int __init tps65912_init(void)
diff --git a/drivers/regulator/tps80031-regulator.c b/drivers/regulator/tps80031-regulator.c
new file mode 100644
index 0000000..b15d711
--- /dev/null
+++ b/drivers/regulator/tps80031-regulator.c
@@ -0,0 +1,788 @@
+/*
+ * tps80031-regulator.c -- TI TPS80031 regulator driver.
+ *
+ * Regulator driver for TI TPS80031/TPS80032 Fully Integrated Power
+ * Management with Power Path and Battery Charger.
+ *
+ * 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/delay.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/mfd/tps80031.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/machine.h>
+#include <linux/slab.h>
+
+/* Flags for DCDC Voltage reading */
+#define DCDC_OFFSET_EN		BIT(0)
+#define DCDC_EXTENDED_EN	BIT(1)
+#define TRACK_MODE_ENABLE	BIT(2)
+
+#define SMPS_MULTOFFSET_VIO	BIT(1)
+#define SMPS_MULTOFFSET_SMPS1	BIT(3)
+#define SMPS_MULTOFFSET_SMPS2	BIT(4)
+#define SMPS_MULTOFFSET_SMPS3	BIT(6)
+#define SMPS_MULTOFFSET_SMPS4	BIT(0)
+
+#define SMPS_CMD_MASK		0xC0
+#define SMPS_VSEL_MASK		0x3F
+#define LDO_VSEL_MASK		0x1F
+#define LDO_TRACK_VSEL_MASK	0x3F
+
+#define MISC2_LDOUSB_IN_VSYS	BIT(4)
+#define MISC2_LDOUSB_IN_PMID	BIT(3)
+#define MISC2_LDOUSB_IN_MASK	0x18
+
+#define MISC2_LDO3_SEL_VIB_VAL	BIT(0)
+#define MISC2_LDO3_SEL_VIB_MASK	0x1
+
+#define BOOST_HW_PWR_EN		BIT(5)
+#define BOOST_HW_PWR_EN_MASK	BIT(5)
+
+#define OPA_MODE_EN		BIT(6)
+#define OPA_MODE_EN_MASK	BIT(6)
+
+#define USB_VBUS_CTRL_SET	0x04
+#define USB_VBUS_CTRL_CLR	0x05
+#define VBUS_DISCHRG		0x20
+
+struct tps80031_regulator_info {
+	/* Regulator register address.*/
+	u8		trans_reg;
+	u8		state_reg;
+	u8		force_reg;
+	u8		volt_reg;
+	u8		volt_id;
+
+	/*Power request bits */
+	int		preq_bit;
+
+	/* used by regulator core */
+	struct regulator_desc	desc;
+
+};
+
+struct tps80031_regulator {
+	struct device			*dev;
+	struct regulator_dev		*rdev;
+	struct tps80031_regulator_info	*rinfo;
+
+	u8				device_flags;
+	unsigned int			config_flags;
+	unsigned int			ext_ctrl_flag;
+};
+
+static inline struct device *to_tps80031_dev(struct regulator_dev *rdev)
+{
+	return rdev_get_dev(rdev)->parent->parent;
+}
+
+static int tps80031_reg_is_enabled(struct regulator_dev *rdev)
+{
+	struct tps80031_regulator *ri = rdev_get_drvdata(rdev);
+	struct device *parent = to_tps80031_dev(rdev);
+	u8 reg_val;
+	int ret;
+
+	if (ri->ext_ctrl_flag & TPS80031_EXT_PWR_REQ)
+		return true;
+
+	ret = tps80031_read(parent, TPS80031_SLAVE_ID1, ri->rinfo->state_reg,
+				&reg_val);
+	if (ret < 0) {
+		dev_err(&rdev->dev, "Reg 0x%02x read failed, err = %d\n",
+			ri->rinfo->state_reg, ret);
+		return ret;
+	}
+	return ((reg_val & TPS80031_STATE_MASK) == TPS80031_STATE_ON);
+}
+
+static int tps80031_reg_enable(struct regulator_dev *rdev)
+{
+	struct tps80031_regulator *ri = rdev_get_drvdata(rdev);
+	struct device *parent = to_tps80031_dev(rdev);
+	int ret;
+
+	if (ri->ext_ctrl_flag & TPS80031_EXT_PWR_REQ)
+		return 0;
+
+	ret = tps80031_update(parent, TPS80031_SLAVE_ID1, ri->rinfo->state_reg,
+			TPS80031_STATE_ON, TPS80031_STATE_MASK);
+	if (ret < 0) {
+		dev_err(&rdev->dev, "Reg 0x%02x update failed, err = %d\n",
+			ri->rinfo->state_reg, ret);
+		return ret;
+	}
+	return ret;
+}
+
+static int tps80031_reg_disable(struct regulator_dev *rdev)
+{
+	struct tps80031_regulator *ri = rdev_get_drvdata(rdev);
+	struct device *parent = to_tps80031_dev(rdev);
+	int ret;
+
+	if (ri->ext_ctrl_flag & TPS80031_EXT_PWR_REQ)
+		return 0;
+
+	ret = tps80031_update(parent, TPS80031_SLAVE_ID1, ri->rinfo->state_reg,
+			TPS80031_STATE_OFF, TPS80031_STATE_MASK);
+	if (ret < 0)
+		dev_err(&rdev->dev, "Reg 0x%02x update failed, err = %d\n",
+			ri->rinfo->state_reg, ret);
+	return ret;
+}
+
+/* DCDC voltages for the selector of 58 to 63 */
+static int tps80031_dcdc_voltages[4][5] = {
+	{ 1350, 1500, 1800, 1900, 2100},
+	{ 1350, 1500, 1800, 1900, 2100},
+	{ 2084, 2315, 2778, 2932, 3241},
+	{ 4167, 2315, 2778, 2932, 3241},
+};
+
+static int tps80031_dcdc_list_voltage(struct regulator_dev *rdev, unsigned sel)
+{
+	struct tps80031_regulator *ri = rdev_get_drvdata(rdev);
+	int volt_index = ri->device_flags & 0x3;
+
+	if (sel == 0)
+		return 0;
+	else if (sel < 58)
+		return regulator_list_voltage_linear(rdev, sel - 1);
+	else
+		return tps80031_dcdc_voltages[volt_index][sel - 58] * 1000;
+}
+
+static int tps80031_dcdc_set_voltage_sel(struct regulator_dev *rdev,
+		unsigned vsel)
+{
+	struct tps80031_regulator *ri = rdev_get_drvdata(rdev);
+	struct device *parent = to_tps80031_dev(rdev);
+	int ret;
+	u8 reg_val;
+
+	if (ri->rinfo->force_reg) {
+		ret = tps80031_read(parent, ri->rinfo->volt_id,
+						ri->rinfo->force_reg, &reg_val);
+		if (ret < 0) {
+			dev_err(ri->dev, "reg 0x%02x read failed, e = %d\n",
+				ri->rinfo->force_reg, ret);
+			return ret;
+		}
+		if (!(reg_val & SMPS_CMD_MASK)) {
+			ret = tps80031_update(parent, ri->rinfo->volt_id,
+				ri->rinfo->force_reg, vsel, SMPS_VSEL_MASK);
+			if (ret < 0)
+				dev_err(ri->dev,
+					"reg 0x%02x update failed, e = %d\n",
+					ri->rinfo->force_reg, ret);
+			return ret;
+		}
+	}
+	ret = tps80031_update(parent, ri->rinfo->volt_id,
+			ri->rinfo->volt_reg, vsel, SMPS_VSEL_MASK);
+	if (ret < 0)
+		dev_err(ri->dev, "reg 0x%02x update failed, e = %d\n",
+			ri->rinfo->volt_reg, ret);
+	return ret;
+}
+
+static int tps80031_dcdc_get_voltage_sel(struct regulator_dev *rdev)
+{
+	struct tps80031_regulator *ri = rdev_get_drvdata(rdev);
+	struct device *parent = to_tps80031_dev(rdev);
+	uint8_t vsel = 0;
+	int ret;
+
+	if (ri->rinfo->force_reg) {
+		ret = tps80031_read(parent, ri->rinfo->volt_id,
+						ri->rinfo->force_reg, &vsel);
+		if (ret < 0) {
+			dev_err(ri->dev, "reg 0x%02x read failed, e = %d\n",
+					ri->rinfo->force_reg, ret);
+			return ret;
+		}
+
+		if (!(vsel & SMPS_CMD_MASK))
+			return vsel & SMPS_VSEL_MASK;
+	}
+	ret = tps80031_read(parent, ri->rinfo->volt_id,
+				ri->rinfo->volt_reg, &vsel);
+	if (ret < 0) {
+		dev_err(ri->dev, "reg 0x%02x read failed, e = %d\n",
+			ri->rinfo->volt_reg, ret);
+		return ret;
+	}
+	return vsel & SMPS_VSEL_MASK;
+}
+
+static int tps80031_ldo_set_voltage_sel(struct regulator_dev *rdev,
+		unsigned sel)
+{
+	struct tps80031_regulator *ri = rdev_get_drvdata(rdev);
+	struct device *parent = to_tps80031_dev(rdev);
+	int ret;
+
+	/* Check for valid setting for TPS80031 or TPS80032-ES1.0 */
+	if ((ri->rinfo->desc.id == TPS80031_REGULATOR_LDO2) &&
+			(ri->device_flags & TRACK_MODE_ENABLE)) {
+		unsigned nvsel = (sel) & 0x1F;
+		if (((tps80031_get_chip_info(parent) == TPS80031) ||
+			((tps80031_get_chip_info(parent) == TPS80032) &&
+			(tps80031_get_pmu_version(parent) == 0x0))) &&
+			((nvsel == 0x0) || (nvsel >= 0x19 && nvsel <= 0x1F))) {
+				dev_err(ri->dev,
+					"Invalid sel %d in track mode LDO2\n",
+					nvsel);
+				return -EINVAL;
+		}
+	}
+
+	ret = tps80031_write(parent, ri->rinfo->volt_id,
+			ri->rinfo->volt_reg, sel);
+	if (ret < 0)
+		dev_err(ri->dev, "Error in writing reg 0x%02x, e = %d\n",
+			ri->rinfo->volt_reg, ret);
+	return ret;
+}
+
+static int tps80031_ldo_get_voltage_sel(struct regulator_dev *rdev)
+{
+	struct tps80031_regulator *ri = rdev_get_drvdata(rdev);
+	struct device *parent = to_tps80031_dev(rdev);
+	uint8_t vsel;
+	int ret;
+
+	ret = tps80031_read(parent, ri->rinfo->volt_id,
+				ri->rinfo->volt_reg, &vsel);
+	if (ret < 0) {
+		dev_err(ri->dev, "Error in writing the Voltage register\n");
+		return ret;
+	}
+	return vsel & rdev->desc->vsel_mask;
+}
+
+static int tps80031_vbus_is_enabled(struct regulator_dev *rdev)
+{
+	struct tps80031_regulator *ri = rdev_get_drvdata(rdev);
+	struct device *parent = to_tps80031_dev(rdev);
+	int ret = -EIO;
+	uint8_t ctrl1 = 0;
+	uint8_t ctrl3 = 0;
+
+	ret = tps80031_read(parent, TPS80031_SLAVE_ID2,
+			TPS80031_CHARGERUSB_CTRL1, &ctrl1);
+	if (ret < 0) {
+		dev_err(ri->dev, "reg 0x%02x read failed, e = %d\n",
+			TPS80031_CHARGERUSB_CTRL1, ret);
+		return ret;
+	}
+	ret = tps80031_read(parent, TPS80031_SLAVE_ID2,
+				TPS80031_CHARGERUSB_CTRL3, &ctrl3);
+	if (ret < 0) {
+		dev_err(ri->dev, "reg 0x%02x read failed, e = %d\n",
+			TPS80031_CHARGERUSB_CTRL3, ret);
+		return ret;
+	}
+	if ((ctrl1 & OPA_MODE_EN) && (ctrl3 & BOOST_HW_PWR_EN))
+		return 1;
+	return ret;
+}
+
+static int tps80031_vbus_enable(struct regulator_dev *rdev)
+{
+	struct tps80031_regulator *ri = rdev_get_drvdata(rdev);
+	struct device *parent = to_tps80031_dev(rdev);
+	int ret;
+
+	ret = tps80031_set_bits(parent, TPS80031_SLAVE_ID2,
+				TPS80031_CHARGERUSB_CTRL1, OPA_MODE_EN);
+	if (ret < 0) {
+		dev_err(ri->dev, "reg 0x%02x read failed, e = %d\n",
+					TPS80031_CHARGERUSB_CTRL1, ret);
+		return ret;
+	}
+
+	ret = tps80031_set_bits(parent, TPS80031_SLAVE_ID2,
+				TPS80031_CHARGERUSB_CTRL3, BOOST_HW_PWR_EN);
+	if (ret < 0) {
+		dev_err(ri->dev, "reg 0x%02x read failed, e = %d\n",
+			TPS80031_CHARGERUSB_CTRL3, ret);
+		return ret;
+	}
+	return ret;
+}
+
+static int tps80031_vbus_disable(struct regulator_dev *rdev)
+{
+	struct tps80031_regulator *ri = rdev_get_drvdata(rdev);
+	struct device *parent = to_tps80031_dev(rdev);
+	int ret = 0;
+
+	if (ri->config_flags & TPS80031_VBUS_DISCHRG_EN_PDN) {
+		ret = tps80031_write(parent, TPS80031_SLAVE_ID2,
+			USB_VBUS_CTRL_SET, VBUS_DISCHRG);
+		if (ret < 0) {
+			dev_err(ri->dev, "reg 0x%02x write failed, e = %d\n",
+				USB_VBUS_CTRL_SET, ret);
+			return ret;
+		}
+	}
+
+	ret = tps80031_clr_bits(parent, TPS80031_SLAVE_ID2,
+			TPS80031_CHARGERUSB_CTRL1,  OPA_MODE_EN);
+	if (ret < 0) {
+		dev_err(ri->dev, "reg 0x%02x clearbit failed, e = %d\n",
+				TPS80031_CHARGERUSB_CTRL1, ret);
+		return ret;
+	}
+
+	ret = tps80031_clr_bits(parent, TPS80031_SLAVE_ID2,
+				TPS80031_CHARGERUSB_CTRL3, BOOST_HW_PWR_EN);
+	if (ret < 0) {
+		dev_err(ri->dev, "reg 0x%02x clearbit failed, e = %d\n",
+				TPS80031_CHARGERUSB_CTRL3, ret);
+		return ret;
+	}
+
+	mdelay(DIV_ROUND_UP(ri->rinfo->desc.enable_time, 1000));
+	if (ri->config_flags & TPS80031_VBUS_DISCHRG_EN_PDN) {
+		ret = tps80031_write(parent, TPS80031_SLAVE_ID2,
+			USB_VBUS_CTRL_CLR, VBUS_DISCHRG);
+		if (ret < 0) {
+			dev_err(ri->dev, "reg 0x%02x write failed, e = %d\n",
+					USB_VBUS_CTRL_CLR, ret);
+			return ret;
+		}
+	}
+	return ret;
+}
+
+static struct regulator_ops tps80031_dcdc_ops = {
+	.list_voltage		= tps80031_dcdc_list_voltage,
+	.set_voltage_sel	= tps80031_dcdc_set_voltage_sel,
+	.get_voltage_sel	= tps80031_dcdc_get_voltage_sel,
+	.enable		= tps80031_reg_enable,
+	.disable	= tps80031_reg_disable,
+	.is_enabled	= tps80031_reg_is_enabled,
+};
+
+static struct regulator_ops tps80031_ldo_ops = {
+	.list_voltage		= regulator_list_voltage_linear,
+	.set_voltage_sel	= tps80031_ldo_set_voltage_sel,
+	.get_voltage_sel	= tps80031_ldo_get_voltage_sel,
+	.enable			= tps80031_reg_enable,
+	.disable		= tps80031_reg_disable,
+	.is_enabled		= tps80031_reg_is_enabled,
+};
+
+static struct regulator_ops tps80031_vbus_sw_ops = {
+	.list_voltage	= regulator_list_voltage_linear,
+	.enable		= tps80031_vbus_enable,
+	.disable	= tps80031_vbus_disable,
+	.is_enabled	= tps80031_vbus_is_enabled,
+};
+
+static struct regulator_ops tps80031_vbus_hw_ops = {
+	.list_voltage	= regulator_list_voltage_linear,
+};
+
+static struct regulator_ops tps80031_ext_reg_ops = {
+	.list_voltage	= regulator_list_voltage_linear,
+	.enable		= tps80031_reg_enable,
+	.disable	= tps80031_reg_disable,
+	.is_enabled	= tps80031_reg_is_enabled,
+};
+
+/* Non-exiting default definition for some register */
+#define TPS80031_SMPS3_CFG_FORCE	0
+#define TPS80031_SMPS4_CFG_FORCE	0
+
+#define TPS80031_VBUS_CFG_TRANS		0
+#define TPS80031_VBUS_CFG_STATE		0
+
+#define TPS80031_REG_SMPS(_id, _volt_id, _pbit)	\
+{								\
+	.trans_reg = TPS80031_##_id##_CFG_TRANS,		\
+	.state_reg = TPS80031_##_id##_CFG_STATE,		\
+	.force_reg = TPS80031_##_id##_CFG_FORCE,		\
+	.volt_reg = TPS80031_##_id##_CFG_VOLTAGE,		\
+	.volt_id = TPS80031_SLAVE_##_volt_id,			\
+	.preq_bit = _pbit,					\
+	.desc = {						\
+		.name = "tps80031_"#_id,			\
+		.id = TPS80031_REGULATOR_##_id,			\
+		.n_voltages = 63,				\
+		.ops = &tps80031_dcdc_ops,			\
+		.type = REGULATOR_VOLTAGE,			\
+		.owner = THIS_MODULE,				\
+		.enable_time = 500,				\
+	},							\
+}
+
+#define TPS80031_REG_LDO(_id, _preq_bit)			\
+{								\
+	.trans_reg = TPS80031_##_id##_CFG_TRANS,		\
+	.state_reg = TPS80031_##_id##_CFG_STATE,		\
+	.volt_reg = TPS80031_##_id##_CFG_VOLTAGE,		\
+	.volt_id = TPS80031_SLAVE_ID1,				\
+	.preq_bit = _preq_bit,					\
+	.desc = {						\
+		.owner = THIS_MODULE,				\
+		.name = "tps80031_"#_id,			\
+		.id = TPS80031_REGULATOR_##_id,			\
+		.ops = &tps80031_ldo_ops,			\
+		.type = REGULATOR_VOLTAGE,			\
+		.min_uV = 1000000,				\
+		.uV_step = 100000,				\
+		.linear_min_sel = 1,				\
+		.n_voltages = 25,				\
+		.vsel_mask = LDO_VSEL_MASK,			\
+		.enable_time = 500,				\
+	},							\
+}
+
+#define TPS80031_REG_FIXED(_id, max_mV, _ops, _delay, _pbit)	\
+{								\
+	.trans_reg = TPS80031_##_id##_CFG_TRANS,		\
+	.state_reg = TPS80031_##_id##_CFG_STATE,		\
+	.volt_id = TPS80031_SLAVE_ID1,				\
+	.preq_bit = _pbit,					\
+	.desc = {						\
+		.name = "tps80031_"#_id,			\
+		.id = TPS80031_REGULATOR_##_id,			\
+		.min_uV = max_mV * 1000,			\
+		.n_voltages = 1,				\
+		.ops = &_ops,					\
+		.type = REGULATOR_VOLTAGE,			\
+		.owner = THIS_MODULE,				\
+		.enable_time = _delay,				\
+	},							\
+}
+
+static struct tps80031_regulator_info tps80031_rinfo[TPS80031_REGULATOR_MAX] = {
+	TPS80031_REG_SMPS(VIO,   ID0, 4),
+	TPS80031_REG_SMPS(SMPS1, ID0, 0),
+	TPS80031_REG_SMPS(SMPS2, ID0, 1),
+	TPS80031_REG_SMPS(SMPS3, ID1, 2),
+	TPS80031_REG_SMPS(SMPS4, ID1, 3),
+	TPS80031_REG_LDO(VANA,   -1),
+	TPS80031_REG_LDO(LDO1,   8),
+	TPS80031_REG_LDO(LDO2,   9),
+	TPS80031_REG_LDO(LDO3,   10),
+	TPS80031_REG_LDO(LDO4,   11),
+	TPS80031_REG_LDO(LDO5,   12),
+	TPS80031_REG_LDO(LDO6,   13),
+	TPS80031_REG_LDO(LDO7,   14),
+	TPS80031_REG_LDO(LDOLN,  15),
+	TPS80031_REG_LDO(LDOUSB, 5),
+	TPS80031_REG_FIXED(VBUS,   5000, tps80031_vbus_hw_ops, 100000, -1),
+	TPS80031_REG_FIXED(REGEN1, 3300, tps80031_ext_reg_ops, 0, 16),
+	TPS80031_REG_FIXED(REGEN2, 3300, tps80031_ext_reg_ops, 0, 17),
+	TPS80031_REG_FIXED(SYSEN,  3300, tps80031_ext_reg_ops, 0, 18),
+};
+
+static int tps80031_power_req_config(struct device *parent,
+		struct tps80031_regulator *ri,
+		struct tps80031_regulator_platform_data *tps80031_pdata)
+{
+	int ret = 0;
+
+	if (ri->rinfo->preq_bit < 0)
+		goto skip_pwr_req_config;
+
+	ret = tps80031_ext_power_req_config(parent, ri->ext_ctrl_flag,
+			ri->rinfo->preq_bit, ri->rinfo->state_reg,
+			ri->rinfo->trans_reg);
+	if (ret < 0) {
+		dev_err(ri->dev, "ext powerreq config failed, err = %d\n", ret);
+		return ret;
+	}
+
+skip_pwr_req_config:
+	if (tps80031_pdata->ext_ctrl_flag & TPS80031_PWR_ON_ON_SLEEP) {
+		ret = tps80031_update(parent, TPS80031_SLAVE_ID1,
+				ri->rinfo->trans_reg, TPS80031_TRANS_SLEEP_ON,
+				TPS80031_TRANS_SLEEP_MASK);
+		if (ret < 0) {
+			dev_err(ri->dev, "Reg 0x%02x update failed, e %d\n",
+					ri->rinfo->trans_reg, ret);
+			return ret;
+		}
+	}
+	return ret;
+}
+
+static int tps80031_regulator_config(struct device *parent,
+		struct tps80031_regulator *ri,
+		struct tps80031_regulator_platform_data *tps80031_pdata)
+{
+	int ret = 0;
+
+	switch (ri->rinfo->desc.id) {
+	case TPS80031_REGULATOR_LDOUSB:
+		if (ri->config_flags & (TPS80031_USBLDO_INPUT_VSYS |
+			TPS80031_USBLDO_INPUT_PMID)) {
+			unsigned val = 0;
+			if (ri->config_flags & TPS80031_USBLDO_INPUT_VSYS)
+				val = MISC2_LDOUSB_IN_VSYS;
+			else
+				val = MISC2_LDOUSB_IN_PMID;
+
+			ret = tps80031_update(parent, TPS80031_SLAVE_ID1,
+				TPS80031_MISC2, val,
+				MISC2_LDOUSB_IN_MASK);
+			if (ret < 0) {
+				dev_err(ri->dev,
+					"LDOUSB config failed, e= %d\n", ret);
+				return ret;
+			}
+		}
+		break;
+
+	case TPS80031_REGULATOR_LDO3:
+		if (ri->config_flags & TPS80031_LDO3_OUTPUT_VIB) {
+			ret = tps80031_update(parent, TPS80031_SLAVE_ID1,
+				TPS80031_MISC2, MISC2_LDO3_SEL_VIB_VAL,
+				MISC2_LDO3_SEL_VIB_MASK);
+			if (ret < 0) {
+				dev_err(ri->dev,
+					"LDO3 config failed, e = %d\n", ret);
+				return ret;
+			}
+		}
+		break;
+
+	case TPS80031_REGULATOR_VBUS:
+		/* Provide SW control Ops if VBUS is SW control */
+		if (!(ri->config_flags & TPS80031_VBUS_SW_ONLY))
+			ri->rinfo->desc.ops = &tps80031_vbus_sw_ops;
+		break;
+	default:
+		break;
+	}
+
+	/* Configure Active state to ON, SLEEP to OFF and OFF_state to OFF */
+	ret = tps80031_update(parent, TPS80031_SLAVE_ID1, ri->rinfo->trans_reg,
+		TPS80031_TRANS_ACTIVE_ON | TPS80031_TRANS_SLEEP_OFF |
+		TPS80031_TRANS_OFF_OFF, TPS80031_TRANS_ACTIVE_MASK |
+		TPS80031_TRANS_SLEEP_MASK | TPS80031_TRANS_OFF_MASK);
+	if (ret < 0) {
+		dev_err(ri->dev, "trans reg update failed, e %d\n", ret);
+		return ret;
+	}
+
+	return ret;
+}
+
+static int check_smps_mode_mult(struct device *parent,
+	struct tps80031_regulator *ri)
+{
+	int mult_offset;
+	int ret;
+	u8 smps_offset;
+	u8 smps_mult;
+
+	ret = tps80031_read(parent, TPS80031_SLAVE_ID1,
+			TPS80031_SMPS_OFFSET, &smps_offset);
+	if (ret < 0) {
+		dev_err(parent, "Error in reading smps offset register\n");
+		return ret;
+	}
+
+	ret = tps80031_read(parent, TPS80031_SLAVE_ID1,
+			TPS80031_SMPS_MULT, &smps_mult);
+	if (ret < 0) {
+		dev_err(parent, "Error in reading smps mult register\n");
+		return ret;
+	}
+
+	switch (ri->rinfo->desc.id) {
+	case TPS80031_REGULATOR_VIO:
+		mult_offset = SMPS_MULTOFFSET_VIO;
+		break;
+	case TPS80031_REGULATOR_SMPS1:
+		mult_offset = SMPS_MULTOFFSET_SMPS1;
+		break;
+	case TPS80031_REGULATOR_SMPS2:
+		mult_offset = SMPS_MULTOFFSET_SMPS2;
+		break;
+	case TPS80031_REGULATOR_SMPS3:
+		mult_offset = SMPS_MULTOFFSET_SMPS3;
+		break;
+	case TPS80031_REGULATOR_SMPS4:
+		mult_offset = SMPS_MULTOFFSET_SMPS4;
+		break;
+	case TPS80031_REGULATOR_LDO2:
+		ri->device_flags = smps_mult & BIT(5) ? TRACK_MODE_ENABLE : 0;
+		/* TRACK mode the ldo2 varies from 600mV to 1300mV */
+		if (ri->device_flags & TRACK_MODE_ENABLE) {
+			ri->rinfo->desc.min_uV = 600000;
+			ri->rinfo->desc.uV_step = 12500;
+			ri->rinfo->desc.n_voltages = 57;
+			ri->rinfo->desc.vsel_mask = LDO_TRACK_VSEL_MASK;
+		}
+		return 0;
+	default:
+		return 0;
+	}
+
+	ri->device_flags = (smps_offset & mult_offset) ? DCDC_OFFSET_EN : 0;
+	ri->device_flags |= (smps_mult & mult_offset) ? DCDC_EXTENDED_EN : 0;
+	switch (ri->device_flags) {
+	case 0:
+		ri->rinfo->desc.min_uV = 607700;
+		ri->rinfo->desc.uV_step = 12660;
+		break;
+	case DCDC_OFFSET_EN:
+		ri->rinfo->desc.min_uV = 700000;
+		ri->rinfo->desc.uV_step = 12500;
+		break;
+	case DCDC_EXTENDED_EN:
+		ri->rinfo->desc.min_uV = 1852000;
+		ri->rinfo->desc.uV_step = 38600;
+		break;
+	case DCDC_OFFSET_EN | DCDC_EXTENDED_EN:
+		ri->rinfo->desc.min_uV = 2161000;
+		ri->rinfo->desc.uV_step = 38600;
+		break;
+	}
+	return 0;
+}
+
+static int tps80031_regulator_probe(struct platform_device *pdev)
+{
+	struct tps80031_platform_data *pdata;
+	struct tps80031_regulator_platform_data *tps_pdata;
+	struct tps80031_regulator *ri;
+	struct tps80031_regulator *pmic;
+	struct regulator_dev *rdev;
+	struct regulator_config config = { };
+	int ret;
+	int num;
+
+	pdata = dev_get_platdata(pdev->dev.parent);
+
+	if (!pdata) {
+		dev_err(&pdev->dev, "No platform data\n");
+		return -EINVAL;
+	}
+
+	pmic = devm_kzalloc(&pdev->dev,
+			TPS80031_REGULATOR_MAX * sizeof(*pmic), GFP_KERNEL);
+	if (!pmic) {
+		dev_err(&pdev->dev, "mem alloc for pmic failed\n");
+		return -ENOMEM;
+	}
+
+	for (num = 0; num < TPS80031_REGULATOR_MAX; ++num) {
+		tps_pdata = pdata->regulator_pdata[num];
+		ri = &pmic[num];
+		ri->rinfo = &tps80031_rinfo[num];
+		ri->dev = &pdev->dev;
+
+		check_smps_mode_mult(pdev->dev.parent, ri);
+		config.dev = &pdev->dev;
+		config.init_data = NULL;
+		config.driver_data = ri;
+		if (tps_pdata) {
+			config.init_data = tps_pdata->reg_init_data;
+			ri->config_flags = tps_pdata->config_flags;
+			ri->ext_ctrl_flag = tps_pdata->ext_ctrl_flag;
+			ret = tps80031_regulator_config(pdev->dev.parent,
+					ri, tps_pdata);
+			if (ret < 0) {
+				dev_err(&pdev->dev,
+					"regulator config failed, e %d\n", ret);
+				goto fail;
+			}
+
+			ret = tps80031_power_req_config(pdev->dev.parent,
+					ri, tps_pdata);
+			if (ret < 0) {
+				dev_err(&pdev->dev,
+					"pwr_req config failed, err %d\n", ret);
+				goto fail;
+			}
+		}
+		rdev = regulator_register(&ri->rinfo->desc, &config);
+		if (IS_ERR_OR_NULL(rdev)) {
+			dev_err(&pdev->dev,
+				"register regulator failed %s\n",
+					ri->rinfo->desc.name);
+			ret = PTR_ERR(rdev);
+			goto fail;
+		}
+		ri->rdev = rdev;
+	}
+
+	platform_set_drvdata(pdev, pmic);
+	return 0;
+fail:
+	while (--num >= 0) {
+		ri = &pmic[num];
+		regulator_unregister(ri->rdev);
+	}
+	return ret;
+}
+
+static int tps80031_regulator_remove(struct platform_device *pdev)
+{
+	struct tps80031_regulator *pmic = platform_get_drvdata(pdev);
+	struct tps80031_regulator *ri = NULL;
+	int num;
+
+	for (num = 0; num < TPS80031_REGULATOR_MAX; ++num) {
+		ri = &pmic[num];
+		regulator_unregister(ri->rdev);
+	}
+	return 0;
+}
+
+static struct platform_driver tps80031_regulator_driver = {
+	.driver	= {
+		.name	= "tps80031-pmic",
+		.owner	= THIS_MODULE,
+	},
+	.probe		= tps80031_regulator_probe,
+	.remove		= tps80031_regulator_remove,
+};
+
+static int __init tps80031_regulator_init(void)
+{
+	return platform_driver_register(&tps80031_regulator_driver);
+}
+subsys_initcall(tps80031_regulator_init);
+
+static void __exit tps80031_regulator_exit(void)
+{
+	platform_driver_unregister(&tps80031_regulator_driver);
+}
+module_exit(tps80031_regulator_exit);
+
+MODULE_ALIAS("platform:tps80031-regulator");
+MODULE_DESCRIPTION("Regulator Driver for TI TPS80031/TPS80032 PMIC");
+MODULE_AUTHOR("Laxman Dewangan <ldewangan@nvidia.com>");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/regulator/twl-regulator.c b/drivers/regulator/twl-regulator.c
index 7eb986a..493c8c6 100644
--- a/drivers/regulator/twl-regulator.c
+++ b/drivers/regulator/twl-regulator.c
@@ -1116,7 +1116,7 @@
 };
 MODULE_DEVICE_TABLE(of, twl_of_match);
 
-static int __devinit twlreg_probe(struct platform_device *pdev)
+static int twlreg_probe(struct platform_device *pdev)
 {
 	int				i, id;
 	struct twlreg_info		*info;
@@ -1241,7 +1241,7 @@
 	return 0;
 }
 
-static int __devexit twlreg_remove(struct platform_device *pdev)
+static int twlreg_remove(struct platform_device *pdev)
 {
 	struct regulator_dev *rdev = platform_get_drvdata(pdev);
 	struct twlreg_info *info = rdev->reg_data;
@@ -1255,7 +1255,7 @@
 
 static struct platform_driver twlreg_driver = {
 	.probe		= twlreg_probe,
-	.remove		= __devexit_p(twlreg_remove),
+	.remove		= twlreg_remove,
 	/* NOTE: short name, to work around driver model truncation of
 	 * "twl_regulator.12" (and friends) to "twl_regulator.1".
 	 */
diff --git a/drivers/regulator/vexpress.c b/drivers/regulator/vexpress.c
new file mode 100644
index 0000000..4668c7f
--- /dev/null
+++ b/drivers/regulator/vexpress.c
@@ -0,0 +1,147 @@
+/*
+ * 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.
+ *
+ * Copyright (C) 2012 ARM Limited
+ */
+
+#define DRVNAME "vexpress-regulator"
+#define pr_fmt(fmt) DRVNAME ": " fmt
+
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/of_regulator.h>
+#include <linux/vexpress.h>
+
+struct vexpress_regulator {
+	struct regulator_desc desc;
+	struct regulator_dev *regdev;
+	struct vexpress_config_func *func;
+};
+
+static int vexpress_regulator_get_voltage(struct regulator_dev *regdev)
+{
+	struct vexpress_regulator *reg = rdev_get_drvdata(regdev);
+	u32 uV;
+	int err = vexpress_config_read(reg->func, 0, &uV);
+
+	return err ? err : uV;
+}
+
+static int vexpress_regulator_set_voltage(struct regulator_dev *regdev,
+		int min_uV, int max_uV, unsigned *selector)
+{
+	struct vexpress_regulator *reg = rdev_get_drvdata(regdev);
+
+	return vexpress_config_write(reg->func, 0, min_uV);
+}
+
+static struct regulator_ops vexpress_regulator_ops_ro = {
+	.get_voltage = vexpress_regulator_get_voltage,
+};
+
+static struct regulator_ops vexpress_regulator_ops = {
+	.get_voltage = vexpress_regulator_get_voltage,
+	.set_voltage = vexpress_regulator_set_voltage,
+};
+
+static int vexpress_regulator_probe(struct platform_device *pdev)
+{
+	int err;
+	struct vexpress_regulator *reg;
+	struct regulator_init_data *init_data;
+	struct regulator_config config = { };
+
+	reg = devm_kzalloc(&pdev->dev, sizeof(*reg), GFP_KERNEL);
+	if (!reg) {
+		err = -ENOMEM;
+		goto error_kzalloc;
+	}
+
+	reg->func = vexpress_config_func_get_by_dev(&pdev->dev);
+	if (!reg->func) {
+		err = -ENXIO;
+		goto error_get_func;
+	}
+
+	reg->desc.name = dev_name(&pdev->dev);
+	reg->desc.type = REGULATOR_VOLTAGE;
+	reg->desc.owner = THIS_MODULE;
+	reg->desc.continuous_voltage_range = true;
+
+	init_data = of_get_regulator_init_data(&pdev->dev, pdev->dev.of_node);
+	if (!init_data) {
+		err = -EINVAL;
+		goto error_get_regulator_init_data;
+	}
+
+	init_data->constraints.apply_uV = 0;
+	if (init_data->constraints.min_uV && init_data->constraints.max_uV)
+		reg->desc.ops = &vexpress_regulator_ops;
+	else
+		reg->desc.ops = &vexpress_regulator_ops_ro;
+
+	config.dev = &pdev->dev;
+	config.init_data = init_data;
+	config.driver_data = reg;
+	config.of_node = pdev->dev.of_node;
+
+	reg->regdev = regulator_register(&reg->desc, &config);
+	if (IS_ERR(reg->regdev)) {
+		err = PTR_ERR(reg->regdev);
+		goto error_regulator_register;
+	}
+
+	platform_set_drvdata(pdev, reg);
+
+	return 0;
+
+error_regulator_register:
+error_get_regulator_init_data:
+	vexpress_config_func_put(reg->func);
+error_get_func:
+error_kzalloc:
+	return err;
+}
+
+static int vexpress_regulator_remove(struct platform_device *pdev)
+{
+	struct vexpress_regulator *reg = platform_get_drvdata(pdev);
+
+	vexpress_config_func_put(reg->func);
+	regulator_unregister(reg->regdev);
+
+	return 0;
+}
+
+static struct of_device_id vexpress_regulator_of_match[] = {
+	{ .compatible = "arm,vexpress-volt", },
+	{ }
+};
+
+static struct platform_driver vexpress_regulator_driver = {
+	.probe = vexpress_regulator_probe,
+	.remove = vexpress_regulator_remove,
+	.driver	= {
+		.name = DRVNAME,
+		.owner = THIS_MODULE,
+		.of_match_table = vexpress_regulator_of_match,
+	},
+};
+
+module_platform_driver(vexpress_regulator_driver);
+
+MODULE_AUTHOR("Pawel Moll <pawel.moll@arm.com>");
+MODULE_DESCRIPTION("Versatile Express regulator");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:vexpress-regulator");
diff --git a/drivers/regulator/virtual.c b/drivers/regulator/virtual.c
index c038e74..01c66e9 100644
--- a/drivers/regulator/virtual.c
+++ b/drivers/regulator/virtual.c
@@ -285,7 +285,7 @@
 	.attrs	= regulator_virtual_attributes,
 };
 
-static int __devinit regulator_virtual_probe(struct platform_device *pdev)
+static int regulator_virtual_probe(struct platform_device *pdev)
 {
 	char *reg_id = pdev->dev.platform_data;
 	struct virtual_consumer_data *drvdata;
@@ -321,7 +321,7 @@
 	return 0;
 }
 
-static int __devexit regulator_virtual_remove(struct platform_device *pdev)
+static int regulator_virtual_remove(struct platform_device *pdev)
 {
 	struct virtual_consumer_data *drvdata = platform_get_drvdata(pdev);
 
@@ -337,7 +337,7 @@
 
 static struct platform_driver regulator_virtual_consumer_driver = {
 	.probe		= regulator_virtual_probe,
-	.remove		= __devexit_p(regulator_virtual_remove),
+	.remove		= regulator_virtual_remove,
 	.driver		= {
 		.name		= "reg-virt-consumer",
 		.owner		= THIS_MODULE,
diff --git a/drivers/regulator/wm831x-dcdc.c b/drivers/regulator/wm831x-dcdc.c
index 782c228..0af6898 100644
--- a/drivers/regulator/wm831x-dcdc.c
+++ b/drivers/regulator/wm831x-dcdc.c
@@ -223,7 +223,7 @@
 	if (min_uV < 600000)
 		vsel = 0;
 	else if (min_uV <= 1800000)
-		vsel = ((min_uV - 600000) / 12500) + 8;
+		vsel = DIV_ROUND_UP(min_uV - 600000, 12500) + 8;
 	else
 		return -EINVAL;
 
@@ -290,7 +290,7 @@
 	if (vsel > dcdc->dvs_vsel) {
 		ret = wm831x_set_bits(wm831x, dvs_reg,
 				      WM831X_DC1_DVS_VSEL_MASK,
-				      dcdc->dvs_vsel);
+				      vsel);
 		if (ret == 0)
 			dcdc->dvs_vsel = vsel;
 		else
@@ -387,7 +387,7 @@
  * Set up DVS control.  We just log errors since we can still run
  * (with reduced performance) if we fail.
  */
-static __devinit void wm831x_buckv_dvs_init(struct wm831x_dcdc *dcdc,
+static void wm831x_buckv_dvs_init(struct wm831x_dcdc *dcdc,
 					    struct wm831x_buckv_pdata *pdata)
 {
 	struct wm831x *wm831x = dcdc->wm831x;
@@ -448,7 +448,7 @@
 	}
 }
 
-static __devinit int wm831x_buckv_probe(struct platform_device *pdev)
+static int wm831x_buckv_probe(struct platform_device *pdev)
 {
 	struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent);
 	struct wm831x_pdata *pdata = wm831x->dev->platform_data;
@@ -562,7 +562,7 @@
 	return ret;
 }
 
-static __devexit int wm831x_buckv_remove(struct platform_device *pdev)
+static int wm831x_buckv_remove(struct platform_device *pdev)
 {
 	struct wm831x_dcdc *dcdc = platform_get_drvdata(pdev);
 	struct wm831x *wm831x = dcdc->wm831x;
@@ -582,7 +582,7 @@
 
 static struct platform_driver wm831x_buckv_driver = {
 	.probe = wm831x_buckv_probe,
-	.remove = __devexit_p(wm831x_buckv_remove),
+	.remove = wm831x_buckv_remove,
 	.driver		= {
 		.name	= "wm831x-buckv",
 		.owner	= THIS_MODULE,
@@ -623,7 +623,7 @@
 	.set_suspend_mode = wm831x_dcdc_set_suspend_mode,
 };
 
-static __devinit int wm831x_buckp_probe(struct platform_device *pdev)
+static int wm831x_buckp_probe(struct platform_device *pdev)
 {
 	struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent);
 	struct wm831x_pdata *pdata = wm831x->dev->platform_data;
@@ -710,7 +710,7 @@
 	return ret;
 }
 
-static __devexit int wm831x_buckp_remove(struct platform_device *pdev)
+static int wm831x_buckp_remove(struct platform_device *pdev)
 {
 	struct wm831x_dcdc *dcdc = platform_get_drvdata(pdev);
 
@@ -725,7 +725,7 @@
 
 static struct platform_driver wm831x_buckp_driver = {
 	.probe = wm831x_buckp_probe,
-	.remove = __devexit_p(wm831x_buckp_remove),
+	.remove = wm831x_buckp_remove,
 	.driver		= {
 		.name	= "wm831x-buckp",
 		.owner	= THIS_MODULE,
@@ -771,7 +771,7 @@
 	.disable = regulator_disable_regmap,
 };
 
-static __devinit int wm831x_boostp_probe(struct platform_device *pdev)
+static int wm831x_boostp_probe(struct platform_device *pdev)
 {
 	struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent);
 	struct wm831x_pdata *pdata = wm831x->dev->platform_data;
@@ -845,7 +845,7 @@
 	return ret;
 }
 
-static __devexit int wm831x_boostp_remove(struct platform_device *pdev)
+static int wm831x_boostp_remove(struct platform_device *pdev)
 {
 	struct wm831x_dcdc *dcdc = platform_get_drvdata(pdev);
 
@@ -860,7 +860,7 @@
 
 static struct platform_driver wm831x_boostp_driver = {
 	.probe = wm831x_boostp_probe,
-	.remove = __devexit_p(wm831x_boostp_remove),
+	.remove = wm831x_boostp_remove,
 	.driver		= {
 		.name	= "wm831x-boostp",
 		.owner	= THIS_MODULE,
@@ -883,7 +883,7 @@
 	.get_status = wm831x_dcdc_get_status,
 };
 
-static __devinit int wm831x_epe_probe(struct platform_device *pdev)
+static int wm831x_epe_probe(struct platform_device *pdev)
 {
 	struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent);
 	struct wm831x_pdata *pdata = wm831x->dev->platform_data;
@@ -936,7 +936,7 @@
 	return ret;
 }
 
-static __devexit int wm831x_epe_remove(struct platform_device *pdev)
+static int wm831x_epe_remove(struct platform_device *pdev)
 {
 	struct wm831x_dcdc *dcdc = platform_get_drvdata(pdev);
 
@@ -948,7 +948,7 @@
 
 static struct platform_driver wm831x_epe_driver = {
 	.probe = wm831x_epe_probe,
-	.remove = __devexit_p(wm831x_epe_remove),
+	.remove = wm831x_epe_remove,
 	.driver		= {
 		.name	= "wm831x-epe",
 		.owner	= THIS_MODULE,
@@ -993,4 +993,5 @@
 MODULE_LICENSE("GPL");
 MODULE_ALIAS("platform:wm831x-buckv");
 MODULE_ALIAS("platform:wm831x-buckp");
+MODULE_ALIAS("platform:wm831x-boostp");
 MODULE_ALIAS("platform:wm831x-epe");
diff --git a/drivers/regulator/wm831x-isink.c b/drivers/regulator/wm831x-isink.c
index 2646a19..68586ee 100644
--- a/drivers/regulator/wm831x-isink.c
+++ b/drivers/regulator/wm831x-isink.c
@@ -148,7 +148,7 @@
 }
 
 
-static __devinit int wm831x_isink_probe(struct platform_device *pdev)
+static int wm831x_isink_probe(struct platform_device *pdev)
 {
 	struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent);
 	struct wm831x_pdata *pdata = wm831x->dev->platform_data;
@@ -221,7 +221,7 @@
 	return ret;
 }
 
-static __devexit int wm831x_isink_remove(struct platform_device *pdev)
+static int wm831x_isink_remove(struct platform_device *pdev)
 {
 	struct wm831x_isink *isink = platform_get_drvdata(pdev);
 
@@ -236,7 +236,7 @@
 
 static struct platform_driver wm831x_isink_driver = {
 	.probe = wm831x_isink_probe,
-	.remove = __devexit_p(wm831x_isink_remove),
+	.remove = wm831x_isink_remove,
 	.driver		= {
 		.name	= "wm831x-isink",
 		.owner	= THIS_MODULE,
diff --git a/drivers/regulator/wm831x-ldo.c b/drivers/regulator/wm831x-ldo.c
index c2dc039..1ec379a 100644
--- a/drivers/regulator/wm831x-ldo.c
+++ b/drivers/regulator/wm831x-ldo.c
@@ -247,7 +247,7 @@
 	.disable = regulator_disable_regmap,
 };
 
-static __devinit int wm831x_gp_ldo_probe(struct platform_device *pdev)
+static int wm831x_gp_ldo_probe(struct platform_device *pdev)
 {
 	struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent);
 	struct wm831x_pdata *pdata = wm831x->dev->platform_data;
@@ -334,7 +334,7 @@
 	return ret;
 }
 
-static __devexit int wm831x_gp_ldo_remove(struct platform_device *pdev)
+static int wm831x_gp_ldo_remove(struct platform_device *pdev)
 {
 	struct wm831x_ldo *ldo = platform_get_drvdata(pdev);
 
@@ -349,7 +349,7 @@
 
 static struct platform_driver wm831x_gp_ldo_driver = {
 	.probe = wm831x_gp_ldo_probe,
-	.remove = __devexit_p(wm831x_gp_ldo_remove),
+	.remove = wm831x_gp_ldo_remove,
 	.driver		= {
 		.name	= "wm831x-ldo",
 		.owner	= THIS_MODULE,
@@ -504,7 +504,7 @@
 	.disable = regulator_disable_regmap,
 };
 
-static __devinit int wm831x_aldo_probe(struct platform_device *pdev)
+static int wm831x_aldo_probe(struct platform_device *pdev)
 {
 	struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent);
 	struct wm831x_pdata *pdata = wm831x->dev->platform_data;
@@ -590,7 +590,7 @@
 	return ret;
 }
 
-static __devexit int wm831x_aldo_remove(struct platform_device *pdev)
+static int wm831x_aldo_remove(struct platform_device *pdev)
 {
 	struct wm831x_ldo *ldo = platform_get_drvdata(pdev);
 
@@ -603,7 +603,7 @@
 
 static struct platform_driver wm831x_aldo_driver = {
 	.probe = wm831x_aldo_probe,
-	.remove = __devexit_p(wm831x_aldo_remove),
+	.remove = wm831x_aldo_remove,
 	.driver		= {
 		.name	= "wm831x-aldo",
 		.owner	= THIS_MODULE,
@@ -660,7 +660,7 @@
 	.disable = regulator_disable_regmap,
 };
 
-static __devinit int wm831x_alive_ldo_probe(struct platform_device *pdev)
+static int wm831x_alive_ldo_probe(struct platform_device *pdev)
 {
 	struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent);
 	struct wm831x_pdata *pdata = wm831x->dev->platform_data;
@@ -737,7 +737,7 @@
 	return ret;
 }
 
-static __devexit int wm831x_alive_ldo_remove(struct platform_device *pdev)
+static int wm831x_alive_ldo_remove(struct platform_device *pdev)
 {
 	struct wm831x_ldo *ldo = platform_get_drvdata(pdev);
 
@@ -748,7 +748,7 @@
 
 static struct platform_driver wm831x_alive_ldo_driver = {
 	.probe = wm831x_alive_ldo_probe,
-	.remove = __devexit_p(wm831x_alive_ldo_remove),
+	.remove = wm831x_alive_ldo_remove,
 	.driver		= {
 		.name	= "wm831x-alive-ldo",
 		.owner	= THIS_MODULE,
diff --git a/drivers/regulator/wm8400-regulator.c b/drivers/regulator/wm8400-regulator.c
index 27c746e..c6a32ea 100644
--- a/drivers/regulator/wm8400-regulator.c
+++ b/drivers/regulator/wm8400-regulator.c
@@ -226,7 +226,7 @@
 	},
 };
 
-static int __devinit wm8400_regulator_probe(struct platform_device *pdev)
+static int wm8400_regulator_probe(struct platform_device *pdev)
 {
 	struct wm8400 *wm8400 = container_of(pdev, struct wm8400, regulators[pdev->id]);
 	struct regulator_config config = { };
@@ -246,7 +246,7 @@
 	return 0;
 }
 
-static int __devexit wm8400_regulator_remove(struct platform_device *pdev)
+static int wm8400_regulator_remove(struct platform_device *pdev)
 {
 	struct regulator_dev *rdev = platform_get_drvdata(pdev);
 
@@ -261,7 +261,7 @@
 		.name = "wm8400-regulator",
 	},
 	.probe = wm8400_regulator_probe,
-	.remove = __devexit_p(wm8400_regulator_remove),
+	.remove = wm8400_regulator_remove,
 };
 
 /**
diff --git a/drivers/regulator/wm8994-regulator.c b/drivers/regulator/wm8994-regulator.c
index 86bb48db..6ff8723 100644
--- a/drivers/regulator/wm8994-regulator.c
+++ b/drivers/regulator/wm8994-regulator.c
@@ -99,7 +99,7 @@
 	},
 };
 
-static __devinit int wm8994_ldo_probe(struct platform_device *pdev)
+static int wm8994_ldo_probe(struct platform_device *pdev)
 {
 	struct wm8994 *wm8994 = dev_get_drvdata(pdev->dev.parent);
 	struct wm8994_pdata *pdata = wm8994->dev->platform_data;
@@ -142,7 +142,7 @@
 	return ret;
 }
 
-static __devexit int wm8994_ldo_remove(struct platform_device *pdev)
+static int wm8994_ldo_remove(struct platform_device *pdev)
 {
 	struct wm8994_ldo *ldo = platform_get_drvdata(pdev);
 
@@ -155,7 +155,7 @@
 
 static struct platform_driver wm8994_ldo_driver = {
 	.probe = wm8994_ldo_probe,
-	.remove = __devexit_p(wm8994_ldo_remove),
+	.remove = wm8994_ldo_remove,
 	.driver		= {
 		.name	= "wm8994-ldo",
 		.owner	= THIS_MODULE,
diff --git a/drivers/remoteproc/remoteproc_elf_loader.c b/drivers/remoteproc/remoteproc_elf_loader.c
index e1f89d6..0d36f94 100644
--- a/drivers/remoteproc/remoteproc_elf_loader.c
+++ b/drivers/remoteproc/remoteproc_elf_loader.c
@@ -66,13 +66,13 @@
 		return -EINVAL;
 	}
 
-	/* We assume the firmware has the same endianess as the host */
+	/* We assume the firmware has the same endianness 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");
+		dev_err(dev, "Unsupported firmware endianness\n");
 		return -EINVAL;
 	}
 
diff --git a/drivers/rtc/rtc-isl1208.c b/drivers/rtc/rtc-isl1208.c
index 26c81f2..afb7cfa 100644
--- a/drivers/rtc/rtc-isl1208.c
+++ b/drivers/rtc/rtc-isl1208.c
@@ -118,7 +118,7 @@
 	return ret;
 }
 
-/* simple check to see wether we have a isl1208 */
+/* simple check to see whether we have a isl1208 */
 static int
 isl1208_i2c_validate_client(struct i2c_client *client)
 {
diff --git a/drivers/rtc/rtc-s3c.c b/drivers/rtc/rtc-s3c.c
index 77823d2..a7a2a99 100644
--- a/drivers/rtc/rtc-s3c.c
+++ b/drivers/rtc/rtc-s3c.c
@@ -186,7 +186,7 @@
 	rtc_tm->tm_year = readb(base + S3C2410_RTCYEAR);
 	rtc_tm->tm_sec  = readb(base + S3C2410_RTCSEC);
 
-	/* the only way to work out wether the system was mid-update
+	/* the only way to work out whether the system was mid-update
 	 * when we read it is to check the second counter, and if it
 	 * is zero, then we re-try the entire read
 	 */
diff --git a/drivers/s390/block/dasd_devmap.c b/drivers/s390/block/dasd_devmap.c
index b2b8c18..20cfd02 100644
--- a/drivers/s390/block/dasd_devmap.c
+++ b/drivers/s390/block/dasd_devmap.c
@@ -1344,7 +1344,7 @@
 
 /*
  * Set / reset given feature.
- * Flag indicates wether to set (!=0) or the reset (=0) the feature.
+ * Flag indicates whether to set (!=0) or the reset (=0) the feature.
  */
 int
 dasd_set_feature(struct ccw_device *cdev, int feature, int flag)
diff --git a/drivers/scsi/bnx2fc/bnx2fc_hwi.c b/drivers/scsi/bnx2fc/bnx2fc_hwi.c
index 6d6eee4..ef60afa 100644
--- a/drivers/scsi/bnx2fc/bnx2fc_hwi.c
+++ b/drivers/scsi/bnx2fc/bnx2fc_hwi.c
@@ -296,7 +296,7 @@
 	ofld_req3.flags |= (interface->vlan_enabled <<
 			    FCOE_KWQE_CONN_OFFLOAD3_B_VLAN_FLAG_SHIFT);
 
-	/* C2_VALID and ACK flags are not set as they are not suppported */
+	/* C2_VALID and ACK flags are not set as they are not supported */
 
 
 	/* Initialize offload request 4 structure */
diff --git a/drivers/scsi/libsas/sas_expander.c b/drivers/scsi/libsas/sas_expander.c
index efc6e72..aec2e0d 100644
--- a/drivers/scsi/libsas/sas_expander.c
+++ b/drivers/scsi/libsas/sas_expander.c
@@ -1800,7 +1800,7 @@
  * @dev:domain device to be detect.
  * @src_dev: the device which originated BROADCAST(CHANGE).
  *
- * Add self-configuration expander suport. Suppose two expander cascading,
+ * Add self-configuration expander support. Suppose two expander cascading,
  * when the first level expander is self-configuring, hotplug the disks in
  * second level expander, BROADCAST(CHANGE) will not only be originated
  * in the second level expander, but also be originated in the first level
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
index 5733811..9d1c7b5 100644
--- a/drivers/scsi/qla2xxx/qla_isr.c
+++ b/drivers/scsi/qla2xxx/qla_isr.c
@@ -251,7 +251,7 @@
 	/* Read all mbox registers? */
 	mboxes = (1 << ha->mbx_count) - 1;
 	if (!ha->mcp)
-		ql_dbg(ql_dbg_async, vha, 0x5001, "MBX pointer ERRROR.\n");
+		ql_dbg(ql_dbg_async, vha, 0x5001, "MBX pointer ERROR.\n");
 	else
 		mboxes = ha->mcp->in_mb;
 
@@ -2318,7 +2318,7 @@
 	/* Read all mbox registers? */
 	mboxes = (1 << ha->mbx_count) - 1;
 	if (!ha->mcp)
-		ql_dbg(ql_dbg_async, vha, 0x504e, "MBX pointer ERRROR.\n");
+		ql_dbg(ql_dbg_async, vha, 0x504e, "MBX pointer ERROR.\n");
 	else
 		mboxes = ha->mcp->in_mb;
 
diff --git a/drivers/scsi/qla2xxx/qla_nx.c b/drivers/scsi/qla2xxx/qla_nx.c
index 14cd361..f5e297c 100644
--- a/drivers/scsi/qla2xxx/qla_nx.c
+++ b/drivers/scsi/qla2xxx/qla_nx.c
@@ -955,7 +955,7 @@
 	}
 	if (loops >= 50000) {
 		ql_log(ql_log_fatal, vha, 0x00b9,
-		    "Failed to aquire SEM2 lock.\n");
+		    "Failed to acquire SEM2 lock.\n");
 		return -1;
 	}
 	ret = qla82xx_do_rom_fast_read(ha, addr, valp);
@@ -1122,7 +1122,7 @@
 		long data;
 	};
 
-	/* Halt all the indiviual PEGs and other blocks of the ISP */
+	/* Halt all the individual PEGs and other blocks of the ISP */
 	qla82xx_rom_lock(ha);
 
 	/* disable all I2Q */
diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c
index 62aa558..b49d217 100644
--- a/drivers/scsi/qla2xxx/qla_target.c
+++ b/drivers/scsi/qla2xxx/qla_target.c
@@ -73,7 +73,7 @@
 #define FCP_PTA_SIMPLE      0   /* simple task attribute */
 #define FCP_PTA_HEADQ       1   /* head of queue task attribute */
 #define FCP_PTA_ORDERED     2   /* ordered task attribute */
-#define FCP_PTA_ACA         4   /* auto. contigent allegiance */
+#define FCP_PTA_ACA         4   /* auto. contingent allegiance */
 #define FCP_PTA_MASK        7   /* mask for task attribute field */
 #define FCP_PRI_SHIFT       3   /* priority field starts in bit 3 */
 #define FCP_PRI_RESVD_MASK  0x80        /* reserved bits in priority field */
@@ -3980,7 +3980,7 @@
 	case MBA_RSP_TRANSFER_ERR:	/* Response Transfer Error */
 		ql_dbg(ql_dbg_tgt_mgt, vha, 0xf03a,
 		    "qla_target(%d): System error async event %#x "
-		    "occured", vha->vp_idx, code);
+		    "occurred", vha->vp_idx, code);
 		break;
 	case MBA_WAKEUP_THRES:		/* Request Queue Wake-up. */
 		set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
@@ -3989,7 +3989,7 @@
 	case MBA_LOOP_UP:
 	{
 		ql_dbg(ql_dbg_tgt_mgt, vha, 0xf03b,
-		    "qla_target(%d): Async LOOP_UP occured "
+		    "qla_target(%d): Async LOOP_UP occurred "
 		    "(m[0]=%x, m[1]=%x, m[2]=%x, m[3]=%x)", vha->vp_idx,
 		    le16_to_cpu(mailbox[0]), le16_to_cpu(mailbox[1]),
 		    le16_to_cpu(mailbox[2]), le16_to_cpu(mailbox[3]));
@@ -4006,7 +4006,7 @@
 	case MBA_LIP_RESET:
 	case MBA_RSCN_UPDATE:
 		ql_dbg(ql_dbg_tgt_mgt, vha, 0xf03c,
-		    "qla_target(%d): Async event %#x occured "
+		    "qla_target(%d): Async event %#x occurred "
 		    "(m[0]=%x, m[1]=%x, m[2]=%x, m[3]=%x)", vha->vp_idx, code,
 		    le16_to_cpu(mailbox[0]), le16_to_cpu(mailbox[1]),
 		    le16_to_cpu(mailbox[2]), le16_to_cpu(mailbox[3]));
@@ -4015,7 +4015,7 @@
 	case MBA_PORT_UPDATE:
 		ql_dbg(ql_dbg_tgt_mgt, vha, 0xf03d,
 		    "qla_target(%d): Port update async event %#x "
-		    "occured: updating the ports database (m[0]=%x, m[1]=%x, "
+		    "occurred: updating the ports database (m[0]=%x, m[1]=%x, "
 		    "m[2]=%x, m[3]=%x)", vha->vp_idx, code,
 		    le16_to_cpu(mailbox[0]), le16_to_cpu(mailbox[1]),
 		    le16_to_cpu(mailbox[2]), le16_to_cpu(mailbox[3]));
@@ -4031,7 +4031,7 @@
 
 	default:
 		ql_dbg(ql_dbg_tgt_mgt, vha, 0xf040,
-		    "qla_target(%d): Async event %#x occured: "
+		    "qla_target(%d): Async event %#x occurred: "
 		    "ignore (m[0]=%x, m[1]=%x, m[2]=%x, m[3]=%x)", vha->vp_idx,
 		    code, le16_to_cpu(mailbox[0]), le16_to_cpu(mailbox[1]),
 		    le16_to_cpu(mailbox[2]), le16_to_cpu(mailbox[3]));
diff --git a/drivers/scsi/qla2xxx/tcm_qla2xxx.c b/drivers/scsi/qla2xxx/tcm_qla2xxx.c
index 3d74f2f..4372e32 100644
--- a/drivers/scsi/qla2xxx/tcm_qla2xxx.c
+++ b/drivers/scsi/qla2xxx/tcm_qla2xxx.c
@@ -367,7 +367,7 @@
 
 	nacl = kzalloc(sizeof(struct tcm_qla2xxx_nacl), GFP_KERNEL);
 	if (!nacl) {
-		pr_err("Unable to alocate struct tcm_qla2xxx_nacl\n");
+		pr_err("Unable to allocate struct tcm_qla2xxx_nacl\n");
 		return NULL;
 	}
 
diff --git a/drivers/staging/comedi/drivers/usbdux.c b/drivers/staging/comedi/drivers/usbdux.c
index 78f3a2e..17b45eb 100644
--- a/drivers/staging/comedi/drivers/usbdux.c
+++ b/drivers/staging/comedi/drivers/usbdux.c
@@ -73,7 +73,7 @@
  *       And loads of cleaning up, in particular streamlining the
  *       bulk transfers.
  * 1.1:  moved EP4 transfers to EP1 to make space for a PWM output on EP4
- * 1.2:  added PWM suport via EP4
+ * 1.2:  added PWM support via EP4
  * 2.0:  PWM seems to be stable and is not interfering with the other functions
  * 2.1:  changed PWM API
  * 2.2:  added firmware kernel request to fix an udev problem
diff --git a/drivers/staging/tidspbridge/rmgr/node.c b/drivers/staging/tidspbridge/rmgr/node.c
index 294e9b4..737f4a9 100644
--- a/drivers/staging/tidspbridge/rmgr/node.c
+++ b/drivers/staging/tidspbridge/rmgr/node.c
@@ -736,7 +736,7 @@
 		case 4:
 			break;
 		default:
-			/* alignment value not suportted */
+			/* alignment value not supportted */
 			status = -EPERM;
 			break;
 		}
diff --git a/drivers/target/iscsi/iscsi_target_configfs.c b/drivers/target/iscsi/iscsi_target_configfs.c
index ff6fd4f..0f03b79 100644
--- a/drivers/target/iscsi/iscsi_target_configfs.c
+++ b/drivers/target/iscsi/iscsi_target_configfs.c
@@ -235,7 +235,7 @@
 	 * iSER/SCTP (TODO, software emulation with osc-iwarp)
 	 * iSER/IB (TODO, hardware available)
 	 *
-	 * can be enabled with atributes under
+	 * can be enabled with attributes under
 	 * sys/kernel/config/iscsi/$IQN/$TPG/np/$IP:$PORT/
 	 *
 	 */
diff --git a/drivers/target/iscsi/iscsi_target_erl0.c b/drivers/target/iscsi/iscsi_target_erl0.c
index 8aacf61..8e6298c 100644
--- a/drivers/target/iscsi/iscsi_target_erl0.c
+++ b/drivers/target/iscsi/iscsi_target_erl0.c
@@ -410,11 +410,11 @@
 	/*
 	 * For DataSequenceInOrder=Yes: If the offset is greater than the global
 	 * DataPDUInOrder=Yes offset counter in struct iscsi_cmd a protcol error has
-	 * occured and fail the connection.
+	 * occurred and fail the connection.
 	 *
 	 * For DataSequenceInOrder=No: If the offset is greater than the per
 	 * sequence DataPDUInOrder=Yes offset counter in struct iscsi_seq a protocol
-	 * error has occured and fail the connection.
+	 * error has occurred and fail the connection.
 	 */
 	if (conn->sess->sess_ops->DataSequenceInOrder) {
 		if (be32_to_cpu(hdr->offset) != cmd->write_data_done) {
@@ -801,7 +801,7 @@
 {
 	int tpg_active;
 	/*
-	 * Only start Time2Retain timer when the assoicated TPG is still in
+	 * Only start Time2Retain timer when the associated TPG is still in
 	 * an ACTIVE (eg: not disabled or shutdown) state.
 	 */
 	spin_lock(&ISCSI_TPG_S(sess)->tpg_state_lock);
diff --git a/drivers/target/iscsi/iscsi_target_parameters.c b/drivers/target/iscsi/iscsi_target_parameters.c
index 90b7400..1bf7432 100644
--- a/drivers/target/iscsi/iscsi_target_parameters.c
+++ b/drivers/target/iscsi/iscsi_target_parameters.c
@@ -1432,6 +1432,7 @@
 			break;
 		case PHASE_OPERATIONAL:
 			pr_debug("Operational phase.\n");
+			break;
 		default:
 			pr_debug("Unknown phase.\n");
 		}
diff --git a/drivers/target/iscsi/iscsi_target_util.c b/drivers/target/iscsi/iscsi_target_util.c
index 1a91195..69e0cfd 100644
--- a/drivers/target/iscsi/iscsi_target_util.c
+++ b/drivers/target/iscsi/iscsi_target_util.c
@@ -684,7 +684,7 @@
 void iscsit_free_cmd(struct iscsi_cmd *cmd)
 {
 	/*
-	 * Determine if a struct se_cmd is assoicated with
+	 * Determine if a struct se_cmd is associated with
 	 * this struct iscsi_cmd.
 	 */
 	switch (cmd->iscsi_opcode) {
diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
index 8636fae..c2c77d1 100644
--- a/drivers/thermal/Kconfig
+++ b/drivers/thermal/Kconfig
@@ -98,7 +98,7 @@
 	depends on (ARCH_EXYNOS4 || ARCH_EXYNOS5)
 	depends on CPU_THERMAL
 	help
-	  If you say yes here you get support for TMU (Thermal Managment
+	  If you say yes here you get support for TMU (Thermal Management
 	  Unit) on SAMSUNG EXYNOS series of SoC.
 
 config DB8500_THERMAL
diff --git a/drivers/tty/hvc/hvc_opal.c b/drivers/tty/hvc/hvc_opal.c
index be1a9a1..cd69b48 100644
--- a/drivers/tty/hvc/hvc_opal.c
+++ b/drivers/tty/hvc/hvc_opal.c
@@ -178,7 +178,7 @@
 		proto = HV_PROTOCOL_HVSI;
 		ops = &hvc_opal_hvsi_ops;
 	} else {
-		pr_err("hvc_opal: Unkown protocol for %s\n",
+		pr_err("hvc_opal: Unknown protocol for %s\n",
 		       dev->dev.of_node->full_name);
 		return -ENXIO;
 	}
diff --git a/drivers/tty/hvc/hvc_vio.c b/drivers/tty/hvc/hvc_vio.c
index ed6f5f1..0c62980 100644
--- a/drivers/tty/hvc/hvc_vio.c
+++ b/drivers/tty/hvc/hvc_vio.c
@@ -313,7 +313,7 @@
 		proto = HV_PROTOCOL_HVSI;
 		ops = &hvterm_hvsi_ops;
 	} else {
-		pr_err("hvc_vio: Unkown protocol for %s\n", vdev->dev.of_node->full_name);
+		pr_err("hvc_vio: Unknown protocol for %s\n", vdev->dev.of_node->full_name);
 		return -ENXIO;
 	}
 
diff --git a/drivers/tty/ipwireless/setup_protocol.h b/drivers/tty/ipwireless/setup_protocol.h
index 9d6bcc7..002c34e 100644
--- a/drivers/tty/ipwireless/setup_protocol.h
+++ b/drivers/tty/ipwireless/setup_protocol.h
@@ -59,7 +59,7 @@
 	unsigned char sig_no;		/* TL_SETUP_SIGNO_CONFIG_DONE_MSG */
 } __attribute__ ((__packed__));
 
-/* Asyncronous messages */
+/* Asynchronous messages */
 struct tl_setup_open_msg {
 	unsigned char sig_no;		/* TL_SETUP_SIGNO_OPEN_MSG */
 	unsigned char port_no;
diff --git a/drivers/tty/serial/8250/Kconfig b/drivers/tty/serial/8250/Kconfig
index f3d283f..c31133a 100644
--- a/drivers/tty/serial/8250/Kconfig
+++ b/drivers/tty/serial/8250/Kconfig
@@ -271,7 +271,7 @@
 	  present in the Synopsys DesignWare APB UART.
 
 config SERIAL_8250_EM
-	tristate "Support for Emma Mobile intergrated serial port"
+	tristate "Support for Emma Mobile integrated serial port"
 	depends on SERIAL_8250 && ARM && HAVE_CLK
 	help
 	  Selecting this option will add support for the integrated serial
diff --git a/drivers/tty/serial/bfin_uart.c b/drivers/tty/serial/bfin_uart.c
index e6a008f..2e2b2c1 100644
--- a/drivers/tty/serial/bfin_uart.c
+++ b/drivers/tty/serial/bfin_uart.c
@@ -815,7 +815,7 @@
 		lcr = WLS(5);
 		break;
 	default:
-		printk(KERN_ERR "%s: word lengh not supported\n",
+		printk(KERN_ERR "%s: word length not supported\n",
 			__func__);
 	}
 
diff --git a/drivers/tty/serial/icom.c b/drivers/tty/serial/icom.c
index 6197a69..72b6334 100644
--- a/drivers/tty/serial/icom.c
+++ b/drivers/tty/serial/icom.c
@@ -505,7 +505,7 @@
 		/* Stop processor */
 		stop_processor(icom_port);
 
-		dev_err(&icom_port->adapter->pci_dev->dev,"Port not opertional\n");
+		dev_err(&icom_port->adapter->pci_dev->dev,"Port not operational\n");
 	}
 
 	if (new_page != NULL)
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c
index 88dde95..d938b2b 100644
--- a/drivers/usb/core/driver.c
+++ b/drivers/usb/core/driver.c
@@ -222,7 +222,7 @@
 	/* TODO: Add real matching code */
 
 	/* The device should always appear to be in use
-	 * unless the driver suports autosuspend.
+	 * unless the driver supports autosuspend.
 	 */
 	if (!udriver->supports_autosuspend)
 		error = usb_autoresume_device(udev);
diff --git a/drivers/usb/gadget/at91_udc.c b/drivers/usb/gadget/at91_udc.c
index 59dcea2..f4a21f6 100644
--- a/drivers/usb/gadget/at91_udc.c
+++ b/drivers/usb/gadget/at91_udc.c
@@ -51,7 +51,7 @@
  * full speed USB controllers, including the at91rm9200 (arm920T, with MMU),
  * at91sam926x (arm926ejs, with MMU), and several no-mmu versions.
  *
- * This driver expects the board has been wired with two GPIOs suppporting
+ * This driver expects the board has been wired with two GPIOs supporting
  * a VBUS sensing IRQ, and a D+ pullup.  (They may be omitted, but the
  * testing hasn't covered such cases.)
  *
diff --git a/drivers/usb/gadget/omap_udc.c b/drivers/usb/gadget/omap_udc.c
index 09699f6..8bfe990 100644
--- a/drivers/usb/gadget/omap_udc.c
+++ b/drivers/usb/gadget/omap_udc.c
@@ -44,7 +44,7 @@
 #include <asm/unaligned.h>
 #include <asm/mach-types.h>
 
-#include <plat-omap/dma-omap.h>
+#include <linux/omap-dma.h>
 
 #include <mach/usb.h>
 
diff --git a/drivers/usb/host/ehci-orion.c b/drivers/usb/host/ehci-orion.c
index f74794c..a7d1f5b 100644
--- a/drivers/usb/host/ehci-orion.c
+++ b/drivers/usb/host/ehci-orion.c
@@ -14,6 +14,9 @@
 #include <linux/mbus.h>
 #include <linux/clk.h>
 #include <linux/platform_data/usb-ehci-orion.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_irq.h>
 
 #define rdl(off)	__raw_readl(hcd->regs + (off))
 #define wrl(off, val)	__raw_writel((val), hcd->regs + (off))
@@ -167,6 +170,8 @@
 	}
 }
 
+static u64 ehci_orion_dma_mask = DMA_BIT_MASK(32);
+
 static int ehci_orion_drv_probe(struct platform_device *pdev)
 {
 	struct orion_ehci_data *pd = pdev->dev.platform_data;
@@ -177,13 +182,17 @@
 	struct clk *clk;
 	void __iomem *regs;
 	int irq, err;
+	enum orion_ehci_phy_ver phy_version;
 
 	if (usb_disabled())
 		return -ENODEV;
 
 	pr_debug("Initializing Orion-SoC USB Host Controller\n");
 
-	irq = platform_get_irq(pdev, 0);
+	if (pdev->dev.of_node)
+		irq = irq_of_parse_and_map(pdev->dev.of_node, 0);
+	else
+		irq = platform_get_irq(pdev, 0);
 	if (irq <= 0) {
 		dev_err(&pdev->dev,
 			"Found HC with no IRQ. Check %s setup!\n",
@@ -201,6 +210,14 @@
 		goto err1;
 	}
 
+	/*
+	 * Right now device-tree probed devices don't get dma_mask
+	 * set. Since shared usb code relies on it, set it here for
+	 * now. Once we have dma capability bindings this can go away.
+	 */
+	if (!pdev->dev.dma_mask)
+		pdev->dev.dma_mask = &ehci_orion_dma_mask;
+
 	if (!request_mem_region(res->start, resource_size(res),
 				ehci_orion_hc_driver.description)) {
 		dev_dbg(&pdev->dev, "controller already in use\n");
@@ -248,7 +265,12 @@
 	/*
 	 * setup Orion USB controller.
 	 */
-	switch (pd->phy_version) {
+	if (pdev->dev.of_node)
+		phy_version = EHCI_PHY_NA;
+	else
+		phy_version = pd->phy_version;
+
+	switch (phy_version) {
 	case EHCI_PHY_NA:	/* dont change USB phy settings */
 		break;
 	case EHCI_PHY_ORION:
@@ -303,9 +325,19 @@
 
 MODULE_ALIAS("platform:orion-ehci");
 
+static const struct of_device_id ehci_orion_dt_ids[] __devinitdata = {
+	{ .compatible = "marvell,orion-ehci", },
+	{},
+};
+MODULE_DEVICE_TABLE(of, ehci_orion_dt_ids);
+
 static struct platform_driver ehci_orion_driver = {
 	.probe		= ehci_orion_drv_probe,
 	.remove		= __exit_p(ehci_orion_drv_remove),
 	.shutdown	= usb_hcd_platform_shutdown,
-	.driver.name	= "orion-ehci",
+	.driver = {
+		.name	= "orion-ehci",
+		.owner  = THIS_MODULE,
+		.of_match_table = of_match_ptr(ehci_orion_dt_ids),
+	},
 };
diff --git a/drivers/usb/musb/tusb6010_omap.c b/drivers/usb/musb/tusb6010_omap.c
index 9716850..98df17c 100644
--- a/drivers/usb/musb/tusb6010_omap.c
+++ b/drivers/usb/musb/tusb6010_omap.c
@@ -16,7 +16,7 @@
 #include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
 #include <linux/slab.h>
-#include <plat-omap/dma-omap.h>
+#include <linux/omap-dma.h>
 
 #include "musb_core.h"
 #include "tusb6010.h"
diff --git a/drivers/usb/storage/realtek_cr.c b/drivers/usb/storage/realtek_cr.c
index ea5f258..6c3586a 100644
--- a/drivers/usb/storage/realtek_cr.c
+++ b/drivers/usb/storage/realtek_cr.c
@@ -883,7 +883,7 @@
 		} else {
 			US_DEBUGP("%s: NOT working scsi, not SS\n", __func__);
 			chip->proto_handler_backup(srb, us);
-			/* Check wether card is plugged in */
+			/* Check whether card is plugged in */
 			if (srb->cmnd[0] == TEST_UNIT_READY) {
 				if (srb->result == SAM_STAT_GOOD) {
 					SET_LUN_READY(chip, srb->device->lun);
diff --git a/drivers/vhost/tcm_vhost.c b/drivers/vhost/tcm_vhost.c
index 79e7e4d..d670130 100644
--- a/drivers/vhost/tcm_vhost.c
+++ b/drivers/vhost/tcm_vhost.c
@@ -230,7 +230,7 @@
 
 	nacl = kzalloc(sizeof(struct tcm_vhost_nacl), GFP_KERNEL);
 	if (!nacl) {
-		pr_err("Unable to alocate struct tcm_vhost_nacl\n");
+		pr_err("Unable to allocate struct tcm_vhost_nacl\n");
 		return NULL;
 	}
 
diff --git a/drivers/video/omap/lcdc.c b/drivers/video/omap/lcdc.c
index c39d6e4..b52f625 100644
--- a/drivers/video/omap/lcdc.c
+++ b/drivers/video/omap/lcdc.c
@@ -31,7 +31,7 @@
 #include <linux/gfp.h>
 
 #include <mach/lcdc.h>
-#include <plat-omap/dma-omap.h>
+#include <linux/omap-dma.h>
 
 #include <asm/mach-types.h>
 
diff --git a/drivers/video/omap/omapfb_main.c b/drivers/video/omap/omapfb_main.c
index 1b5ee8e..e31f5b3 100644
--- a/drivers/video/omap/omapfb_main.c
+++ b/drivers/video/omap/omapfb_main.c
@@ -30,7 +30,7 @@
 #include <linux/uaccess.h>
 #include <linux/module.h>
 
-#include <plat-omap/dma-omap.h>
+#include <linux/omap-dma.h>
 
 #include "omapfb.h"
 #include "lcdc.h"
diff --git a/drivers/video/omap/sossi.c b/drivers/video/omap/sossi.c
index c510a44..d4e7684 100644
--- a/drivers/video/omap/sossi.c
+++ b/drivers/video/omap/sossi.c
@@ -25,7 +25,7 @@
 #include <linux/io.h>
 #include <linux/interrupt.h>
 
-#include <plat-omap/dma-omap.h>
+#include <linux/omap-dma.h>
 
 #include "omapfb.h"
 #include "lcdc.h"
diff --git a/drivers/watchdog/at91sam9_wdt.c b/drivers/watchdog/at91sam9_wdt.c
index 05e1be8..dc42e44 100644
--- a/drivers/watchdog/at91sam9_wdt.c
+++ b/drivers/watchdog/at91sam9_wdt.c
@@ -32,6 +32,7 @@
 #include <linux/timer.h>
 #include <linux/bitops.h>
 #include <linux/uaccess.h>
+#include <linux/of.h>
 
 #include "at91sam9_wdt.h"
 
@@ -302,11 +303,21 @@
 	return res;
 }
 
+#if defined(CONFIG_OF)
+static const struct of_device_id at91_wdt_dt_ids[] __initconst = {
+	{ .compatible = "atmel,at91sam9260-wdt" },
+	{ /* sentinel */ }
+};
+
+MODULE_DEVICE_TABLE(of, at91_wdt_dt_ids);
+#endif
+
 static struct platform_driver at91wdt_driver = {
 	.remove		= __exit_p(at91wdt_remove),
 	.driver		= {
 		.name	= "at91_wdt",
 		.owner	= THIS_MODULE,
+		.of_match_table = of_match_ptr(at91_wdt_dt_ids),
 	},
 };
 
diff --git a/drivers/watchdog/booke_wdt.c b/drivers/watchdog/booke_wdt.c
index 5b06d31..c0bc92d 100644
--- a/drivers/watchdog/booke_wdt.c
+++ b/drivers/watchdog/booke_wdt.c
@@ -212,7 +212,7 @@
 	return 0;
 }
 
-/* wdt_is_active stores wether or not the /dev/watchdog device is opened */
+/* wdt_is_active stores whether or not the /dev/watchdog device is opened */
 static unsigned long wdt_is_active;
 
 static int booke_wdt_open(struct inode *inode, struct file *file)
diff --git a/drivers/watchdog/omap_wdt.c b/drivers/watchdog/omap_wdt.c
index 43cc1a1..3e3ebbc 100644
--- a/drivers/watchdog/omap_wdt.c
+++ b/drivers/watchdog/omap_wdt.c
@@ -45,8 +45,6 @@
 #include <linux/uaccess.h>
 #include <linux/slab.h>
 #include <linux/pm_runtime.h>
-#include <mach/hardware.h>
-
 #include <linux/platform_data/omap-wd-timer.h>
 
 #include "omap_wdt.h"
diff --git a/drivers/xen/xen-pciback/pci_stub.c b/drivers/xen/xen-pciback/pci_stub.c
index 961d664..68dcc59 100644
--- a/drivers/xen/xen-pciback/pci_stub.c
+++ b/drivers/xen/xen-pciback/pci_stub.c
@@ -360,7 +360,7 @@
 	if (!dev_data->pci_saved_state)
 		dev_err(&dev->dev, "Could not store PCI conf saved state!\n");
 	else {
-		dev_dbg(&dev->dev, "reseting (FLR, D3, etc) the device\n");
+		dev_dbg(&dev->dev, "resetting (FLR, D3, etc) the device\n");
 		__pci_reset_function_locked(dev);
 		pci_restore_state(dev);
 	}
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index c72ead8..596617e 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -413,7 +413,7 @@
 	__le64 bytes_used;
 	__le64 num_devices;
 	/* future */
-	__le64 unsed_64[4];
+	__le64 unused_64[4];
 
 	u8 tree_root_level;
 	u8 chunk_root_level;
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 3d3e2c1..06b2635 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -3888,7 +3888,7 @@
  * @root - the root we're allocating for
  * @block_rsv - the block_rsv we're allocating for
  * @orig_bytes - the number of bytes we want
- * @flush - wether or not we can flush to make our reservation
+ * @flush - whether or not we can flush to make our reservation
  *
  * This will reserve orgi_bytes number of bytes from the space info associated
  * with the block_rsv.  If there is not enough space it will make an attempt to
diff --git a/fs/btrfs/extent_map.c b/fs/btrfs/extent_map.c
index b8cbc8d..ce9f792 100644
--- a/fs/btrfs/extent_map.c
+++ b/fs/btrfs/extent_map.c
@@ -234,12 +234,11 @@
 }
 
 /**
- * unpint_extent_cache - unpin an extent from the cache
+ * unpin_extent_cache - unpin an extent from the cache
  * @tree:	tree to unpin the extent in
  * @start:	logical offset in the file
  * @len:	length of the extent
  * @gen:	generation that this extent has been modified in
- * @prealloc:	if this is set we need to clear the prealloc flag
  *
  * Called after an extent has been written to disk properly.  Set the generation
  * to the generation that actually added the file item to the inode so we know
diff --git a/fs/btrfs/ordered-data.h b/fs/btrfs/ordered-data.h
index dd27a0b..853fc7b 100644
--- a/fs/btrfs/ordered-data.h
+++ b/fs/btrfs/ordered-data.h
@@ -76,7 +76,7 @@
 
 #define BTRFS_ORDERED_IOERR 6 /* We had an io error when writing this out */
 
-#define BTRFS_ORDERED_UPDATED_ISIZE 7 /* indicates wether this ordered extent
+#define BTRFS_ORDERED_UPDATED_ISIZE 7 /* indicates whether this ordered extent
 				       * has done its due diligence in updating
 				       * the isize. */
 
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index 0f5ebb7..e3c6ee3 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -4294,7 +4294,7 @@
 
 			rcu_read_lock();
 			name = rcu_dereference(dev->name);
-			pr_debug("btrfs_map_bio: rw %d, secor=%llu, dev=%lu "
+			pr_debug("btrfs_map_bio: rw %d, sector=%llu, dev=%lu "
 				 "(%s id %llu), size=%u\n", rw,
 				 (u64)bio->bi_sector, (u_long)dev->bdev->bd_dev,
 				 name->str, dev->devid, bio->bi_size);
diff --git a/fs/buffer.c b/fs/buffer.c
index 6e9ed48..c017a2d 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -46,8 +46,7 @@
 
 #define BH_ENTRY(list) list_entry((list), struct buffer_head, b_assoc_buffers)
 
-inline void
-init_buffer(struct buffer_head *bh, bh_end_io_t *handler, void *private)
+void init_buffer(struct buffer_head *bh, bh_end_io_t *handler, void *private)
 {
 	bh->b_end_io = handler;
 	bh->b_private = private;
@@ -850,13 +849,10 @@
 		if (!bh)
 			goto no_grow;
 
-		bh->b_bdev = NULL;
 		bh->b_this_page = head;
 		bh->b_blocknr = -1;
 		head = bh;
 
-		bh->b_state = 0;
-		atomic_set(&bh->b_count, 0);
 		bh->b_size = size;
 
 		/* Link the buffer to its page */
diff --git a/fs/cifs/README b/fs/cifs/README
index 22ab7b5..2d5622f 100644
--- a/fs/cifs/README
+++ b/fs/cifs/README
@@ -480,7 +480,7 @@
 		Unicode on the wire.
  nomapchars     Do not translate any of these seven characters (default).
  nocase         Request case insensitive path name matching (case
-		sensitive is the default if the server suports it).
+		sensitive is the default if the server supports it).
 		(mount option "ignorecase" is identical to "nocase")
  posixpaths     If CIFS Unix extensions are supported, attempt to
 		negotiate posix path name support which allows certain
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index 3c20de1..df163da 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -2455,7 +2455,7 @@
 BUFFER_FNS(Da_Mapped, da_mapped)
 
 /*
- * Add new method to test wether block and inode bitmaps are properly
+ * Add new method to test whether block and inode bitmaps are properly
  * initialized. With uninit_bg reading the block from disk is not enough
  * to mark the bitmap uptodate. We need to also zero-out the bitmap
  */
diff --git a/fs/fhandle.c b/fs/fhandle.c
index f775bfd..cccdc87 100644
--- a/fs/fhandle.c
+++ b/fs/fhandle.c
@@ -22,7 +22,7 @@
 	struct file_handle *handle = NULL;
 
 	/*
-	 * We need t make sure wether the file system
+	 * We need to make sure whether the file system
 	 * support decoding of the file handle
 	 */
 	if (!path->dentry->d_sb->s_export_op ||
@@ -40,7 +40,7 @@
 	if (!handle)
 		return -ENOMEM;
 
-	/* convert handle size to  multiple of sizeof(u32) */
+	/* convert handle size to multiple of sizeof(u32) */
 	handle_dwords = f_handle.handle_bytes >> 2;
 
 	/* we ask for a non connected handle */
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
index 3e3422f..310972b 100644
--- a/fs/fs-writeback.c
+++ b/fs/fs-writeback.c
@@ -1034,7 +1034,7 @@
 	while (!kthread_freezable_should_stop(NULL)) {
 		/*
 		 * Remove own delayed wake-up timer, since we are already awake
-		 * and we'll take care of the preriodic write-back.
+		 * and we'll take care of the periodic write-back.
 		 */
 		del_timer(&wb->wakeup_timer);
 
diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c
index 4a55f35..78bde32 100644
--- a/fs/hugetlbfs/inode.c
+++ b/fs/hugetlbfs/inode.c
@@ -1,7 +1,7 @@
 /*
  * hugetlbpage-backed filesystem.  Based on ramfs.
  *
- * William Irwin, 2002
+ * Nadia Yvette Chambers, 2002
  *
  * Copyright (C) 2002 Linus Torvalds.
  */
diff --git a/fs/jbd/transaction.c b/fs/jbd/transaction.c
index 7f5120b..071d690 100644
--- a/fs/jbd/transaction.c
+++ b/fs/jbd/transaction.c
@@ -1259,7 +1259,7 @@
 		goto not_jbd;
 	}
 
-	/* keep track of wether or not this transaction modified us */
+	/* keep track of whether or not this transaction modified us */
 	was_modified = jh->b_modified;
 
 	/*
diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c
index a74ba46..d8da40e 100644
--- a/fs/jbd2/transaction.c
+++ b/fs/jbd2/transaction.c
@@ -1261,7 +1261,7 @@
 		goto not_jbd;
 	}
 
-	/* keep track of wether or not this transaction modified us */
+	/* keep track of whether or not this transaction modified us */
 	was_modified = jh->b_modified;
 
 	/*
diff --git a/fs/logfs/inode.c b/fs/logfs/inode.c
index adb9011..af49e2d 100644
--- a/fs/logfs/inode.c
+++ b/fs/logfs/inode.c
@@ -33,7 +33,7 @@
  * are being written out - and waiting for GC to make progress, naturally.
  *
  * So we cannot just call iget() or some variant of it, but first have to check
- * wether the inode in question might be in I_FREEING state.  Therefore we
+ * whether the inode in question might be in I_FREEING state.  Therefore we
  * maintain our own per-sb list of "almost deleted" inodes and check against
  * that list first.  Normally this should be at most 1-2 entries long.
  *
diff --git a/fs/ncpfs/mmap.c b/fs/ncpfs/mmap.c
index be20a7e..63d14a9 100644
--- a/fs/ncpfs/mmap.c
+++ b/fs/ncpfs/mmap.c
@@ -89,7 +89,7 @@
 	/*
 	 * If I understand ncp_read_kernel() properly, the above always
 	 * fetches from the network, here the analogue of disk.
-	 * -- wli
+	 * -- nyc
 	 */
 	count_vm_event(PGMAJFAULT);
 	mem_cgroup_count_vm_event(area->vm_mm, PGMAJFAULT);
diff --git a/fs/notify/fanotify/Kconfig b/fs/notify/fanotify/Kconfig
index 7dceff0..e5f911b 100644
--- a/fs/notify/fanotify/Kconfig
+++ b/fs/notify/fanotify/Kconfig
@@ -4,7 +4,7 @@
 	select ANON_INODES
 	default n
 	---help---
-	   Say Y here to enable fanotify suport.  fanotify is a file access
+	   Say Y here to enable fanotify support.  fanotify is a file access
 	   notification system which differs from inotify in that it sends
 	   an open file descriptor to the userspace listener along with
 	   the event.
diff --git a/fs/notify/notification.c b/fs/notify/notification.c
index c887b13..48cb994 100644
--- a/fs/notify/notification.c
+++ b/fs/notify/notification.c
@@ -18,7 +18,7 @@
 
 /*
  * Basic idea behind the notification queue: An fsnotify group (like inotify)
- * sends the userspace notification about events asyncronously some time after
+ * sends the userspace notification about events asynchronously some time after
  * the event happened.  When inotify gets an event it will need to add that
  * event to the group notify queue.  Since a single event might need to be on
  * multiple group's notification queues we can't add the event directly to each
diff --git a/fs/proc/kcore.c b/fs/proc/kcore.c
index 86c67ee..e96d4f1 100644
--- a/fs/proc/kcore.c
+++ b/fs/proc/kcore.c
@@ -249,7 +249,7 @@
 	/* Not inialized....update now */
 	/* find out "max pfn" */
 	end_pfn = 0;
-	for_each_node_state(nid, N_HIGH_MEMORY) {
+	for_each_node_state(nid, N_MEMORY) {
 		unsigned long node_end;
 		node_end  = NODE_DATA(nid)->node_start_pfn +
 			NODE_DATA(nid)->node_spanned_pages;
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
index 90c63f9..4877562 100644
--- a/fs/proc/task_mmu.c
+++ b/fs/proc/task_mmu.c
@@ -643,7 +643,7 @@
 	spinlock_t *ptl;
 	struct page *page;
 
-	split_huge_page_pmd(walk->mm, pmd);
+	split_huge_page_pmd(vma, addr, pmd);
 	if (pmd_trans_unstable(pmd))
 		return 0;
 
@@ -1126,7 +1126,7 @@
 		return NULL;
 
 	nid = page_to_nid(page);
-	if (!node_isset(nid, node_states[N_HIGH_MEMORY]))
+	if (!node_isset(nid, node_states[N_MEMORY]))
 		return NULL;
 
 	return page;
@@ -1279,7 +1279,7 @@
 	if (md->writeback)
 		seq_printf(m, " writeback=%lu", md->writeback);
 
-	for_each_node_state(n, N_HIGH_MEMORY)
+	for_each_node_state(n, N_MEMORY)
 		if (md->node[n])
 			seq_printf(m, " N%d=%lu", n, md->node[n]);
 out:
diff --git a/include/acpi/acpi_drivers.h b/include/acpi/acpi_drivers.h
index bb145e4..8b1d7a6 100644
--- a/include/acpi/acpi_drivers.h
+++ b/include/acpi/acpi_drivers.h
@@ -92,8 +92,8 @@
 
 /* ACPI PCI Interrupt Routing (pci_irq.c) */
 
-int acpi_pci_irq_add_prt(acpi_handle handle, struct pci_bus *bus);
-void acpi_pci_irq_del_prt(struct pci_bus *bus);
+int acpi_pci_irq_add_prt(acpi_handle handle, int segment, int bus);
+void acpi_pci_irq_del_prt(int segment, int bus);
 
 /* ACPI PCI Device Binding (pci_bind.c) */
 
diff --git a/include/asm-generic/pgtable.h b/include/asm-generic/pgtable.h
index b36ce40..284e808 100644
--- a/include/asm-generic/pgtable.h
+++ b/include/asm-generic/pgtable.h
@@ -449,6 +449,32 @@
 			unsigned long size);
 #endif
 
+#ifdef __HAVE_COLOR_ZERO_PAGE
+static inline int is_zero_pfn(unsigned long pfn)
+{
+	extern unsigned long zero_pfn;
+	unsigned long offset_from_zero_pfn = pfn - zero_pfn;
+	return offset_from_zero_pfn <= (zero_page_mask >> PAGE_SHIFT);
+}
+
+static inline unsigned long my_zero_pfn(unsigned long addr)
+{
+	return page_to_pfn(ZERO_PAGE(addr));
+}
+#else
+static inline int is_zero_pfn(unsigned long pfn)
+{
+	extern unsigned long zero_pfn;
+	return pfn == zero_pfn;
+}
+
+static inline unsigned long my_zero_pfn(unsigned long addr)
+{
+	extern unsigned long zero_pfn;
+	return zero_pfn;
+}
+#endif
+
 #ifdef CONFIG_MMU
 
 #ifndef CONFIG_TRANSPARENT_HUGEPAGE
diff --git a/include/linux/atmel-ssc.h b/include/linux/atmel-ssc.h
index 4eb3175..deb0ae5 100644
--- a/include/linux/atmel-ssc.h
+++ b/include/linux/atmel-ssc.h
@@ -5,10 +5,16 @@
 #include <linux/list.h>
 #include <linux/io.h>
 
+struct atmel_ssc_platform_data {
+	int			use_dma;
+};
+
 struct ssc_device {
 	struct list_head	list;
+	resource_size_t		phybase;
 	void __iomem		*regs;
 	struct platform_device	*pdev;
+	struct atmel_ssc_platform_data *pdata;
 	struct clk		*clk;
 	int			user;
 	int			irq;
diff --git a/include/linux/bootmem.h b/include/linux/bootmem.h
index 7b74452..3f778c2 100644
--- a/include/linux/bootmem.h
+++ b/include/linux/bootmem.h
@@ -137,9 +137,6 @@
 #define alloc_bootmem_low_pages_node(pgdat, x) \
 	__alloc_bootmem_low_node(pgdat, x, PAGE_SIZE, 0)
 
-extern int reserve_bootmem_generic(unsigned long addr, unsigned long size,
-				   int flags);
-
 #ifdef CONFIG_HAVE_ARCH_ALLOC_REMAP
 extern void *alloc_remap(int nid, unsigned long size);
 #else
diff --git a/arch/arm/mach-vt8500/include/mach/irqs.h b/include/linux/clk/zynq.h
similarity index 78%
rename from arch/arm/mach-vt8500/include/mach/irqs.h
rename to include/linux/clk/zynq.h
index a129fd1..56be7cd 100644
--- a/arch/arm/mach-vt8500/include/mach/irqs.h
+++ b/include/linux/clk/zynq.h
@@ -1,7 +1,5 @@
 /*
- *  arch/arm/mach-vt8500/include/mach/irqs.h
- *
- *  Copyright (C) 2010 Alexey Charkov <alchark@gmail.com>
+ * Copyright (C) 2012 National Instruments
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -18,5 +16,9 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
-/* This value is just to make the core happy, never used otherwise */
-#define NR_IRQS 128
+#ifndef __LINUX_CLK_ZYNQ_H_
+#define __LINUX_CLK_ZYNQ_H_
+
+void __init xilinx_zynq_clocks_init(void __iomem *slcr);
+
+#endif
diff --git a/include/linux/cpuset.h b/include/linux/cpuset.h
index 838320f..8c8a60d 100644
--- a/include/linux/cpuset.h
+++ b/include/linux/cpuset.h
@@ -144,7 +144,7 @@
 	return node_possible_map;
 }
 
-#define cpuset_current_mems_allowed (node_states[N_HIGH_MEMORY])
+#define cpuset_current_mems_allowed (node_states[N_MEMORY])
 static inline void cpuset_init_current_mems_allowed(void) {}
 
 static inline int cpuset_nodemask_valid_mems_allowed(nodemask_t *nodemask)
diff --git a/include/linux/dlm.h b/include/linux/dlm.h
index 1d47dcc..d02da2c 100644
--- a/include/linux/dlm.h
+++ b/include/linux/dlm.h
@@ -98,7 +98,7 @@
 /*
  * dlm_lock
  *
- * Make an asyncronous request to acquire or convert a lock on a named
+ * Make an asynchronous request to acquire or convert a lock on a named
  * resource.
  *
  * lockspace: context for the request
diff --git a/include/linux/efi.h b/include/linux/efi.h
index c47ec36..b02099d 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -196,6 +196,77 @@
 	void *create_event_ex;
 } efi_boot_services_t;
 
+typedef enum {
+	EfiPciIoWidthUint8,
+	EfiPciIoWidthUint16,
+	EfiPciIoWidthUint32,
+	EfiPciIoWidthUint64,
+	EfiPciIoWidthFifoUint8,
+	EfiPciIoWidthFifoUint16,
+	EfiPciIoWidthFifoUint32,
+	EfiPciIoWidthFifoUint64,
+	EfiPciIoWidthFillUint8,
+	EfiPciIoWidthFillUint16,
+	EfiPciIoWidthFillUint32,
+	EfiPciIoWidthFillUint64,
+	EfiPciIoWidthMaximum
+} EFI_PCI_IO_PROTOCOL_WIDTH;
+
+typedef enum {
+	EfiPciIoAttributeOperationGet,
+	EfiPciIoAttributeOperationSet,
+	EfiPciIoAttributeOperationEnable,
+	EfiPciIoAttributeOperationDisable,
+	EfiPciIoAttributeOperationSupported,
+    EfiPciIoAttributeOperationMaximum
+} EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION;
+
+
+typedef struct {
+	void *read;
+	void *write;
+} efi_pci_io_protocol_access_t;
+
+typedef struct {
+	void *poll_mem;
+	void *poll_io;
+	efi_pci_io_protocol_access_t mem;
+	efi_pci_io_protocol_access_t io;
+	efi_pci_io_protocol_access_t pci;
+	void *copy_mem;
+	void *map;
+	void *unmap;
+	void *allocate_buffer;
+	void *free_buffer;
+	void *flush;
+	void *get_location;
+	void *attributes;
+	void *get_bar_attributes;
+	void *set_bar_attributes;
+	uint64_t romsize;
+	void *romimage;
+} efi_pci_io_protocol;
+
+#define EFI_PCI_IO_ATTRIBUTE_ISA_MOTHERBOARD_IO 0x0001
+#define EFI_PCI_IO_ATTRIBUTE_ISA_IO 0x0002
+#define EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO 0x0004
+#define EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY 0x0008
+#define EFI_PCI_IO_ATTRIBUTE_VGA_IO 0x0010
+#define EFI_PCI_IO_ATTRIBUTE_IDE_PRIMARY_IO 0x0020
+#define EFI_PCI_IO_ATTRIBUTE_IDE_SECONDARY_IO 0x0040
+#define EFI_PCI_IO_ATTRIBUTE_MEMORY_WRITE_COMBINE 0x0080
+#define EFI_PCI_IO_ATTRIBUTE_IO 0x0100
+#define EFI_PCI_IO_ATTRIBUTE_MEMORY 0x0200
+#define EFI_PCI_IO_ATTRIBUTE_BUS_MASTER 0x0400
+#define EFI_PCI_IO_ATTRIBUTE_MEMORY_CACHED 0x0800
+#define EFI_PCI_IO_ATTRIBUTE_MEMORY_DISABLE 0x1000
+#define EFI_PCI_IO_ATTRIBUTE_EMBEDDED_DEVICE 0x2000
+#define EFI_PCI_IO_ATTRIBUTE_EMBEDDED_ROM 0x4000
+#define EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE 0x8000
+#define EFI_PCI_IO_ATTRIBUTE_ISA_IO_16 0x10000
+#define EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO_16 0x20000
+#define EFI_PCI_IO_ATTRIBUTE_VGA_IO_16 0x40000
+
 /*
  * Types and defines for EFI ResetSystem
  */
diff --git a/include/linux/gfp.h b/include/linux/gfp.h
index 31e8041..f74856e 100644
--- a/include/linux/gfp.h
+++ b/include/linux/gfp.h
@@ -34,6 +34,7 @@
 #define ___GFP_NO_KSWAPD	0x400000u
 #define ___GFP_OTHER_NODE	0x800000u
 #define ___GFP_WRITE		0x1000000u
+/* If the above are modified, __GFP_BITS_SHIFT may need updating */
 
 /*
  * GFP bitmasks..
diff --git a/include/linux/hash.h b/include/linux/hash.h
index 24df9e7..61c97ae 100644
--- a/include/linux/hash.h
+++ b/include/linux/hash.h
@@ -1,7 +1,7 @@
 #ifndef _LINUX_HASH_H
 #define _LINUX_HASH_H
 /* Fast hashing routine for ints,  longs and pointers.
-   (C) 2002 William Lee Irwin III, IBM */
+   (C) 2002 Nadia Yvette Chambers, IBM */
 
 /*
  * Knuth recommends primes in approximately golden ratio to the maximum
diff --git a/include/linux/hid-sensor-ids.h b/include/linux/hid-sensor-ids.h
index ca8d7e9..55f2773 100644
--- a/include/linux/hid-sensor-ids.h
+++ b/include/linux/hid-sensor-ids.h
@@ -19,7 +19,6 @@
 #ifndef _HID_SENSORS_IDS_H
 #define _HID_SENSORS_IDS_H
 
-#define HID_UP_SENSOR						0x00200000
 #define HID_MAX_PHY_DEVICES					0xFF
 
 /* Accel 3D (200073) */
diff --git a/include/linux/hid.h b/include/linux/hid.h
index c076041..7330a0f 100644
--- a/include/linux/hid.h
+++ b/include/linux/hid.h
@@ -167,6 +167,7 @@
 #define HID_UP_MSVENDOR		0xff000000
 #define HID_UP_CUSTOM		0x00ff0000
 #define HID_UP_LOGIVENDOR	0xffbc0000
+#define HID_UP_SENSOR		0x00200000
 
 #define HID_USAGE		0x0000ffff
 
@@ -292,6 +293,7 @@
  */
 #define HID_GROUP_GENERIC			0x0001
 #define HID_GROUP_MULTITOUCH			0x0002
+#define HID_GROUP_SENSOR_HUB			0x0003
 
 /*
  * This is the global environment of the parser. This information is
@@ -342,6 +344,7 @@
 struct hid_usage {
 	unsigned  hid;			/* hid usage code */
 	unsigned  collection_index;	/* index into collection array */
+	unsigned  usage_index;		/* index into usage array */
 	/* hidinput data */
 	__u16     code;			/* input driver code */
 	__u8      type;			/* input driver type */
@@ -684,6 +687,7 @@
 
 extern int hid_debug;
 
+extern bool hid_ignore(struct hid_device *);
 extern int hid_add_device(struct hid_device *);
 extern void hid_destroy_device(struct hid_device *);
 
@@ -706,6 +710,7 @@
 int hidinput_find_field(struct hid_device *hid, unsigned int type, unsigned int code, struct hid_field **field);
 struct hid_field *hidinput_get_led_field(struct hid_device *hid);
 unsigned int hidinput_count_leds(struct hid_device *hid);
+__s32 hidinput_calc_abs_res(const struct hid_field *field, __u16 code);
 void hid_output_report(struct hid_report *report, __u8 *data);
 struct hid_device *hid_allocate_device(void);
 struct hid_report *hid_register_report(struct hid_device *device, unsigned type, unsigned id);
@@ -716,6 +721,7 @@
 void hid_disconnect(struct hid_device *hid);
 const struct hid_device_id *hid_match_id(struct hid_device *hdev,
 					 const struct hid_device_id *id);
+s32 hid_snto32(__u32 value, unsigned n);
 
 /**
  * hid_map_usage - map usage input bits
diff --git a/include/linux/huge_mm.h b/include/linux/huge_mm.h
index 1af4775..092dc53 100644
--- a/include/linux/huge_mm.h
+++ b/include/linux/huge_mm.h
@@ -39,6 +39,7 @@
 	TRANSPARENT_HUGEPAGE_DEFRAG_FLAG,
 	TRANSPARENT_HUGEPAGE_DEFRAG_REQ_MADV_FLAG,
 	TRANSPARENT_HUGEPAGE_DEFRAG_KHUGEPAGED_FLAG,
+	TRANSPARENT_HUGEPAGE_USE_ZERO_PAGE_FLAG,
 #ifdef CONFIG_DEBUG_VM
 	TRANSPARENT_HUGEPAGE_DEBUG_COW_FLAG,
 #endif
@@ -78,6 +79,9 @@
 	 (transparent_hugepage_flags &					\
 	  (1<<TRANSPARENT_HUGEPAGE_DEFRAG_REQ_MADV_FLAG) &&		\
 	  (__vma)->vm_flags & VM_HUGEPAGE))
+#define transparent_hugepage_use_zero_page()				\
+	(transparent_hugepage_flags &					\
+	 (1<<TRANSPARENT_HUGEPAGE_USE_ZERO_PAGE_FLAG))
 #ifdef CONFIG_DEBUG_VM
 #define transparent_hugepage_debug_cow()				\
 	(transparent_hugepage_flags &					\
@@ -95,12 +99,14 @@
 			    struct vm_area_struct *vma, unsigned long address,
 			    pte_t *pte, pmd_t *pmd, unsigned int flags);
 extern int split_huge_page(struct page *page);
-extern void __split_huge_page_pmd(struct mm_struct *mm, pmd_t *pmd);
-#define split_huge_page_pmd(__mm, __pmd)				\
+extern void __split_huge_page_pmd(struct vm_area_struct *vma,
+		unsigned long address, pmd_t *pmd);
+#define split_huge_page_pmd(__vma, __address, __pmd)			\
 	do {								\
 		pmd_t *____pmd = (__pmd);				\
 		if (unlikely(pmd_trans_huge(*____pmd)))			\
-			__split_huge_page_pmd(__mm, ____pmd);		\
+			__split_huge_page_pmd(__vma, __address,		\
+					____pmd);			\
 	}  while (0)
 #define wait_split_huge_page(__anon_vma, __pmd)				\
 	do {								\
@@ -110,6 +116,8 @@
 		BUG_ON(pmd_trans_splitting(*____pmd) ||			\
 		       pmd_trans_huge(*____pmd));			\
 	} while (0)
+extern void split_huge_page_pmd_mm(struct mm_struct *mm, unsigned long address,
+		pmd_t *pmd);
 #if HPAGE_PMD_ORDER > MAX_ORDER
 #error "hugepages can't be allocated by the buddy allocator"
 #endif
@@ -177,10 +185,12 @@
 {
 	return 0;
 }
-#define split_huge_page_pmd(__mm, __pmd)	\
+#define split_huge_page_pmd(__vma, __address, __pmd)	\
 	do { } while (0)
 #define wait_split_huge_page(__anon_vma, __pmd)	\
 	do { } while (0)
+#define split_huge_page_pmd_mm(__mm, __address, __pmd)	\
+	do { } while (0)
 #define compound_trans_head(page) compound_head(page)
 static inline int hugepage_madvise(struct vm_area_struct *vma,
 				   unsigned long *vm_flags, int advice)
diff --git a/include/linux/i2c/i2c-hid.h b/include/linux/i2c/i2c-hid.h
new file mode 100644
index 0000000..60e411d
--- /dev/null
+++ b/include/linux/i2c/i2c-hid.h
@@ -0,0 +1,35 @@
+/*
+ * HID over I2C protocol implementation
+ *
+ * Copyright (c) 2012 Benjamin Tissoires <benjamin.tissoires@gmail.com>
+ * Copyright (c) 2012 Ecole Nationale de l'Aviation Civile, France
+ *
+ * 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 __LINUX_I2C_HID_H
+#define __LINUX_I2C_HID_H
+
+#include <linux/types.h>
+
+/**
+ * struct i2chid_platform_data - used by hid over i2c implementation.
+ * @hid_descriptor_address: i2c register where the HID descriptor is stored.
+ *
+ * Note that it is the responsibility of the platform driver (or the acpi 5.0
+ * driver) to setup the irq related to the gpio in the struct i2c_board_info.
+ * The platform driver should also setup the gpio according to the device:
+ *
+ * A typical example is the following:
+ *	irq = gpio_to_irq(intr_gpio);
+ *	hkdk4412_i2c_devs5[0].irq = irq; // store the irq in i2c_board_info
+ *	gpio_request(intr_gpio, "elan-irq");
+ *	s3c_gpio_setpull(intr_gpio, S3C_GPIO_PULL_UP);
+ */
+struct i2c_hid_platform_data {
+	u16 hid_descriptor_address;
+};
+
+#endif /* __LINUX_I2C_HID_H */
diff --git a/include/linux/input/mt.h b/include/linux/input/mt.h
index cc5cca7..2e86bd0 100644
--- a/include/linux/input/mt.h
+++ b/include/linux/input/mt.h
@@ -69,6 +69,12 @@
 	return input_mt_get_value(slot, ABS_MT_TRACKING_ID) >= 0;
 }
 
+static inline bool input_mt_is_used(const struct input_mt *mt,
+				    const struct input_mt_slot *slot)
+{
+	return slot->frame == mt->frame;
+}
+
 int input_mt_init_slots(struct input_dev *dev, unsigned int num_slots,
 			unsigned int flags);
 void input_mt_destroy_slots(struct input_dev *dev);
diff --git a/include/linux/ipmi_smi.h b/include/linux/ipmi_smi.h
index fcb5d44..8ea3fe0 100644
--- a/include/linux/ipmi_smi.h
+++ b/include/linux/ipmi_smi.h
@@ -216,7 +216,7 @@
 
 /*
  * The lower layer reports received messages through this interface.
- * The data_size should be zero if this is an asyncronous message.  If
+ * The data_size should be zero if this is an asynchronous message.  If
  * the lower layer gets an error sending a message, it should format
  * an error response in the message response.
  */
diff --git a/include/linux/lru_cache.h b/include/linux/lru_cache.h
index 7a71ffa..cafc7f9 100644
--- a/include/linux/lru_cache.h
+++ b/include/linux/lru_cache.h
@@ -52,8 +52,8 @@
 
 For crash recovery after replication node failure,
   we need to resync all regions that have been target of in-flight WRITE IO
-  (in use, or "hot", regions), as we don't know wether or not those WRITEs have
-  made it to stable storage.
+  (in use, or "hot", regions), as we don't know whether or not those WRITEs
+  have made it to stable storage.
 
   To avoid a "full resync", we need to persistently track these regions.
 
diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h
index 11ddc7f..e98a74c 100644
--- a/include/linux/memcontrol.h
+++ b/include/linux/memcontrol.h
@@ -181,7 +181,14 @@
 						gfp_t gfp_mask,
 						unsigned long *total_scanned);
 
-void mem_cgroup_count_vm_event(struct mm_struct *mm, enum vm_event_item idx);
+void __mem_cgroup_count_vm_event(struct mm_struct *mm, enum vm_event_item idx);
+static inline void mem_cgroup_count_vm_event(struct mm_struct *mm,
+					     enum vm_event_item idx)
+{
+	if (mem_cgroup_disabled())
+		return;
+	__mem_cgroup_count_vm_event(mm, idx);
+}
 #ifdef CONFIG_TRANSPARENT_HUGEPAGE
 void mem_cgroup_split_huge_fixup(struct page *head);
 #endif
diff --git a/include/linux/memory.h b/include/linux/memory.h
index a09216d..45e93b4 100644
--- a/include/linux/memory.h
+++ b/include/linux/memory.h
@@ -54,6 +54,7 @@
 	unsigned long start_pfn;
 	unsigned long nr_pages;
 	int status_change_nid_normal;
+	int status_change_nid_high;
 	int status_change_nid;
 };
 
diff --git a/include/linux/mfd/arizona/core.h b/include/linux/mfd/arizona/core.h
index dd231ac..a580363 100644
--- a/include/linux/mfd/arizona/core.h
+++ b/include/linux/mfd/arizona/core.h
@@ -78,6 +78,8 @@
 
 #define ARIZONA_NUM_IRQ                   50
 
+struct snd_soc_dapm_context;
+
 struct arizona {
 	struct regmap *regmap;
 	struct device *dev;
@@ -98,6 +100,8 @@
 
 	struct mutex clk_lock;
 	int clk32k_ref;
+
+	struct snd_soc_dapm_context *dapm;
 };
 
 int arizona_clk32k_enable(struct arizona *arizona);
diff --git a/include/linux/mfd/arizona/pdata.h b/include/linux/mfd/arizona/pdata.h
index 7ab4429..8b1d1da 100644
--- a/include/linux/mfd/arizona/pdata.h
+++ b/include/linux/mfd/arizona/pdata.h
@@ -62,6 +62,9 @@
 
 #define ARIZONA_MAX_OUTPUT 6
 
+#define ARIZONA_HAP_ACT_ERM 0
+#define ARIZONA_HAP_ACT_LRA 2
+
 #define ARIZONA_MAX_PDM_SPK 2
 
 struct regulator_init_data;
@@ -114,6 +117,9 @@
 
 	/** PDM speaker format */
 	unsigned int spk_fmt[ARIZONA_MAX_PDM_SPK];
+
+	/** Haptic actuator type */
+	unsigned int hap_act;
 };
 
 #endif
diff --git a/include/linux/mfd/arizona/registers.h b/include/linux/mfd/arizona/registers.h
index 7671a28..ba26e99 100644
--- a/include/linux/mfd/arizona/registers.h
+++ b/include/linux/mfd/arizona/registers.h
@@ -76,6 +76,7 @@
 #define ARIZONA_RATE_ESTIMATOR_3                 0x154
 #define ARIZONA_RATE_ESTIMATOR_4                 0x155
 #define ARIZONA_RATE_ESTIMATOR_5                 0x156
+#define ARIZONA_DYNAMIC_FREQUENCY_SCALING_1      0x161
 #define ARIZONA_FLL1_CONTROL_1                   0x171
 #define ARIZONA_FLL1_CONTROL_2                   0x172
 #define ARIZONA_FLL1_CONTROL_3                   0x173
@@ -110,6 +111,7 @@
 #define ARIZONA_FLL2_GPIO_CLOCK                  0x1AA
 #define ARIZONA_MIC_CHARGE_PUMP_1                0x200
 #define ARIZONA_LDO1_CONTROL_1                   0x210
+#define ARIZONA_LDO1_CONTROL_2                   0x212
 #define ARIZONA_LDO2_CONTROL_1                   0x213
 #define ARIZONA_MIC_BIAS_CTRL_1                  0x218
 #define ARIZONA_MIC_BIAS_CTRL_2                  0x219
@@ -1574,6 +1576,13 @@
 #define ARIZONA_SAMPLE_RATE_DETECT_D_WIDTH            5  /* SAMPLE_RATE_DETECT_D - [4:0] */
 
 /*
+ * R353 (0x161) - Dynamic Frequency Scaling 1
+ */
+#define ARIZONA_SUBSYS_MAX_FREQ                  0x0001  /* SUBSYS_MAX_FREQ */
+#define ARIZONA_SUBSYS_MAX_FREQ_SHIFT                 0  /* SUBSYS_MAX_FREQ */
+#define ARIZONA_SUBSYS_MAX_FREQ_WIDTH                 1  /* SUBSYS_MAX_FREQ */
+
+/*
  * R369 (0x171) - FLL1 Control 1
  */
 #define ARIZONA_FLL1_FREERUN                     0x0002  /* FLL1_FREERUN */
@@ -1889,6 +1898,13 @@
 #define ARIZONA_LDO1_ENA_WIDTH                        1  /* LDO1_ENA */
 
 /*
+ * R530 (0x212) - LDO1 Control 2
+ */
+#define ARIZONA_LDO1_HI_PWR                      0x0001  /* LDO1_HI_PWR */
+#define ARIZONA_LDO1_HI_PWR_SHIFT                     0  /* LDO1_HI_PWR */
+#define ARIZONA_LDO1_HI_PWR_WIDTH                     1  /* LDO1_HI_PWR */
+
+/*
  * R531 (0x213) - LDO2 Control 1
  */
 #define ARIZONA_LDO2_VSEL_MASK                   0x07E0  /* LDO2_VSEL - [10:5] */
diff --git a/include/linux/mfd/da9055/pdata.h b/include/linux/mfd/da9055/pdata.h
index 147293b..f87a6c1 100644
--- a/include/linux/mfd/da9055/pdata.h
+++ b/include/linux/mfd/da9055/pdata.h
@@ -25,8 +25,29 @@
 	int gpio_base;
 
 	struct regulator_init_data *regulators[DA9055_MAX_REGULATORS];
-	bool reset_enable;		/* Enable RTC in RESET Mode */
-	enum gpio_select *gpio_rsel;	/* Select regulator set thru GPIO 1/2 */
-	enum gpio_select *gpio_ren;	/* Enable regulator thru GPIO 1/2 */
+	/* Enable RTC in RESET Mode */
+	bool reset_enable;
+	/*
+	 * GPI muxed pin to control
+	 * regulator state A/B, 0 if not available.
+	 */
+	int *gpio_ren;
+	/*
+	 * GPI muxed pin to control
+	 * regulator set, 0 if not available.
+	 */
+	int *gpio_rsel;
+	/*
+	 * Regulator mode control bits value (GPI offset) that
+	 * that controls the regulator state, 0 if not available.
+	 */
+	enum gpio_select *reg_ren;
+	/*
+	 * Regulator mode control bits value (GPI offset) that
+	 * controls the regulator set A/B, 0 if  not available.
+	 */
+	enum gpio_select *reg_rsel;
+	/* GPIOs to enable regulator, 0 if not available */
+	int *ena_gpio;
 };
 #endif /* __DA9055_PDATA_H */
diff --git a/include/linux/mfd/max8997-private.h b/include/linux/mfd/max8997-private.h
index 830152c..6ae21bf 100644
--- a/include/linux/mfd/max8997-private.h
+++ b/include/linux/mfd/max8997-private.h
@@ -316,6 +316,7 @@
 #define MAX8997_NUM_GPIO	12
 struct max8997_dev {
 	struct device *dev;
+	struct max8997_platform_data *pdata;
 	struct i2c_client *i2c; /* 0xcc / PMIC, Battery Control, and FLASH */
 	struct i2c_client *rtc; /* slave addr 0x0c */
 	struct i2c_client *haptic; /* slave addr 0x90 */
diff --git a/include/linux/mfd/max8997.h b/include/linux/mfd/max8997.h
index 328d8e2..1d4a4fe 100644
--- a/include/linux/mfd/max8997.h
+++ b/include/linux/mfd/max8997.h
@@ -75,6 +75,7 @@
 struct max8997_regulator_data {
 	int id;
 	struct regulator_init_data *initdata;
+	struct device_node *reg_node;
 };
 
 enum max8997_muic_usb_type {
diff --git a/include/linux/mfd/tps65090.h b/include/linux/mfd/tps65090.h
index 6bc31d8..804e280 100644
--- a/include/linux/mfd/tps65090.h
+++ b/include/linux/mfd/tps65090.h
@@ -24,6 +24,25 @@
 
 #include <linux/irq.h>
 
+/* TPS65090 Regulator ID */
+enum {
+	TPS65090_REGULATOR_DCDC1,
+	TPS65090_REGULATOR_DCDC2,
+	TPS65090_REGULATOR_DCDC3,
+	TPS65090_REGULATOR_FET1,
+	TPS65090_REGULATOR_FET2,
+	TPS65090_REGULATOR_FET3,
+	TPS65090_REGULATOR_FET4,
+	TPS65090_REGULATOR_FET5,
+	TPS65090_REGULATOR_FET6,
+	TPS65090_REGULATOR_FET7,
+	TPS65090_REGULATOR_LDO1,
+	TPS65090_REGULATOR_LDO2,
+
+	/* Last entry for maximum ID */
+	TPS65090_REGULATOR_MAX,
+};
+
 struct tps65090 {
 	struct mutex		lock;
 	struct device		*dev;
@@ -41,10 +60,26 @@
 	void		*platform_data;
 };
 
+/*
+ * struct tps65090_regulator_plat_data
+ *
+ * @reg_init_data: The regulator init data.
+ * @enable_ext_control: Enable extrenal control or not. Only available for
+ *     DCDC1, DCDC2 and DCDC3.
+ * @gpio: Gpio number if external control is enabled and controlled through
+ *     gpio.
+ */
+struct tps65090_regulator_plat_data {
+	struct regulator_init_data *reg_init_data;
+	bool enable_ext_control;
+	int gpio;
+};
+
 struct tps65090_platform_data {
 	int irq_base;
 	int num_subdevs;
 	struct tps65090_subdev_info *subdevs;
+	struct tps65090_regulator_plat_data *reg_pdata[TPS65090_REGULATOR_MAX];
 };
 
 /*
diff --git a/include/linux/mfd/tps6586x.h b/include/linux/mfd/tps6586x.h
index 2dd1231..f8da0e1 100644
--- a/include/linux/mfd/tps6586x.h
+++ b/include/linux/mfd/tps6586x.h
@@ -29,6 +29,7 @@
 	TPS6586X_ID_LDO_8,
 	TPS6586X_ID_LDO_9,
 	TPS6586X_ID_LDO_RTC,
+	TPS6586X_ID_MAX_REGULATOR,
 };
 
 enum {
@@ -79,6 +80,8 @@
 	int gpio_base;
 	int irq_base;
 	bool pm_off;
+
+	struct regulator_init_data *reg_init_data[TPS6586X_ID_MAX_REGULATOR];
 };
 
 /*
diff --git a/include/linux/mfd/wm8994/core.h b/include/linux/mfd/wm8994/core.h
index 1f17330..ae5c249 100644
--- a/include/linux/mfd/wm8994/core.h
+++ b/include/linux/mfd/wm8994/core.h
@@ -19,6 +19,8 @@
 #include <linux/interrupt.h>
 #include <linux/regmap.h>
 
+#include <linux/mfd/wm8994/pdata.h>
+
 enum wm8994_type {
 	WM8994 = 0,
 	WM8958 = 1,
@@ -55,6 +57,8 @@
 struct wm8994 {
 	struct mutex irq_lock;
 
+	struct wm8994_pdata pdata;
+
 	enum wm8994_type type;
 	int revision;
 	int cust_id;
diff --git a/include/linux/mfd/wm8994/pdata.h b/include/linux/mfd/wm8994/pdata.h
index fc87be4..8e21a09 100644
--- a/include/linux/mfd/wm8994/pdata.h
+++ b/include/linux/mfd/wm8994/pdata.h
@@ -176,6 +176,11 @@
         unsigned int lineout1fb:1;
         unsigned int lineout2fb:1;
 
+	/* Delay between detecting a jack and starting microphone
+	 * detect (specified in ms)
+	 */
+	int micdet_delay;
+
 	/* IRQ for microphone detection if brought out directly as a
 	 * signal.
 	 */
diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
index 0c0b1d6..cd55dad 100644
--- a/include/linux/mmzone.h
+++ b/include/linux/mmzone.h
@@ -460,17 +460,44 @@
 	unsigned long		zone_start_pfn;
 
 	/*
-	 * zone_start_pfn, spanned_pages and present_pages are all
-	 * protected by span_seqlock.  It is a seqlock because it has
-	 * to be read outside of zone->lock, and it is done in the main
-	 * allocator path.  But, it is written quite infrequently.
+	 * spanned_pages is the total pages spanned by the zone, including
+	 * holes, which is calculated as:
+	 * 	spanned_pages = zone_end_pfn - zone_start_pfn;
 	 *
-	 * The lock is declared along with zone->lock because it is
+	 * present_pages is physical pages existing within the zone, which
+	 * is calculated as:
+	 *	present_pages = spanned_pages - absent_pages(pags in holes);
+	 *
+	 * managed_pages is present pages managed by the buddy system, which
+	 * is calculated as (reserved_pages includes pages allocated by the
+	 * bootmem allocator):
+	 *	managed_pages = present_pages - reserved_pages;
+	 *
+	 * So present_pages may be used by memory hotplug or memory power
+	 * management logic to figure out unmanaged pages by checking
+	 * (present_pages - managed_pages). And managed_pages should be used
+	 * by page allocator and vm scanner to calculate all kinds of watermarks
+	 * and thresholds.
+	 *
+	 * Locking rules:
+	 *
+	 * zone_start_pfn and spanned_pages are protected by span_seqlock.
+	 * It is a seqlock because it has to be read outside of zone->lock,
+	 * and it is done in the main allocator path.  But, it is written
+	 * quite infrequently.
+	 *
+	 * The span_seq lock is declared along with zone->lock because it is
 	 * frequently read in proximity to zone->lock.  It's good to
 	 * give them a chance of being in the same cacheline.
+	 *
+	 * Write access to present_pages and managed_pages at runtime should
+	 * be protected by lock_memory_hotplug()/unlock_memory_hotplug().
+	 * Any reader who can't tolerant drift of present_pages and
+	 * managed_pages should hold memory hotplug lock to get a stable value.
 	 */
-	unsigned long		spanned_pages;	/* total size, including holes */
-	unsigned long		present_pages;	/* amount of memory (excluding holes) */
+	unsigned long		spanned_pages;
+	unsigned long		present_pages;
+	unsigned long		managed_pages;
 
 	/*
 	 * rarely used fields:
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index ef9336c..02e0f6b 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -369,7 +369,7 @@
  *
  * If the rx_handler consider the skb should be ignored, it should return
  * RX_HANDLER_EXACT. The skb will only be delivered to protocol handlers that
- * are registred on exact device (ptype->dev == skb->dev).
+ * are registered on exact device (ptype->dev == skb->dev).
  *
  * If the rx_handler didn't changed skb->dev, but want the skb to be normally
  * delivered, it should return RX_HANDLER_PASS.
diff --git a/include/linux/nodemask.h b/include/linux/nodemask.h
index 7afc363..4e2cbfa 100644
--- a/include/linux/nodemask.h
+++ b/include/linux/nodemask.h
@@ -380,6 +380,11 @@
 #else
 	N_HIGH_MEMORY = N_NORMAL_MEMORY,
 #endif
+#ifdef CONFIG_MOVABLE_NODE
+	N_MEMORY,		/* The node has memory(regular, high, movable) */
+#else
+	N_MEMORY = N_HIGH_MEMORY,
+#endif
 	N_CPU,		/* The node has one or more cpus */
 	NR_NODE_STATES
 };
diff --git a/include/linux/omap-dma.h b/include/linux/omap-dma.h
index eb475a8..7af25a9 100644
--- a/include/linux/omap-dma.h
+++ b/include/linux/omap-dma.h
@@ -19,4 +19,370 @@
 }
 #endif
 
+/*
+ *  Legacy OMAP DMA handling defines and functions
+ *
+ *  NOTE: Do not use these any longer.
+ *
+ *  Use the generic dmaengine functions as defined in
+ *  include/linux/dmaengine.h.
+ *
+ *  Copyright (C) 2003 Nokia Corporation
+ *  Author: Juha Yrjölä <juha.yrjola@nokia.com>
+ *
+ */
+
+#include <linux/platform_device.h>
+
+#define INT_DMA_LCD			25
+
+#define OMAP1_DMA_TOUT_IRQ		(1 << 0)
+#define OMAP_DMA_DROP_IRQ		(1 << 1)
+#define OMAP_DMA_HALF_IRQ		(1 << 2)
+#define OMAP_DMA_FRAME_IRQ		(1 << 3)
+#define OMAP_DMA_LAST_IRQ		(1 << 4)
+#define OMAP_DMA_BLOCK_IRQ		(1 << 5)
+#define OMAP1_DMA_SYNC_IRQ		(1 << 6)
+#define OMAP2_DMA_PKT_IRQ		(1 << 7)
+#define OMAP2_DMA_TRANS_ERR_IRQ		(1 << 8)
+#define OMAP2_DMA_SECURE_ERR_IRQ	(1 << 9)
+#define OMAP2_DMA_SUPERVISOR_ERR_IRQ	(1 << 10)
+#define OMAP2_DMA_MISALIGNED_ERR_IRQ	(1 << 11)
+
+#define OMAP_DMA_CCR_EN			(1 << 7)
+#define OMAP_DMA_CCR_RD_ACTIVE		(1 << 9)
+#define OMAP_DMA_CCR_WR_ACTIVE		(1 << 10)
+#define OMAP_DMA_CCR_SEL_SRC_DST_SYNC	(1 << 24)
+#define OMAP_DMA_CCR_BUFFERING_DISABLE	(1 << 25)
+
+#define OMAP_DMA_DATA_TYPE_S8		0x00
+#define OMAP_DMA_DATA_TYPE_S16		0x01
+#define OMAP_DMA_DATA_TYPE_S32		0x02
+
+#define OMAP_DMA_SYNC_ELEMENT		0x00
+#define OMAP_DMA_SYNC_FRAME		0x01
+#define OMAP_DMA_SYNC_BLOCK		0x02
+#define OMAP_DMA_SYNC_PACKET		0x03
+
+#define OMAP_DMA_DST_SYNC_PREFETCH	0x02
+#define OMAP_DMA_SRC_SYNC		0x01
+#define OMAP_DMA_DST_SYNC		0x00
+
+#define OMAP_DMA_PORT_EMIFF		0x00
+#define OMAP_DMA_PORT_EMIFS		0x01
+#define OMAP_DMA_PORT_OCP_T1		0x02
+#define OMAP_DMA_PORT_TIPB		0x03
+#define OMAP_DMA_PORT_OCP_T2		0x04
+#define OMAP_DMA_PORT_MPUI		0x05
+
+#define OMAP_DMA_AMODE_CONSTANT		0x00
+#define OMAP_DMA_AMODE_POST_INC		0x01
+#define OMAP_DMA_AMODE_SINGLE_IDX	0x02
+#define OMAP_DMA_AMODE_DOUBLE_IDX	0x03
+
+#define DMA_DEFAULT_FIFO_DEPTH		0x10
+#define DMA_DEFAULT_ARB_RATE		0x01
+/* Pass THREAD_RESERVE ORed with THREAD_FIFO for tparams */
+#define DMA_THREAD_RESERVE_NORM		(0x00 << 12) /* Def */
+#define DMA_THREAD_RESERVE_ONET		(0x01 << 12)
+#define DMA_THREAD_RESERVE_TWOT		(0x02 << 12)
+#define DMA_THREAD_RESERVE_THREET	(0x03 << 12)
+#define DMA_THREAD_FIFO_NONE		(0x00 << 14) /* Def */
+#define DMA_THREAD_FIFO_75		(0x01 << 14)
+#define DMA_THREAD_FIFO_25		(0x02 << 14)
+#define DMA_THREAD_FIFO_50		(0x03 << 14)
+
+/* DMA4_OCP_SYSCONFIG bits */
+#define DMA_SYSCONFIG_MIDLEMODE_MASK		(3 << 12)
+#define DMA_SYSCONFIG_CLOCKACTIVITY_MASK	(3 << 8)
+#define DMA_SYSCONFIG_EMUFREE			(1 << 5)
+#define DMA_SYSCONFIG_SIDLEMODE_MASK		(3 << 3)
+#define DMA_SYSCONFIG_SOFTRESET			(1 << 2)
+#define DMA_SYSCONFIG_AUTOIDLE			(1 << 0)
+
+#define DMA_SYSCONFIG_MIDLEMODE(n)		((n) << 12)
+#define DMA_SYSCONFIG_SIDLEMODE(n)		((n) << 3)
+
+#define DMA_IDLEMODE_SMARTIDLE			0x2
+#define DMA_IDLEMODE_NO_IDLE			0x1
+#define DMA_IDLEMODE_FORCE_IDLE			0x0
+
+/* Chaining modes*/
+#ifndef CONFIG_ARCH_OMAP1
+#define OMAP_DMA_STATIC_CHAIN		0x1
+#define OMAP_DMA_DYNAMIC_CHAIN		0x2
+#define OMAP_DMA_CHAIN_ACTIVE		0x1
+#define OMAP_DMA_CHAIN_INACTIVE		0x0
 #endif
+
+#define DMA_CH_PRIO_HIGH		0x1
+#define DMA_CH_PRIO_LOW			0x0 /* Def */
+
+/* Errata handling */
+#define IS_DMA_ERRATA(id)		(errata & (id))
+#define SET_DMA_ERRATA(id)		(errata |= (id))
+
+#define DMA_ERRATA_IFRAME_BUFFERING	BIT(0x0)
+#define DMA_ERRATA_PARALLEL_CHANNELS	BIT(0x1)
+#define DMA_ERRATA_i378			BIT(0x2)
+#define DMA_ERRATA_i541			BIT(0x3)
+#define DMA_ERRATA_i88			BIT(0x4)
+#define DMA_ERRATA_3_3			BIT(0x5)
+#define DMA_ROMCODE_BUG			BIT(0x6)
+
+/* Attributes for OMAP DMA Contrller */
+#define DMA_LINKED_LCH			BIT(0x0)
+#define GLOBAL_PRIORITY			BIT(0x1)
+#define RESERVE_CHANNEL			BIT(0x2)
+#define IS_CSSA_32			BIT(0x3)
+#define IS_CDSA_32			BIT(0x4)
+#define IS_RW_PRIORITY			BIT(0x5)
+#define ENABLE_1510_MODE		BIT(0x6)
+#define SRC_PORT			BIT(0x7)
+#define DST_PORT			BIT(0x8)
+#define SRC_INDEX			BIT(0x9)
+#define DST_INDEX			BIT(0xa)
+#define IS_BURST_ONLY4			BIT(0xb)
+#define CLEAR_CSR_ON_READ		BIT(0xc)
+#define IS_WORD_16			BIT(0xd)
+#define ENABLE_16XX_MODE		BIT(0xe)
+#define HS_CHANNELS_RESERVED		BIT(0xf)
+
+/* Defines for DMA Capabilities */
+#define DMA_HAS_TRANSPARENT_CAPS	(0x1 << 18)
+#define DMA_HAS_CONSTANT_FILL_CAPS	(0x1 << 19)
+#define DMA_HAS_DESCRIPTOR_CAPS		(0x3 << 20)
+
+enum omap_reg_offsets {
+
+GCR,		GSCR,		GRST1,		HW_ID,
+PCH2_ID,	PCH0_ID,	PCH1_ID,	PCHG_ID,
+PCHD_ID,	CAPS_0,		CAPS_1,		CAPS_2,
+CAPS_3,		CAPS_4,		PCH2_SR,	PCH0_SR,
+PCH1_SR,	PCHD_SR,	REVISION,	IRQSTATUS_L0,
+IRQSTATUS_L1,	IRQSTATUS_L2,	IRQSTATUS_L3,	IRQENABLE_L0,
+IRQENABLE_L1,	IRQENABLE_L2,	IRQENABLE_L3,	SYSSTATUS,
+OCP_SYSCONFIG,
+
+/* omap1+ specific */
+CPC, CCR2, LCH_CTRL,
+
+/* Common registers for all omap's */
+CSDP,		CCR,		CICR,		CSR,
+CEN,		CFN,		CSFI,		CSEI,
+CSAC,		CDAC,		CDEI,
+CDFI,		CLNK_CTRL,
+
+/* Channel specific registers */
+CSSA,		CDSA,		COLOR,
+CCEN,		CCFN,
+
+/* omap3630 and omap4 specific */
+CDP,		CNDP,		CCDN,
+
+};
+
+enum omap_dma_burst_mode {
+	OMAP_DMA_DATA_BURST_DIS = 0,
+	OMAP_DMA_DATA_BURST_4,
+	OMAP_DMA_DATA_BURST_8,
+	OMAP_DMA_DATA_BURST_16,
+};
+
+enum end_type {
+	OMAP_DMA_LITTLE_ENDIAN = 0,
+	OMAP_DMA_BIG_ENDIAN
+};
+
+enum omap_dma_color_mode {
+	OMAP_DMA_COLOR_DIS = 0,
+	OMAP_DMA_CONSTANT_FILL,
+	OMAP_DMA_TRANSPARENT_COPY
+};
+
+enum omap_dma_write_mode {
+	OMAP_DMA_WRITE_NON_POSTED = 0,
+	OMAP_DMA_WRITE_POSTED,
+	OMAP_DMA_WRITE_LAST_NON_POSTED
+};
+
+enum omap_dma_channel_mode {
+	OMAP_DMA_LCH_2D = 0,
+	OMAP_DMA_LCH_G,
+	OMAP_DMA_LCH_P,
+	OMAP_DMA_LCH_PD
+};
+
+struct omap_dma_channel_params {
+	int data_type;		/* data type 8,16,32 */
+	int elem_count;		/* number of elements in a frame */
+	int frame_count;	/* number of frames in a element */
+
+	int src_port;		/* Only on OMAP1 REVISIT: Is this needed? */
+	int src_amode;		/* constant, post increment, indexed,
+					double indexed */
+	unsigned long src_start;	/* source address : physical */
+	int src_ei;		/* source element index */
+	int src_fi;		/* source frame index */
+
+	int dst_port;		/* Only on OMAP1 REVISIT: Is this needed? */
+	int dst_amode;		/* constant, post increment, indexed,
+					double indexed */
+	unsigned long dst_start;	/* source address : physical */
+	int dst_ei;		/* source element index */
+	int dst_fi;		/* source frame index */
+
+	int trigger;		/* trigger attached if the channel is
+					synchronized */
+	int sync_mode;		/* sycn on element, frame , block or packet */
+	int src_or_dst_synch;	/* source synch(1) or destination synch(0) */
+
+	int ie;			/* interrupt enabled */
+
+	unsigned char read_prio;/* read priority */
+	unsigned char write_prio;/* write priority */
+
+#ifndef CONFIG_ARCH_OMAP1
+	enum omap_dma_burst_mode burst_mode; /* Burst mode 4/8/16 words */
+#endif
+};
+
+struct omap_dma_lch {
+	int next_lch;
+	int dev_id;
+	u16 saved_csr;
+	u16 enabled_irqs;
+	const char *dev_name;
+	void (*callback)(int lch, u16 ch_status, void *data);
+	void *data;
+	long flags;
+	/* required for Dynamic chaining */
+	int prev_linked_ch;
+	int next_linked_ch;
+	int state;
+	int chain_id;
+	int status;
+};
+
+struct omap_dma_dev_attr {
+	u32 dev_caps;
+	u16 lch_count;
+	u16 chan_count;
+	struct omap_dma_lch *chan;
+};
+
+/* System DMA platform data structure */
+struct omap_system_dma_plat_info {
+	struct omap_dma_dev_attr *dma_attr;
+	u32 errata;
+	void (*disable_irq_lch)(int lch);
+	void (*show_dma_caps)(void);
+	void (*clear_lch_regs)(int lch);
+	void (*clear_dma)(int lch);
+	void (*dma_write)(u32 val, int reg, int lch);
+	u32 (*dma_read)(int reg, int lch);
+};
+
+#ifdef CONFIG_ARCH_OMAP2PLUS
+#define dma_omap2plus()	1
+#else
+#define dma_omap2plus()	0
+#endif
+#define dma_omap1()	(!dma_omap2plus())
+#define dma_omap15xx()	((dma_omap1() && (d->dev_caps & ENABLE_1510_MODE)))
+#define dma_omap16xx()	((dma_omap1() && (d->dev_caps & ENABLE_16XX_MODE)))
+
+extern void omap_set_dma_priority(int lch, int dst_port, int priority);
+extern int omap_request_dma(int dev_id, const char *dev_name,
+			void (*callback)(int lch, u16 ch_status, void *data),
+			void *data, int *dma_ch);
+extern void omap_enable_dma_irq(int ch, u16 irq_bits);
+extern void omap_disable_dma_irq(int ch, u16 irq_bits);
+extern void omap_free_dma(int ch);
+extern void omap_start_dma(int lch);
+extern void omap_stop_dma(int lch);
+extern void omap_set_dma_transfer_params(int lch, int data_type,
+					 int elem_count, int frame_count,
+					 int sync_mode,
+					 int dma_trigger, int src_or_dst_synch);
+extern void omap_set_dma_color_mode(int lch, enum omap_dma_color_mode mode,
+				    u32 color);
+extern void omap_set_dma_write_mode(int lch, enum omap_dma_write_mode mode);
+extern void omap_set_dma_channel_mode(int lch, enum omap_dma_channel_mode mode);
+
+extern void omap_set_dma_src_params(int lch, int src_port, int src_amode,
+				    unsigned long src_start,
+				    int src_ei, int src_fi);
+extern void omap_set_dma_src_index(int lch, int eidx, int fidx);
+extern void omap_set_dma_src_data_pack(int lch, int enable);
+extern void omap_set_dma_src_burst_mode(int lch,
+					enum omap_dma_burst_mode burst_mode);
+
+extern void omap_set_dma_dest_params(int lch, int dest_port, int dest_amode,
+				     unsigned long dest_start,
+				     int dst_ei, int dst_fi);
+extern void omap_set_dma_dest_index(int lch, int eidx, int fidx);
+extern void omap_set_dma_dest_data_pack(int lch, int enable);
+extern void omap_set_dma_dest_burst_mode(int lch,
+					 enum omap_dma_burst_mode burst_mode);
+
+extern void omap_set_dma_params(int lch,
+				struct omap_dma_channel_params *params);
+
+extern void omap_dma_link_lch(int lch_head, int lch_queue);
+extern void omap_dma_unlink_lch(int lch_head, int lch_queue);
+
+extern int omap_set_dma_callback(int lch,
+			void (*callback)(int lch, u16 ch_status, void *data),
+			void *data);
+extern dma_addr_t omap_get_dma_src_pos(int lch);
+extern dma_addr_t omap_get_dma_dst_pos(int lch);
+extern void omap_clear_dma(int lch);
+extern int omap_get_dma_active_status(int lch);
+extern int omap_dma_running(void);
+extern void omap_dma_set_global_params(int arb_rate, int max_fifo_depth,
+				       int tparams);
+extern int omap_dma_set_prio_lch(int lch, unsigned char read_prio,
+				 unsigned char write_prio);
+extern void omap_set_dma_dst_endian_type(int lch, enum end_type etype);
+extern void omap_set_dma_src_endian_type(int lch, enum end_type etype);
+extern int omap_get_dma_index(int lch, int *ei, int *fi);
+
+void omap_dma_global_context_save(void);
+void omap_dma_global_context_restore(void);
+
+extern void omap_dma_disable_irq(int lch);
+
+/* Chaining APIs */
+#ifndef CONFIG_ARCH_OMAP1
+extern int omap_request_dma_chain(int dev_id, const char *dev_name,
+				  void (*callback) (int lch, u16 ch_status,
+						    void *data),
+				  int *chain_id, int no_of_chans,
+				  int chain_mode,
+				  struct omap_dma_channel_params params);
+extern int omap_free_dma_chain(int chain_id);
+extern int omap_dma_chain_a_transfer(int chain_id, int src_start,
+				     int dest_start, int elem_count,
+				     int frame_count, void *callbk_data);
+extern int omap_start_dma_chain_transfers(int chain_id);
+extern int omap_stop_dma_chain_transfers(int chain_id);
+extern int omap_get_dma_chain_index(int chain_id, int *ei, int *fi);
+extern int omap_get_dma_chain_dst_pos(int chain_id);
+extern int omap_get_dma_chain_src_pos(int chain_id);
+
+extern int omap_modify_dma_chain_params(int chain_id,
+					struct omap_dma_channel_params params);
+extern int omap_dma_chain_status(int chain_id);
+#endif
+
+#if defined(CONFIG_ARCH_OMAP1) && defined(CONFIG_FB_OMAP)
+#include <mach/lcd_dma.h>
+#else
+static inline int omap_lcd_dma_running(void)
+{
+	return 0;
+}
+#endif
+
+#endif /* __LINUX_OMAP_DMA_H */
diff --git a/include/linux/pci.h b/include/linux/pci.h
index af82292..15472d6 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -333,6 +333,8 @@
 	};
 	struct pci_ats	*ats;	/* Address Translation Service */
 #endif
+	phys_addr_t rom; /* Physical address of ROM if it's not from the BAR */
+	size_t romlen; /* Length of ROM if it's not from the BAR */
 };
 
 static inline struct pci_dev *pci_physfn(struct pci_dev *dev)
@@ -538,6 +540,9 @@
 
 	/* Device driver is fully recovered and operational */
 	PCI_ERS_RESULT_RECOVERED = (__force pci_ers_result_t) 5,
+
+	/* No AER capabilities registered for the driver */
+	PCI_ERS_RESULT_NO_AER_DRIVER = (__force pci_ers_result_t) 6,
 };
 
 /* PCI bus error event callbacks */
@@ -573,6 +578,7 @@
 	int  (*resume_early) (struct pci_dev *dev);
 	int  (*resume) (struct pci_dev *dev);	                /* Device woken up */
 	void (*shutdown) (struct pci_dev *dev);
+	int (*sriov_configure) (struct pci_dev *dev, int num_vfs); /* PF pdev */
 	const struct pci_error_handlers *err_handler;
 	struct device_driver	driver;
 	struct pci_dynids dynids;
@@ -726,6 +732,8 @@
 extern void pci_dev_put(struct pci_dev *dev);
 extern void pci_remove_bus(struct pci_bus *b);
 extern void pci_stop_and_remove_bus_device(struct pci_dev *dev);
+void pci_stop_root_bus(struct pci_bus *bus);
+void pci_remove_root_bus(struct pci_bus *bus);
 void pci_setup_cardbus(struct pci_bus *bus);
 extern void pci_sort_breadthfirst(void);
 #define dev_is_pci(d) ((d)->bus == &pci_bus_type)
@@ -970,6 +978,7 @@
 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 pci_assign_unassigned_bus_resources(struct pci_bus *bus);
 void pdev_enable_device(struct pci_dev *);
 int pci_enable_resources(struct pci_dev *, int mask);
 void pci_fixup_irqs(u8 (*)(struct pci_dev *, u8 *),
@@ -1604,6 +1613,7 @@
 void pcibios_set_master(struct pci_dev *dev);
 int pcibios_set_pcie_reset_state(struct pci_dev *dev,
 				 enum pcie_reset_state state);
+int pcibios_add_device(struct pci_dev *dev);
 
 #ifdef CONFIG_PCI_MMCONFIG
 extern void __init pci_mmcfg_early_init(void);
@@ -1613,7 +1623,7 @@
 static inline void pci_mmcfg_late_init(void) { }
 #endif
 
-int pci_ext_cfg_avail(struct pci_dev *dev);
+int pci_ext_cfg_avail(void);
 
 void __iomem *pci_ioremap_bar(struct pci_dev *pdev, int bar);
 
@@ -1622,6 +1632,8 @@
 extern void pci_disable_sriov(struct pci_dev *dev);
 extern irqreturn_t pci_sriov_migration(struct pci_dev *dev);
 extern int pci_num_vf(struct pci_dev *dev);
+extern int pci_sriov_set_totalvfs(struct pci_dev *dev, u16 numvfs);
+extern int pci_sriov_get_totalvfs(struct pci_dev *dev);
 #else
 static inline int pci_enable_sriov(struct pci_dev *dev, int nr_virtfn)
 {
@@ -1638,6 +1650,14 @@
 {
 	return 0;
 }
+static inline int pci_sriov_set_totalvfs(struct pci_dev *dev, u16 numvfs)
+{
+	return 0;
+}
+static inline int pci_sriov_get_totalvfs(struct pci_dev *dev)
+{
+	return 0;
+}
 #endif
 
 #if defined(CONFIG_HOTPLUG_PCI) || defined(CONFIG_HOTPLUG_PCI_MODULE)
diff --git a/include/linux/platform_data/asoc-s3c.h b/include/linux/platform_data/asoc-s3c.h
index aa9875f..8827259 100644
--- a/include/linux/platform_data/asoc-s3c.h
+++ b/include/linux/platform_data/asoc-s3c.h
@@ -38,12 +38,6 @@
 #define QUIRK_NEED_RSTCLR	(1 << 3)
 	/* Quirks of the I2S controller */
 	u32 quirks;
-
-	/*
-	 * Array of clock names that can be used to generate I2S signals.
-	 * Also corresponds to clocks of I2SMOD[10]
-	 */
-	const char **src_clk;
 	dma_addr_t idma_addr;
 };
 
diff --git a/arch/arm/plat-nomadik/include/plat/mtu.h b/include/linux/platform_data/clocksource-nomadik-mtu.h
similarity index 71%
rename from arch/arm/plat-nomadik/include/plat/mtu.h
rename to include/linux/platform_data/clocksource-nomadik-mtu.h
index 582641f..8008897 100644
--- a/arch/arm/plat-nomadik/include/plat/mtu.h
+++ b/include/linux/platform_data/clocksource-nomadik-mtu.h
@@ -1,7 +1,7 @@
 #ifndef __PLAT_MTU_H
 #define __PLAT_MTU_H
 
-void nmdk_timer_init(void __iomem *base);
+void nmdk_timer_init(void __iomem *base, int irq);
 void nmdk_clkevt_reset(void);
 void nmdk_clksrc_reset(void);
 
diff --git a/include/linux/platform_data/crypto-ux500.h b/include/linux/platform_data/crypto-ux500.h
index 5b2d081..94df96d 100644
--- a/include/linux/platform_data/crypto-ux500.h
+++ b/include/linux/platform_data/crypto-ux500.h
@@ -7,7 +7,7 @@
 #ifndef _CRYPTO_UX500_H
 #define _CRYPTO_UX500_H
 #include <linux/dmaengine.h>
-#include <plat/ste_dma40.h>
+#include <linux/platform_data/dma-ste-dma40.h>
 
 struct hash_platform_data {
 	void *mem_to_engine;
diff --git a/include/linux/platform_data/davinci_asp.h b/include/linux/platform_data/davinci_asp.h
index d0c5825..8db5ae0 100644
--- a/include/linux/platform_data/davinci_asp.h
+++ b/include/linux/platform_data/davinci_asp.h
@@ -16,12 +16,13 @@
 #ifndef __DAVINCI_ASP_H
 #define __DAVINCI_ASP_H
 
+#include <linux/genalloc.h>
+
 struct snd_platform_data {
 	u32 tx_dma_offset;
 	u32 rx_dma_offset;
 	int asp_chan_q;	/* event queue number for ASP channel */
 	int ram_chan_q;	/* event queue number for RAM channel */
-	unsigned int codec_fmt;
 	/*
 	 * Allowing this is more efficient and eliminates left and right swaps
 	 * caused by underruns, but will swap the left and right channels
@@ -30,6 +31,7 @@
 	unsigned enable_channel_combine:1;
 	unsigned sram_size_playback;
 	unsigned sram_size_capture;
+	struct gen_pool *sram_pool;
 
 	/*
 	 * If McBSP peripheral gets the clock from an external pin,
diff --git a/arch/arm/plat-nomadik/include/plat/ste_dma40.h b/include/linux/platform_data/dma-ste-dma40.h
similarity index 100%
rename from arch/arm/plat-nomadik/include/plat/ste_dma40.h
rename to include/linux/platform_data/dma-ste-dma40.h
diff --git a/include/linux/platform_data/omap-twl4030.h b/include/linux/platform_data/omap-twl4030.h
index c7bef78..ee60ef7 100644
--- a/include/linux/platform_data/omap-twl4030.h
+++ b/include/linux/platform_data/omap-twl4030.h
@@ -25,8 +25,34 @@
 #ifndef _OMAP_TWL4030_H_
 #define _OMAP_TWL4030_H_
 
+/* To select if only one channel is connected in a stereo port */
+#define OMAP_TWL4030_LEFT	(1 << 0)
+#define OMAP_TWL4030_RIGHT	(1 << 1)
+
 struct omap_tw4030_pdata {
 	const char *card_name;
+	/* Voice port is connected to McBSP3 */
+	bool voice_connected;
+
+	/* The driver will parse the connection flags if this flag is set */
+	bool	custom_routing;
+	/* Flags to indicate connected audio ports. */
+	u8	has_hs;
+	u8	has_hf;
+	u8	has_predriv;
+	u8	has_carkit;
+	bool	has_ear;
+
+	bool	has_mainmic;
+	bool	has_submic;
+	bool	has_hsmic;
+	bool	has_carkitmic;
+	bool	has_digimic0;
+	bool	has_digimic1;
+	u8	has_linein;
+
+	/* Jack detect GPIO or  <= 0 if it is not implemented */
+	int jack_detect;
 };
 
 #endif /* _OMAP_TWL4030_H_ */
diff --git a/include/linux/power/smartreflex.h b/include/linux/power/smartreflex.h
index 4a496eb..c0f44c2 100644
--- a/include/linux/power/smartreflex.h
+++ b/include/linux/power/smartreflex.h
@@ -260,8 +260,13 @@
  *
  * @name:		instance name
  * @ip_type:		Smartreflex IP type.
- * @senp_mod:		SENPENABLE value for the sr
- * @senn_mod:		SENNENABLE value for sr
+ * @senp_mod:		SENPENABLE value of the sr CONFIG register
+ * @senn_mod:		SENNENABLE value for sr CONFIG register
+ * @err_weight		ERRWEIGHT value of the sr ERRCONFIG register
+ * @err_maxlimit	ERRMAXLIMIT value of the sr ERRCONFIG register
+ * @accum_data		ACCUMDATA value of the sr CONFIG register
+ * @senn_avgweight	SENNAVGWEIGHT value of the sr AVGWEIGHT register
+ * @senp_avgweight	SENPAVGWEIGHT value of the sr AVGWEIGHT register
  * @nvalue_count:	Number of distinct nvalues in the nvalue table
  * @enable_on_init:	whether this sr module needs to enabled at
  *			boot up or not.
@@ -274,6 +279,11 @@
 	int				ip_type;
 	u32				senp_mod;
 	u32				senn_mod;
+	u32				err_weight;
+	u32				err_maxlimit;
+	u32				accum_data;
+	u32				senn_avgweight;
+	u32				senp_avgweight;
 	int				nvalue_count;
 	bool				enable_on_init;
 	struct omap_sr_nvalue_table	*nvalue_table;
diff --git a/include/linux/regulator/consumer.h b/include/linux/regulator/consumer.h
index c43cd35..7bc732c 100644
--- a/include/linux/regulator/consumer.h
+++ b/include/linux/regulator/consumer.h
@@ -160,6 +160,7 @@
 void regulator_bulk_free(int num_consumers,
 			 struct regulator_bulk_data *consumers);
 
+int regulator_can_change_voltage(struct regulator *regulator);
 int regulator_count_voltages(struct regulator *regulator);
 int regulator_list_voltage(struct regulator *regulator, unsigned selector);
 int regulator_is_supported_voltage(struct regulator *regulator,
@@ -358,6 +359,10 @@
 {
 }
 
+static inline int regulator_count_voltages(struct regulator *regulator)
+{
+	return 0;
+}
 #endif
 
 static inline int regulator_set_voltage_tol(struct regulator *regulator,
@@ -367,4 +372,12 @@
 				     new_uV - tol_uV, new_uV + tol_uV);
 }
 
+static inline int regulator_is_supported_voltage_tol(struct regulator *regulator,
+						     int target_uV, int tol_uV)
+{
+	return regulator_is_supported_voltage(regulator,
+					      target_uV - tol_uV,
+					      target_uV + tol_uV);
+}
+
 #endif
diff --git a/include/linux/regulator/driver.h b/include/linux/regulator/driver.h
index 7932a3b..d10bb0f 100644
--- a/include/linux/regulator/driver.h
+++ b/include/linux/regulator/driver.h
@@ -181,10 +181,13 @@
  * @type: Indicates if the regulator is a voltage or current regulator.
  * @owner: Module providing the regulator, used for refcounting.
  *
+ * @continuous_voltage_range: Indicates if the regulator can set any
+ *                            voltage within constrains range.
  * @n_voltages: Number of selectors available for ops.list_voltage().
  *
  * @min_uV: Voltage given by the lowest selector (if linear mapping)
  * @uV_step: Voltage increase with each selector (if linear mapping)
+ * @linear_min_sel: Minimal selector for starting linear mapping
  * @ramp_delay: Time to settle down after voltage change (unit: uV/us)
  * @volt_table: Voltage mapping table (if table based mapping)
  *
@@ -199,6 +202,7 @@
 	const char *name;
 	const char *supply_name;
 	int id;
+	bool continuous_voltage_range;
 	unsigned n_voltages;
 	struct regulator_ops *ops;
 	int irq;
@@ -207,6 +211,7 @@
 
 	unsigned int min_uV;
 	unsigned int uV_step;
+	unsigned int linear_min_sel;
 	unsigned int ramp_delay;
 
 	const unsigned int *volt_table;
diff --git a/include/linux/regulator/max8973-regulator.h b/include/linux/regulator/max8973-regulator.h
new file mode 100644
index 0000000..f8acc05
--- /dev/null
+++ b/include/linux/regulator/max8973-regulator.h
@@ -0,0 +1,72 @@
+/*
+ * max8973-regulator.h -- MAXIM 8973 regulator
+ *
+ * Interface for regulator driver for MAXIM 8973 DC-DC step-down
+ * switching regulator.
+ *
+ * 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_MAX8973_H
+#define __LINUX_REGULATOR_MAX8973_H
+
+/*
+ * Control flags for configuration of the device.
+ * Client need to pass this information with ORed
+ */
+#define MAX8973_CONTROL_REMOTE_SENSE_ENABLE			0x00000001
+#define MAX8973_CONTROL_FALLING_SLEW_RATE_ENABLE		0x00000002
+#define MAX8973_CONTROL_OUTPUT_ACTIVE_DISCH_ENABLE		0x00000004
+#define MAX8973_CONTROL_BIAS_ENABLE				0x00000008
+#define MAX8973_CONTROL_PULL_DOWN_ENABLE			0x00000010
+#define MAX8973_CONTROL_FREQ_SHIFT_9PER_ENABLE			0x00000020
+
+#define MAX8973_CONTROL_CLKADV_TRIP_DISABLED			0x00000000
+#define MAX8973_CONTROL_CLKADV_TRIP_75mV_PER_US			0x00010000
+#define MAX8973_CONTROL_CLKADV_TRIP_150mV_PER_US		0x00020000
+#define MAX8973_CONTROL_CLKADV_TRIP_75mV_PER_US_HIST_DIS	0x00030000
+
+#define MAX8973_CONTROL_INDUCTOR_VALUE_NOMINAL			0x00000000
+#define MAX8973_CONTROL_INDUCTOR_VALUE_MINUS_30_PER		0x00100000
+#define MAX8973_CONTROL_INDUCTOR_VALUE_PLUS_30_PER		0x00200000
+#define MAX8973_CONTROL_INDUCTOR_VALUE_PLUS_60_PER		0x00300000
+
+/*
+ * struct max8973_regulator_platform_data - max8973 regulator platform data.
+ *
+ * @reg_init_data: The regulator init data.
+ * @control_flags: Control flags which are ORed value of above flags to
+ *		configure device.
+ * @enable_ext_control: Enable the voltage enable/disable through external
+ *		control signal from EN input pin. If it is false then
+ *		voltage output will be enabled/disabled through EN bit of
+ *		device register.
+ * @dvs_gpio: GPIO for dvs. It should be -1 if this is tied with fixed logic.
+ * @dvs_def_state: Default state of dvs. 1 if it is high else 0.
+ */
+struct max8973_regulator_platform_data {
+	struct regulator_init_data *reg_init_data;
+	unsigned long control_flags;
+	bool enable_ext_control;
+	int dvs_gpio;
+	unsigned dvs_def_state:1;
+};
+
+#endif /* __LINUX_REGULATOR_MAX8973_H */
diff --git a/include/linux/regulator/tps51632-regulator.h b/include/linux/regulator/tps51632-regulator.h
new file mode 100644
index 0000000..d00841e
--- /dev/null
+++ b/include/linux/regulator/tps51632-regulator.h
@@ -0,0 +1,47 @@
+/*
+ * tps51632-regulator.h -- TPS51632 regulator
+ *
+ * Interface for regulator driver for TPS51632 3-2-1 Phase D-Cap Step Down
+ * Driverless Controller with serial VID control and DVFS.
+ *
+ * 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_TPS51632_H
+#define __LINUX_REGULATOR_TPS51632_H
+
+/*
+ * struct tps51632_regulator_platform_data - tps51632 regulator platform data.
+ *
+ * @reg_init_data: The regulator init data.
+ * @enable_pwm_dvfs: Enable PWM DVFS or not.
+ * @dvfs_step_20mV: Step for DVFS is 20mV or 10mV.
+ * @max_voltage_uV: Maximum possible voltage in PWM-DVFS mode.
+ * @base_voltage_uV: Base voltage when PWM-DVFS enabled.
+ */
+struct tps51632_regulator_platform_data {
+	struct regulator_init_data *reg_init_data;
+	bool enable_pwm_dvfs;
+	bool dvfs_step_20mV;
+	int max_voltage_uV;
+	int base_voltage_uV;
+};
+
+#endif /* __LINUX_REGULATOR_TPS51632_H */
diff --git a/include/linux/regulator/tps65090-regulator.h b/include/linux/regulator/tps65090-regulator.h
deleted file mode 100644
index 0fa04b6..0000000
--- a/include/linux/regulator/tps65090-regulator.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Regulator driver interface for TI TPS65090 PMIC family
- *
- * 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 __REGULATOR_TPS65090_H
-#define __REGULATOR_TPS65090_H
-
-#include <linux/regulator/machine.h>
-
-#define tps65090_rails(_name) "tps65090_"#_name
-
-enum {
-	TPS65090_ID_DCDC1,
-	TPS65090_ID_DCDC2,
-	TPS65090_ID_DCDC3,
-	TPS65090_ID_FET1,
-	TPS65090_ID_FET2,
-	TPS65090_ID_FET3,
-	TPS65090_ID_FET4,
-	TPS65090_ID_FET5,
-	TPS65090_ID_FET6,
-	TPS65090_ID_FET7,
-};
-
-/*
- * struct tps65090_regulator_platform_data
- *
- * @regulator: The regulator init data.
- * @slew_rate_uV_per_us: Slew rate microvolt per microsec.
- */
-
-struct tps65090_regulator_platform_data {
-	struct regulator_init_data regulator;
-};
-
-#endif	/* __REGULATOR_TPS65090_H */
diff --git a/include/linux/res_counter.h b/include/linux/res_counter.h
index 7d7fbe2..6f54e40f 100644
--- a/include/linux/res_counter.h
+++ b/include/linux/res_counter.h
@@ -74,14 +74,9 @@
 		const char __user *buf, size_t nbytes, loff_t *pos,
 		int (*read_strategy)(unsigned long long val, char *s));
 
-typedef int (*write_strategy_fn)(const char *buf, unsigned long long *val);
-
 int res_counter_memparse_write_strategy(const char *buf,
 					unsigned long long *res);
 
-int res_counter_write(struct res_counter *counter, int member,
-		      const char *buffer, write_strategy_fn write_strategy);
-
 /*
  * the field descriptors. one for each member of res_counter
  */
diff --git a/include/linux/stmmac.h b/include/linux/stmmac.h
index de5b2f8..c1b3ed3 100644
--- a/include/linux/stmmac.h
+++ b/include/linux/stmmac.h
@@ -61,7 +61,7 @@
 #define STMMAC_CSR_I_16		0xE	/* clk_csr_i/16 */
 #define STMMAC_CSR_I_18		0xF	/* clk_csr_i/18 */
 
-/* AXI DMA Burst length suported */
+/* AXI DMA Burst length supported */
 #define DMA_AXI_BLEN_4		(1 << 1)
 #define DMA_AXI_BLEN_8		(1 << 2)
 #define DMA_AXI_BLEN_16		(1 << 3)
diff --git a/include/linux/vgaarb.h b/include/linux/vgaarb.h
index 0ee42d9..2c02f3a 100644
--- a/include/linux/vgaarb.h
+++ b/include/linux/vgaarb.h
@@ -78,7 +78,7 @@
  *     This function acquires VGA resources for the given
  *     card and mark those resources locked. If the resource requested
  *     are "normal" (and not legacy) resources, the arbiter will first check
- *     wether the card is doing legacy decoding for that type of resource. If
+ *     whether the card is doing legacy decoding for that type of resource. If
  *     yes, the lock is "converted" into a legacy resource lock.
  *     The arbiter will first look for all VGA cards that might conflict
  *     and disable their IOs and/or Memory access, including VGA forwarding
@@ -89,7 +89,7 @@
  *     This function will block if some conflicting card is already locking
  *     one of the required resources (or any resource on a different bus
  *     segment, since P2P bridges don't differenciate VGA memory and IO
- *     afaik). You can indicate wether this blocking should be interruptible
+ *     afaik). You can indicate whether this blocking should be interruptible
  *     by a signal (for userland interface) or not.
  *     Must not be called at interrupt time or in atomic context.
  *     If the card already owns the resources, the function succeeds.
diff --git a/include/linux/vm_event_item.h b/include/linux/vm_event_item.h
index 3d31145..fe786f0 100644
--- a/include/linux/vm_event_item.h
+++ b/include/linux/vm_event_item.h
@@ -58,6 +58,8 @@
 		THP_COLLAPSE_ALLOC,
 		THP_COLLAPSE_ALLOC_FAILED,
 		THP_SPLIT,
+		THP_ZERO_PAGE_ALLOC,
+		THP_ZERO_PAGE_ALLOC_FAILED,
 #endif
 		NR_VM_EVENT_ITEMS
 };
diff --git a/include/linux/watchdog.h b/include/linux/watchdog.h
index b7f45d4..87490ac 100644
--- a/include/linux/watchdog.h
+++ b/include/linux/watchdog.h
@@ -105,7 +105,7 @@
 #define WATCHDOG_NOWAYOUT_INIT_STATUS	0
 #endif
 
-/* Use the following function to check wether or not the watchdog is active */
+/* Use the following function to check whether or not the watchdog is active */
 static inline bool watchdog_active(struct watchdog_device *wdd)
 {
 	return test_bit(WDOG_ACTIVE, &wdd->status);
diff --git a/include/net/irda/irlmp.h b/include/net/irda/irlmp.h
index fff11b7..591f786 100644
--- a/include/net/irda/irlmp.h
+++ b/include/net/irda/irlmp.h
@@ -134,7 +134,7 @@
 } CACHE_ENTRY;
 
 /*
- *  Information about each registred IrLAP layer
+ *  Information about each registered IrLAP layer
  */
 struct lap_cb {
 	irda_queue_t queue; /* Must be first */
diff --git a/include/net/sock.h b/include/net/sock.h
index 0a9a01a..93a6745 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -231,7 +231,7 @@
   *	@sk_sndbuf: size of send buffer in bytes
   *	@sk_flags: %SO_LINGER (l_onoff), %SO_BROADCAST, %SO_KEEPALIVE,
   *		   %SO_OOBINLINE settings, %SO_TIMESTAMPING settings
-  *	@sk_no_check: %SO_NO_CHECK setting, wether or not checkup packets
+  *	@sk_no_check: %SO_NO_CHECK setting, whether or not checkup packets
   *	@sk_route_caps: route capabilities (e.g. %NETIF_F_TSO)
   *	@sk_route_nocaps: forbidden route capabilities (e.g NETIF_F_GSO_MASK)
   *	@sk_gso_type: GSO type (e.g. %SKB_GSO_TCPV4)
diff --git a/include/sound/Kbuild b/include/sound/Kbuild
index 6df30ed..e69de29 100644
--- a/include/sound/Kbuild
+++ b/include/sound/Kbuild
@@ -1,10 +0,0 @@
-header-y += asequencer.h
-header-y += asound.h
-header-y += asound_fm.h
-header-y += emu10k1.h
-header-y += hdsp.h
-header-y += hdspm.h
-header-y += sb16_csp.h
-header-y += sfnt_info.h
-header-y += compress_params.h
-header-y += compress_offload.h
diff --git a/include/sound/asequencer.h b/include/sound/asequencer.h
index 1505e6d..75935ce 100644
--- a/include/sound/asequencer.h
+++ b/include/sound/asequencer.h
@@ -22,294 +22,9 @@
 #ifndef __SOUND_ASEQUENCER_H
 #define __SOUND_ASEQUENCER_H
 
-#ifdef __KERNEL__
 #include <linux/ioctl.h>
 #include <sound/asound.h>
-#endif
-
-/** version of the sequencer */
-#define SNDRV_SEQ_VERSION SNDRV_PROTOCOL_VERSION (1, 0, 1)
-
-/**
- * definition of sequencer event types
- */
-
-/** system messages
- * event data type = #snd_seq_result
- */
-#define SNDRV_SEQ_EVENT_SYSTEM		0
-#define SNDRV_SEQ_EVENT_RESULT		1
-
-/** note messages (channel specific)
- * event data type = #snd_seq_ev_note
- */
-#define SNDRV_SEQ_EVENT_NOTE		5
-#define SNDRV_SEQ_EVENT_NOTEON		6
-#define SNDRV_SEQ_EVENT_NOTEOFF		7
-#define SNDRV_SEQ_EVENT_KEYPRESS	8
-	
-/** control messages (channel specific)
- * event data type = #snd_seq_ev_ctrl
- */
-#define SNDRV_SEQ_EVENT_CONTROLLER	10
-#define SNDRV_SEQ_EVENT_PGMCHANGE	11
-#define SNDRV_SEQ_EVENT_CHANPRESS	12
-#define SNDRV_SEQ_EVENT_PITCHBEND	13	/**< from -8192 to 8191 */
-#define SNDRV_SEQ_EVENT_CONTROL14	14	/**< 14 bit controller value */
-#define SNDRV_SEQ_EVENT_NONREGPARAM	15	/**< 14 bit NRPN address + 14 bit unsigned value */
-#define SNDRV_SEQ_EVENT_REGPARAM	16	/**< 14 bit RPN address + 14 bit unsigned value */
-
-/** synchronisation messages
- * event data type = #snd_seq_ev_ctrl
- */
-#define SNDRV_SEQ_EVENT_SONGPOS		20	/* Song Position Pointer with LSB and MSB values */
-#define SNDRV_SEQ_EVENT_SONGSEL		21	/* Song Select with song ID number */
-#define SNDRV_SEQ_EVENT_QFRAME		22	/* midi time code quarter frame */
-#define SNDRV_SEQ_EVENT_TIMESIGN	23	/* SMF Time Signature event */
-#define SNDRV_SEQ_EVENT_KEYSIGN		24	/* SMF Key Signature event */
-	        
-/** timer messages
- * event data type = snd_seq_ev_queue_control
- */
-#define SNDRV_SEQ_EVENT_START		30	/* midi Real Time Start message */
-#define SNDRV_SEQ_EVENT_CONTINUE	31	/* midi Real Time Continue message */
-#define SNDRV_SEQ_EVENT_STOP		32	/* midi Real Time Stop message */	
-#define	SNDRV_SEQ_EVENT_SETPOS_TICK	33	/* set tick queue position */
-#define SNDRV_SEQ_EVENT_SETPOS_TIME	34	/* set realtime queue position */
-#define SNDRV_SEQ_EVENT_TEMPO		35	/* (SMF) Tempo event */
-#define SNDRV_SEQ_EVENT_CLOCK		36	/* midi Real Time Clock message */
-#define SNDRV_SEQ_EVENT_TICK		37	/* midi Real Time Tick message */
-#define SNDRV_SEQ_EVENT_QUEUE_SKEW	38	/* skew queue tempo */
-
-/** others
- * event data type = none
- */
-#define SNDRV_SEQ_EVENT_TUNE_REQUEST	40	/* tune request */
-#define SNDRV_SEQ_EVENT_RESET		41	/* reset to power-on state */
-#define SNDRV_SEQ_EVENT_SENSING		42	/* "active sensing" event */
-
-/** echo back, kernel private messages
- * event data type = any type
- */
-#define SNDRV_SEQ_EVENT_ECHO		50	/* echo event */
-#define SNDRV_SEQ_EVENT_OSS		51	/* OSS raw event */
-
-/** system status messages (broadcast for subscribers)
- * event data type = snd_seq_addr
- */
-#define SNDRV_SEQ_EVENT_CLIENT_START	60	/* new client has connected */
-#define SNDRV_SEQ_EVENT_CLIENT_EXIT	61	/* client has left the system */
-#define SNDRV_SEQ_EVENT_CLIENT_CHANGE	62	/* client status/info has changed */
-#define SNDRV_SEQ_EVENT_PORT_START	63	/* new port was created */
-#define SNDRV_SEQ_EVENT_PORT_EXIT	64	/* port was deleted from system */
-#define SNDRV_SEQ_EVENT_PORT_CHANGE	65	/* port status/info has changed */
-
-/** port connection changes
- * event data type = snd_seq_connect
- */
-#define SNDRV_SEQ_EVENT_PORT_SUBSCRIBED	66	/* ports connected */
-#define SNDRV_SEQ_EVENT_PORT_UNSUBSCRIBED 67	/* ports disconnected */
-
-/* 70-89:  synthesizer events - obsoleted */
-
-/** user-defined events with fixed length
- * event data type = any
- */
-#define SNDRV_SEQ_EVENT_USR0		90
-#define SNDRV_SEQ_EVENT_USR1		91
-#define SNDRV_SEQ_EVENT_USR2		92
-#define SNDRV_SEQ_EVENT_USR3		93
-#define SNDRV_SEQ_EVENT_USR4		94
-#define SNDRV_SEQ_EVENT_USR5		95
-#define SNDRV_SEQ_EVENT_USR6		96
-#define SNDRV_SEQ_EVENT_USR7		97
-#define SNDRV_SEQ_EVENT_USR8		98
-#define SNDRV_SEQ_EVENT_USR9		99
-
-/* 100-118: instrument layer - obsoleted */
-/* 119-129: reserved */
-
-/* 130-139: variable length events
- * event data type = snd_seq_ev_ext
- * (SNDRV_SEQ_EVENT_LENGTH_VARIABLE must be set)
- */
-#define SNDRV_SEQ_EVENT_SYSEX		130	/* system exclusive data (variable length) */
-#define SNDRV_SEQ_EVENT_BOUNCE		131	/* error event */
-/* 132-134: reserved */
-#define SNDRV_SEQ_EVENT_USR_VAR0	135
-#define SNDRV_SEQ_EVENT_USR_VAR1	136
-#define SNDRV_SEQ_EVENT_USR_VAR2	137
-#define SNDRV_SEQ_EVENT_USR_VAR3	138
-#define SNDRV_SEQ_EVENT_USR_VAR4	139
-
-/* 150-151: kernel events with quote - DO NOT use in user clients */
-#define SNDRV_SEQ_EVENT_KERNEL_ERROR	150
-#define SNDRV_SEQ_EVENT_KERNEL_QUOTE	151	/* obsolete */
-
-/* 152-191: reserved */
-
-/* 192-254: hardware specific events */
-
-/* 255: special event */
-#define SNDRV_SEQ_EVENT_NONE		255
-
-
-typedef unsigned char snd_seq_event_type_t;
-
-/** event address */
-struct snd_seq_addr {
-	unsigned char client;	/**< Client number:         0..255, 255 = broadcast to all clients */
-	unsigned char port;	/**< Port within client:    0..255, 255 = broadcast to all ports */
-};
-
-/** port connection */
-struct snd_seq_connect {
-	struct snd_seq_addr sender;
-	struct snd_seq_addr dest;
-};
-
-
-#define SNDRV_SEQ_ADDRESS_UNKNOWN	253	/* unknown source */
-#define SNDRV_SEQ_ADDRESS_SUBSCRIBERS	254	/* send event to all subscribed ports */
-#define SNDRV_SEQ_ADDRESS_BROADCAST	255	/* send event to all queues/clients/ports/channels */
-#define SNDRV_SEQ_QUEUE_DIRECT		253	/* direct dispatch */
-
-	/* event mode flag - NOTE: only 8 bits available! */
-#define SNDRV_SEQ_TIME_STAMP_TICK	(0<<0) /* timestamp in clock ticks */
-#define SNDRV_SEQ_TIME_STAMP_REAL	(1<<0) /* timestamp in real time */
-#define SNDRV_SEQ_TIME_STAMP_MASK	(1<<0)
-
-#define SNDRV_SEQ_TIME_MODE_ABS		(0<<1)	/* absolute timestamp */
-#define SNDRV_SEQ_TIME_MODE_REL		(1<<1)	/* relative to current time */
-#define SNDRV_SEQ_TIME_MODE_MASK	(1<<1)
-
-#define SNDRV_SEQ_EVENT_LENGTH_FIXED	(0<<2)	/* fixed event size */
-#define SNDRV_SEQ_EVENT_LENGTH_VARIABLE	(1<<2)	/* variable event size */
-#define SNDRV_SEQ_EVENT_LENGTH_VARUSR	(2<<2)	/* variable event size - user memory space */
-#define SNDRV_SEQ_EVENT_LENGTH_MASK	(3<<2)
-
-#define SNDRV_SEQ_PRIORITY_NORMAL	(0<<4)	/* normal priority */
-#define SNDRV_SEQ_PRIORITY_HIGH		(1<<4)	/* event should be processed before others */
-#define SNDRV_SEQ_PRIORITY_MASK		(1<<4)
-
-
-	/* note event */
-struct snd_seq_ev_note {
-	unsigned char channel;
-	unsigned char note;
-	unsigned char velocity;
-	unsigned char off_velocity;	/* only for SNDRV_SEQ_EVENT_NOTE */
-	unsigned int duration;		/* only for SNDRV_SEQ_EVENT_NOTE */
-};
-
-	/* controller event */
-struct snd_seq_ev_ctrl {
-	unsigned char channel;
-	unsigned char unused1, unused2, unused3;	/* pad */
-	unsigned int param;
-	signed int value;
-};
-
-	/* generic set of bytes (12x8 bit) */
-struct snd_seq_ev_raw8 {
-	unsigned char d[12];	/* 8 bit value */
-};
-
-	/* generic set of integers (3x32 bit) */
-struct snd_seq_ev_raw32 {
-	unsigned int d[3];	/* 32 bit value */
-};
-
-	/* external stored data */
-struct snd_seq_ev_ext {
-	unsigned int len;	/* length of data */
-	void *ptr;		/* pointer to data (note: maybe 64-bit) */
-} __attribute__((packed));
-
-struct snd_seq_result {
-	int event;		/* processed event type */
-	int result;
-};
-
-
-struct snd_seq_real_time {
-	unsigned int tv_sec;	/* seconds */
-	unsigned int tv_nsec;	/* nanoseconds */
-};
-
-typedef unsigned int snd_seq_tick_time_t;	/* midi ticks */
-
-union snd_seq_timestamp {
-	snd_seq_tick_time_t tick;
-	struct snd_seq_real_time time;
-};
-
-struct snd_seq_queue_skew {
-	unsigned int value;
-	unsigned int base;
-};
-
-	/* queue timer control */
-struct snd_seq_ev_queue_control {
-	unsigned char queue;			/* affected queue */
-	unsigned char pad[3];			/* reserved */
-	union {
-		signed int value;		/* affected value (e.g. tempo) */
-		union snd_seq_timestamp time;	/* time */
-		unsigned int position;		/* sync position */
-		struct snd_seq_queue_skew skew;
-		unsigned int d32[2];
-		unsigned char d8[8];
-	} param;
-};
-
-	/* quoted event - inside the kernel only */
-struct snd_seq_ev_quote {
-	struct snd_seq_addr origin;		/* original sender */
-	unsigned short value;		/* optional data */
-	struct snd_seq_event *event;		/* quoted event */
-} __attribute__((packed));
-
-
-	/* sequencer event */
-struct snd_seq_event {
-	snd_seq_event_type_t type;	/* event type */
-	unsigned char flags;		/* event flags */
-	char tag;
-	
-	unsigned char queue;		/* schedule queue */
-	union snd_seq_timestamp time;	/* schedule time */
-
-
-	struct snd_seq_addr source;	/* source address */
-	struct snd_seq_addr dest;	/* destination address */
-
-	union {				/* event data... */
-		struct snd_seq_ev_note note;
-		struct snd_seq_ev_ctrl control;
-		struct snd_seq_ev_raw8 raw8;
-		struct snd_seq_ev_raw32 raw32;
-		struct snd_seq_ev_ext ext;
-		struct snd_seq_ev_queue_control queue;
-		union snd_seq_timestamp time;
-		struct snd_seq_addr addr;
-		struct snd_seq_connect connect;
-		struct snd_seq_result result;
-		struct snd_seq_ev_quote quote;
-	} data;
-};
-
-
-/*
- * bounce event - stored as variable size data
- */
-struct snd_seq_event_bounce {
-	int err;
-	struct snd_seq_event event;
-	/* external data follows here. */
-};
-
-#ifdef __KERNEL__
+#include <uapi/sound/asequencer.h>
 
 /* helper macro */
 #define snd_seq_event_bounce_ext_data(ev) ((void*)((char *)(ev)->data.ext.ptr + sizeof(struct snd_seq_event_bounce)))
@@ -368,311 +83,4 @@
 /* queue sync port */
 #define snd_seq_queue_sync_port(q)	((q) + 16)
 
-#endif /* __KERNEL__ */
-
-	/* system information */
-struct snd_seq_system_info {
-	int queues;			/* maximum queues count */
-	int clients;			/* maximum clients count */
-	int ports;			/* maximum ports per client */
-	int channels;			/* maximum channels per port */
-	int cur_clients;		/* current clients */
-	int cur_queues;			/* current queues */
-	char reserved[24];
-};
-
-
-	/* system running information */
-struct snd_seq_running_info {
-	unsigned char client;		/* client id */
-	unsigned char big_endian;	/* 1 = big-endian */
-	unsigned char cpu_mode;		/* 4 = 32bit, 8 = 64bit */
-	unsigned char pad;		/* reserved */
-	unsigned char reserved[12];
-};
-
-
-	/* known client numbers */
-#define SNDRV_SEQ_CLIENT_SYSTEM		0
-	/* internal client numbers */
-#define SNDRV_SEQ_CLIENT_DUMMY		14	/* midi through */
-#define SNDRV_SEQ_CLIENT_OSS		15	/* oss sequencer emulator */
-
-
-	/* client types */
-typedef int __bitwise snd_seq_client_type_t;
-#define	NO_CLIENT	((__force snd_seq_client_type_t) 0)
-#define	USER_CLIENT	((__force snd_seq_client_type_t) 1)
-#define	KERNEL_CLIENT	((__force snd_seq_client_type_t) 2)
-                        
-	/* event filter flags */
-#define SNDRV_SEQ_FILTER_BROADCAST	(1<<0)	/* accept broadcast messages */
-#define SNDRV_SEQ_FILTER_MULTICAST	(1<<1)	/* accept multicast messages */
-#define SNDRV_SEQ_FILTER_BOUNCE		(1<<2)	/* accept bounce event in error */
-#define SNDRV_SEQ_FILTER_USE_EVENT	(1<<31)	/* use event filter */
-
-struct snd_seq_client_info {
-	int client;			/* client number to inquire */
-	snd_seq_client_type_t type;	/* client type */
-	char name[64];			/* client name */
-	unsigned int filter;		/* filter flags */
-	unsigned char multicast_filter[8]; /* multicast filter bitmap */
-	unsigned char event_filter[32];	/* event filter bitmap */
-	int num_ports;			/* RO: number of ports */
-	int event_lost;			/* number of lost events */
-	char reserved[64];		/* for future use */
-};
-
-
-/* client pool size */
-struct snd_seq_client_pool {
-	int client;			/* client number to inquire */
-	int output_pool;		/* outgoing (write) pool size */
-	int input_pool;			/* incoming (read) pool size */
-	int output_room;		/* minimum free pool size for select/blocking mode */
-	int output_free;		/* unused size */
-	int input_free;			/* unused size */
-	char reserved[64];
-};
-
-
-/* Remove events by specified criteria */
-
-#define SNDRV_SEQ_REMOVE_INPUT		(1<<0)	/* Flush input queues */
-#define SNDRV_SEQ_REMOVE_OUTPUT		(1<<1)	/* Flush output queues */
-#define SNDRV_SEQ_REMOVE_DEST		(1<<2)	/* Restrict by destination q:client:port */
-#define SNDRV_SEQ_REMOVE_DEST_CHANNEL	(1<<3)	/* Restrict by channel */
-#define SNDRV_SEQ_REMOVE_TIME_BEFORE	(1<<4)	/* Restrict to before time */
-#define SNDRV_SEQ_REMOVE_TIME_AFTER	(1<<5)	/* Restrict to time or after */
-#define SNDRV_SEQ_REMOVE_TIME_TICK	(1<<6)	/* Time is in ticks */
-#define SNDRV_SEQ_REMOVE_EVENT_TYPE	(1<<7)	/* Restrict to event type */
-#define SNDRV_SEQ_REMOVE_IGNORE_OFF 	(1<<8)	/* Do not flush off events */
-#define SNDRV_SEQ_REMOVE_TAG_MATCH 	(1<<9)	/* Restrict to events with given tag */
-
-struct snd_seq_remove_events {
-	unsigned int  remove_mode;	/* Flags that determine what gets removed */
-
-	union snd_seq_timestamp time;
-
-	unsigned char queue;	/* Queue for REMOVE_DEST */
-	struct snd_seq_addr dest;	/* Address for REMOVE_DEST */
-	unsigned char channel;	/* Channel for REMOVE_DEST */
-
-	int  type;	/* For REMOVE_EVENT_TYPE */
-	char  tag;	/* Tag for REMOVE_TAG */
-
-	int  reserved[10];	/* To allow for future binary compatibility */
-
-};
-
-
-	/* known port numbers */
-#define SNDRV_SEQ_PORT_SYSTEM_TIMER	0
-#define SNDRV_SEQ_PORT_SYSTEM_ANNOUNCE	1
-
-	/* port capabilities (32 bits) */
-#define SNDRV_SEQ_PORT_CAP_READ		(1<<0)	/* readable from this port */
-#define SNDRV_SEQ_PORT_CAP_WRITE	(1<<1)	/* writable to this port */
-
-#define SNDRV_SEQ_PORT_CAP_SYNC_READ	(1<<2)
-#define SNDRV_SEQ_PORT_CAP_SYNC_WRITE	(1<<3)
-
-#define SNDRV_SEQ_PORT_CAP_DUPLEX	(1<<4)
-
-#define SNDRV_SEQ_PORT_CAP_SUBS_READ	(1<<5)	/* allow read subscription */
-#define SNDRV_SEQ_PORT_CAP_SUBS_WRITE	(1<<6)	/* allow write subscription */
-#define SNDRV_SEQ_PORT_CAP_NO_EXPORT	(1<<7)	/* routing not allowed */
-
-	/* port type */
-#define SNDRV_SEQ_PORT_TYPE_SPECIFIC	(1<<0)	/* hardware specific */
-#define SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC (1<<1)	/* generic MIDI device */
-#define SNDRV_SEQ_PORT_TYPE_MIDI_GM	(1<<2)	/* General MIDI compatible device */
-#define SNDRV_SEQ_PORT_TYPE_MIDI_GS	(1<<3)	/* GS compatible device */
-#define SNDRV_SEQ_PORT_TYPE_MIDI_XG	(1<<4)	/* XG compatible device */
-#define SNDRV_SEQ_PORT_TYPE_MIDI_MT32	(1<<5)	/* MT-32 compatible device */
-#define SNDRV_SEQ_PORT_TYPE_MIDI_GM2	(1<<6)	/* General MIDI 2 compatible device */
-
-/* other standards...*/
-#define SNDRV_SEQ_PORT_TYPE_SYNTH	(1<<10)	/* Synth device (no MIDI compatible - direct wavetable) */
-#define SNDRV_SEQ_PORT_TYPE_DIRECT_SAMPLE (1<<11)	/* Sampling device (support sample download) */
-#define SNDRV_SEQ_PORT_TYPE_SAMPLE	(1<<12)	/* Sampling device (sample can be downloaded at any time) */
-/*...*/
-#define SNDRV_SEQ_PORT_TYPE_HARDWARE	(1<<16)	/* driver for a hardware device */
-#define SNDRV_SEQ_PORT_TYPE_SOFTWARE	(1<<17)	/* implemented in software */
-#define SNDRV_SEQ_PORT_TYPE_SYNTHESIZER	(1<<18)	/* generates sound */
-#define SNDRV_SEQ_PORT_TYPE_PORT	(1<<19)	/* connects to other device(s) */
-#define SNDRV_SEQ_PORT_TYPE_APPLICATION	(1<<20)	/* application (sequencer/editor) */
-
-/* misc. conditioning flags */
-#define SNDRV_SEQ_PORT_FLG_GIVEN_PORT	(1<<0)
-#define SNDRV_SEQ_PORT_FLG_TIMESTAMP	(1<<1)
-#define SNDRV_SEQ_PORT_FLG_TIME_REAL	(1<<2)
-
-struct snd_seq_port_info {
-	struct snd_seq_addr addr;	/* client/port numbers */
-	char name[64];			/* port name */
-
-	unsigned int capability;	/* port capability bits */
-	unsigned int type;		/* port type bits */
-	int midi_channels;		/* channels per MIDI port */
-	int midi_voices;		/* voices per MIDI port */
-	int synth_voices;		/* voices per SYNTH port */
-
-	int read_use;			/* R/O: subscribers for output (from this port) */
-	int write_use;			/* R/O: subscribers for input (to this port) */
-
-	void *kernel;			/* reserved for kernel use (must be NULL) */
-	unsigned int flags;		/* misc. conditioning */
-	unsigned char time_queue;	/* queue # for timestamping */
-	char reserved[59];		/* for future use */
-};
-
-
-/* queue flags */
-#define SNDRV_SEQ_QUEUE_FLG_SYNC	(1<<0)	/* sync enabled */
-
-/* queue information */
-struct snd_seq_queue_info {
-	int queue;		/* queue id */
-
-	/*
-	 *  security settings, only owner of this queue can start/stop timer
-	 *  etc. if the queue is locked for other clients
-	 */
-	int owner;		/* client id for owner of the queue */
-	unsigned locked:1;	/* timing queue locked for other queues */
-	char name[64];		/* name of this queue */
-	unsigned int flags;	/* flags */
-	char reserved[60];	/* for future use */
-
-};
-
-/* queue info/status */
-struct snd_seq_queue_status {
-	int queue;			/* queue id */
-	int events;			/* read-only - queue size */
-	snd_seq_tick_time_t tick;	/* current tick */
-	struct snd_seq_real_time time;	/* current time */
-	int running;			/* running state of queue */
-	int flags;			/* various flags */
-	char reserved[64];		/* for the future */
-};
-
-
-/* queue tempo */
-struct snd_seq_queue_tempo {
-	int queue;			/* sequencer queue */
-	unsigned int tempo;		/* current tempo, us/tick */
-	int ppq;			/* time resolution, ticks/quarter */
-	unsigned int skew_value;	/* queue skew */
-	unsigned int skew_base;		/* queue skew base */
-	char reserved[24];		/* for the future */
-};
-
-
-/* sequencer timer sources */
-#define SNDRV_SEQ_TIMER_ALSA		0	/* ALSA timer */
-#define SNDRV_SEQ_TIMER_MIDI_CLOCK	1	/* Midi Clock (CLOCK event) */
-#define SNDRV_SEQ_TIMER_MIDI_TICK	2	/* Midi Timer Tick (TICK event) */
-
-/* queue timer info */
-struct snd_seq_queue_timer {
-	int queue;			/* sequencer queue */
-	int type;			/* source timer type */
-	union {
-		struct {
-			struct snd_timer_id id;	/* ALSA's timer ID */
-			unsigned int resolution;	/* resolution in Hz */
-		} alsa;
-	} u;
-	char reserved[64];		/* for the future use */
-};
-
-
-struct snd_seq_queue_client {
-	int queue;		/* sequencer queue */
-	int client;		/* sequencer client */
-	int used;		/* queue is used with this client
-				   (must be set for accepting events) */
-	/* per client watermarks */
-	char reserved[64];	/* for future use */
-};
-
-
-#define SNDRV_SEQ_PORT_SUBS_EXCLUSIVE	(1<<0)	/* exclusive connection */
-#define SNDRV_SEQ_PORT_SUBS_TIMESTAMP	(1<<1)
-#define SNDRV_SEQ_PORT_SUBS_TIME_REAL	(1<<2)
-
-struct snd_seq_port_subscribe {
-	struct snd_seq_addr sender;	/* sender address */
-	struct snd_seq_addr dest;	/* destination address */
-	unsigned int voices;		/* number of voices to be allocated (0 = don't care) */
-	unsigned int flags;		/* modes */
-	unsigned char queue;		/* input time-stamp queue (optional) */
-	unsigned char pad[3];		/* reserved */
-	char reserved[64];
-};
-
-/* type of query subscription */
-#define SNDRV_SEQ_QUERY_SUBS_READ	0
-#define SNDRV_SEQ_QUERY_SUBS_WRITE	1
-
-struct snd_seq_query_subs {
-	struct snd_seq_addr root;	/* client/port id to be searched */
-	int type;		/* READ or WRITE */
-	int index;		/* 0..N-1 */
-	int num_subs;		/* R/O: number of subscriptions on this port */
-	struct snd_seq_addr addr;	/* R/O: result */
-	unsigned char queue;	/* R/O: result */
-	unsigned int flags;	/* R/O: result */
-	char reserved[64];	/* for future use */
-};
-
-
-/*
- *  IOCTL commands
- */
-
-#define SNDRV_SEQ_IOCTL_PVERSION	_IOR ('S', 0x00, int)
-#define SNDRV_SEQ_IOCTL_CLIENT_ID	_IOR ('S', 0x01, int)
-#define SNDRV_SEQ_IOCTL_SYSTEM_INFO	_IOWR('S', 0x02, struct snd_seq_system_info)
-#define SNDRV_SEQ_IOCTL_RUNNING_MODE	_IOWR('S', 0x03, struct snd_seq_running_info)
-
-#define SNDRV_SEQ_IOCTL_GET_CLIENT_INFO	_IOWR('S', 0x10, struct snd_seq_client_info)
-#define SNDRV_SEQ_IOCTL_SET_CLIENT_INFO	_IOW ('S', 0x11, struct snd_seq_client_info)
-
-#define SNDRV_SEQ_IOCTL_CREATE_PORT	_IOWR('S', 0x20, struct snd_seq_port_info)
-#define SNDRV_SEQ_IOCTL_DELETE_PORT	_IOW ('S', 0x21, struct snd_seq_port_info)
-#define SNDRV_SEQ_IOCTL_GET_PORT_INFO	_IOWR('S', 0x22, struct snd_seq_port_info)
-#define SNDRV_SEQ_IOCTL_SET_PORT_INFO	_IOW ('S', 0x23, struct snd_seq_port_info)
-
-#define SNDRV_SEQ_IOCTL_SUBSCRIBE_PORT	_IOW ('S', 0x30, struct snd_seq_port_subscribe)
-#define SNDRV_SEQ_IOCTL_UNSUBSCRIBE_PORT _IOW ('S', 0x31, struct snd_seq_port_subscribe)
-
-#define SNDRV_SEQ_IOCTL_CREATE_QUEUE	_IOWR('S', 0x32, struct snd_seq_queue_info)
-#define SNDRV_SEQ_IOCTL_DELETE_QUEUE	_IOW ('S', 0x33, struct snd_seq_queue_info)
-#define SNDRV_SEQ_IOCTL_GET_QUEUE_INFO	_IOWR('S', 0x34, struct snd_seq_queue_info)
-#define SNDRV_SEQ_IOCTL_SET_QUEUE_INFO	_IOWR('S', 0x35, struct snd_seq_queue_info)
-#define SNDRV_SEQ_IOCTL_GET_NAMED_QUEUE	_IOWR('S', 0x36, struct snd_seq_queue_info)
-#define SNDRV_SEQ_IOCTL_GET_QUEUE_STATUS _IOWR('S', 0x40, struct snd_seq_queue_status)
-#define SNDRV_SEQ_IOCTL_GET_QUEUE_TEMPO	_IOWR('S', 0x41, struct snd_seq_queue_tempo)
-#define SNDRV_SEQ_IOCTL_SET_QUEUE_TEMPO	_IOW ('S', 0x42, struct snd_seq_queue_tempo)
-#define SNDRV_SEQ_IOCTL_GET_QUEUE_OWNER	_IOWR('S', 0x43, struct snd_seq_queue_owner)
-#define SNDRV_SEQ_IOCTL_SET_QUEUE_OWNER	_IOW ('S', 0x44, struct snd_seq_queue_owner)
-#define SNDRV_SEQ_IOCTL_GET_QUEUE_TIMER	_IOWR('S', 0x45, struct snd_seq_queue_timer)
-#define SNDRV_SEQ_IOCTL_SET_QUEUE_TIMER	_IOW ('S', 0x46, struct snd_seq_queue_timer)
-/* XXX
-#define SNDRV_SEQ_IOCTL_GET_QUEUE_SYNC	_IOWR('S', 0x53, struct snd_seq_queue_sync)
-#define SNDRV_SEQ_IOCTL_SET_QUEUE_SYNC	_IOW ('S', 0x54, struct snd_seq_queue_sync)
-*/
-#define SNDRV_SEQ_IOCTL_GET_QUEUE_CLIENT	_IOWR('S', 0x49, struct snd_seq_queue_client)
-#define SNDRV_SEQ_IOCTL_SET_QUEUE_CLIENT	_IOW ('S', 0x4a, struct snd_seq_queue_client)
-#define SNDRV_SEQ_IOCTL_GET_CLIENT_POOL	_IOWR('S', 0x4b, struct snd_seq_client_pool)
-#define SNDRV_SEQ_IOCTL_SET_CLIENT_POOL	_IOW ('S', 0x4c, struct snd_seq_client_pool)
-#define SNDRV_SEQ_IOCTL_REMOVE_EVENTS	_IOW ('S', 0x4e, struct snd_seq_remove_events)
-#define SNDRV_SEQ_IOCTL_QUERY_SUBS	_IOWR('S', 0x4f, struct snd_seq_query_subs)
-#define SNDRV_SEQ_IOCTL_GET_SUBSCRIPTION	_IOWR('S', 0x50, struct snd_seq_port_subscribe)
-#define SNDRV_SEQ_IOCTL_QUERY_NEXT_CLIENT	_IOWR('S', 0x51, struct snd_seq_client_info)
-#define SNDRV_SEQ_IOCTL_QUERY_NEXT_PORT	_IOWR('S', 0x52, struct snd_seq_port_info)
-
 #endif /* __SOUND_ASEQUENCER_H */
diff --git a/include/sound/asound.h b/include/sound/asound.h
index dfe7d44..c2dff53 100644
--- a/include/sound/asound.h
+++ b/include/sound/asound.h
@@ -19,13 +19,9 @@
  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  *
  */
-
 #ifndef __SOUND_ASOUND_H
 #define __SOUND_ASOUND_H
 
-#include <linux/types.h>
-
-#ifdef __KERNEL__
 #include <linux/ioctl.h>
 #include <linux/time.h>
 #include <asm/byteorder.h>
@@ -40,934 +36,5 @@
 #endif
 #endif
 
-#endif /* __KERNEL__ **/
-
-/*
- *  protocol version
- */
-
-#define SNDRV_PROTOCOL_VERSION(major, minor, subminor) (((major)<<16)|((minor)<<8)|(subminor))
-#define SNDRV_PROTOCOL_MAJOR(version) (((version)>>16)&0xffff)
-#define SNDRV_PROTOCOL_MINOR(version) (((version)>>8)&0xff)
-#define SNDRV_PROTOCOL_MICRO(version) ((version)&0xff)
-#define SNDRV_PROTOCOL_INCOMPATIBLE(kversion, uversion) \
-	(SNDRV_PROTOCOL_MAJOR(kversion) != SNDRV_PROTOCOL_MAJOR(uversion) || \
-	 (SNDRV_PROTOCOL_MAJOR(kversion) == SNDRV_PROTOCOL_MAJOR(uversion) && \
-	   SNDRV_PROTOCOL_MINOR(kversion) != SNDRV_PROTOCOL_MINOR(uversion)))
-
-/****************************************************************************
- *                                                                          *
- *        Digital audio interface					    *
- *                                                                          *
- ****************************************************************************/
-
-struct snd_aes_iec958 {
-	unsigned char status[24];	/* AES/IEC958 channel status bits */
-	unsigned char subcode[147];	/* AES/IEC958 subcode bits */
-	unsigned char pad;		/* nothing */
-	unsigned char dig_subframe[4];	/* AES/IEC958 subframe bits */
-};
-
-/****************************************************************************
- *                                                                          *
- *        CEA-861 Audio InfoFrame. Used in HDMI and DisplayPort		    *
- *                                                                          *
- ****************************************************************************/
-
-struct snd_cea_861_aud_if {
-	unsigned char db1_ct_cc; /* coding type and channel count */
-	unsigned char db2_sf_ss; /* sample frequency and size */
-	unsigned char db3; /* not used, all zeros */
-	unsigned char db4_ca; /* channel allocation code */
-	unsigned char db5_dminh_lsv; /* downmix inhibit & level-shit values */
-};
-
-/****************************************************************************
- *                                                                          *
- *      Section for driver hardware dependent interface - /dev/snd/hw?      *
- *                                                                          *
- ****************************************************************************/
-
-#define SNDRV_HWDEP_VERSION		SNDRV_PROTOCOL_VERSION(1, 0, 1)
-
-enum {
-	SNDRV_HWDEP_IFACE_OPL2 = 0,
-	SNDRV_HWDEP_IFACE_OPL3,
-	SNDRV_HWDEP_IFACE_OPL4,
-	SNDRV_HWDEP_IFACE_SB16CSP,	/* Creative Signal Processor */
-	SNDRV_HWDEP_IFACE_EMU10K1,	/* FX8010 processor in EMU10K1 chip */
-	SNDRV_HWDEP_IFACE_YSS225,	/* Yamaha FX processor */
-	SNDRV_HWDEP_IFACE_ICS2115,	/* Wavetable synth */
-	SNDRV_HWDEP_IFACE_SSCAPE,	/* Ensoniq SoundScape ISA card (MC68EC000) */
-	SNDRV_HWDEP_IFACE_VX,		/* Digigram VX cards */
-	SNDRV_HWDEP_IFACE_MIXART,	/* Digigram miXart cards */
-	SNDRV_HWDEP_IFACE_USX2Y,	/* Tascam US122, US224 & US428 usb */
-	SNDRV_HWDEP_IFACE_EMUX_WAVETABLE, /* EmuX wavetable */	
-	SNDRV_HWDEP_IFACE_BLUETOOTH,	/* Bluetooth audio */
-	SNDRV_HWDEP_IFACE_USX2Y_PCM,	/* Tascam US122, US224 & US428 rawusb pcm */
-	SNDRV_HWDEP_IFACE_PCXHR,	/* Digigram PCXHR */
-	SNDRV_HWDEP_IFACE_SB_RC,	/* SB Extigy/Audigy2NX remote control */
-	SNDRV_HWDEP_IFACE_HDA,		/* HD-audio */
-	SNDRV_HWDEP_IFACE_USB_STREAM,	/* direct access to usb stream */
-
-	/* Don't forget to change the following: */
-	SNDRV_HWDEP_IFACE_LAST = SNDRV_HWDEP_IFACE_USB_STREAM
-};
-
-struct snd_hwdep_info {
-	unsigned int device;		/* WR: device number */
-	int card;			/* R: card number */
-	unsigned char id[64];		/* ID (user selectable) */
-	unsigned char name[80];		/* hwdep name */
-	int iface;			/* hwdep interface */
-	unsigned char reserved[64];	/* reserved for future */
-};
-
-/* generic DSP loader */
-struct snd_hwdep_dsp_status {
-	unsigned int version;		/* R: driver-specific version */
-	unsigned char id[32];		/* R: driver-specific ID string */
-	unsigned int num_dsps;		/* R: number of DSP images to transfer */
-	unsigned int dsp_loaded;	/* R: bit flags indicating the loaded DSPs */
-	unsigned int chip_ready;	/* R: 1 = initialization finished */
-	unsigned char reserved[16];	/* reserved for future use */
-};
-
-struct snd_hwdep_dsp_image {
-	unsigned int index;		/* W: DSP index */
-	unsigned char name[64];		/* W: ID (e.g. file name) */
-	unsigned char __user *image;	/* W: binary image */
-	size_t length;			/* W: size of image in bytes */
-	unsigned long driver_data;	/* W: driver-specific data */
-};
-
-#define SNDRV_HWDEP_IOCTL_PVERSION	_IOR ('H', 0x00, int)
-#define SNDRV_HWDEP_IOCTL_INFO		_IOR ('H', 0x01, struct snd_hwdep_info)
-#define SNDRV_HWDEP_IOCTL_DSP_STATUS	_IOR('H', 0x02, struct snd_hwdep_dsp_status)
-#define SNDRV_HWDEP_IOCTL_DSP_LOAD	_IOW('H', 0x03, struct snd_hwdep_dsp_image)
-
-/*****************************************************************************
- *                                                                           *
- *             Digital Audio (PCM) interface - /dev/snd/pcm??                *
- *                                                                           *
- *****************************************************************************/
-
-#define SNDRV_PCM_VERSION		SNDRV_PROTOCOL_VERSION(2, 0, 10)
-
-typedef unsigned long snd_pcm_uframes_t;
-typedef signed long snd_pcm_sframes_t;
-
-enum {
-	SNDRV_PCM_CLASS_GENERIC = 0,	/* standard mono or stereo device */
-	SNDRV_PCM_CLASS_MULTI,		/* multichannel device */
-	SNDRV_PCM_CLASS_MODEM,		/* software modem class */
-	SNDRV_PCM_CLASS_DIGITIZER,	/* digitizer class */
-	/* Don't forget to change the following: */
-	SNDRV_PCM_CLASS_LAST = SNDRV_PCM_CLASS_DIGITIZER,
-};
-
-enum {
-	SNDRV_PCM_SUBCLASS_GENERIC_MIX = 0, /* mono or stereo subdevices are mixed together */
-	SNDRV_PCM_SUBCLASS_MULTI_MIX,	/* multichannel subdevices are mixed together */
-	/* Don't forget to change the following: */
-	SNDRV_PCM_SUBCLASS_LAST = SNDRV_PCM_SUBCLASS_MULTI_MIX,
-};
-
-enum {
-	SNDRV_PCM_STREAM_PLAYBACK = 0,
-	SNDRV_PCM_STREAM_CAPTURE,
-	SNDRV_PCM_STREAM_LAST = SNDRV_PCM_STREAM_CAPTURE,
-};
-
-typedef int __bitwise snd_pcm_access_t;
-#define	SNDRV_PCM_ACCESS_MMAP_INTERLEAVED	((__force snd_pcm_access_t) 0) /* interleaved mmap */
-#define	SNDRV_PCM_ACCESS_MMAP_NONINTERLEAVED	((__force snd_pcm_access_t) 1) /* noninterleaved mmap */
-#define	SNDRV_PCM_ACCESS_MMAP_COMPLEX		((__force snd_pcm_access_t) 2) /* complex mmap */
-#define	SNDRV_PCM_ACCESS_RW_INTERLEAVED		((__force snd_pcm_access_t) 3) /* readi/writei */
-#define	SNDRV_PCM_ACCESS_RW_NONINTERLEAVED	((__force snd_pcm_access_t) 4) /* readn/writen */
-#define	SNDRV_PCM_ACCESS_LAST		SNDRV_PCM_ACCESS_RW_NONINTERLEAVED
-
-typedef int __bitwise snd_pcm_format_t;
-#define	SNDRV_PCM_FORMAT_S8	((__force snd_pcm_format_t) 0)
-#define	SNDRV_PCM_FORMAT_U8	((__force snd_pcm_format_t) 1)
-#define	SNDRV_PCM_FORMAT_S16_LE	((__force snd_pcm_format_t) 2)
-#define	SNDRV_PCM_FORMAT_S16_BE	((__force snd_pcm_format_t) 3)
-#define	SNDRV_PCM_FORMAT_U16_LE	((__force snd_pcm_format_t) 4)
-#define	SNDRV_PCM_FORMAT_U16_BE	((__force snd_pcm_format_t) 5)
-#define	SNDRV_PCM_FORMAT_S24_LE	((__force snd_pcm_format_t) 6) /* low three bytes */
-#define	SNDRV_PCM_FORMAT_S24_BE	((__force snd_pcm_format_t) 7) /* low three bytes */
-#define	SNDRV_PCM_FORMAT_U24_LE	((__force snd_pcm_format_t) 8) /* low three bytes */
-#define	SNDRV_PCM_FORMAT_U24_BE	((__force snd_pcm_format_t) 9) /* low three bytes */
-#define	SNDRV_PCM_FORMAT_S32_LE	((__force snd_pcm_format_t) 10)
-#define	SNDRV_PCM_FORMAT_S32_BE	((__force snd_pcm_format_t) 11)
-#define	SNDRV_PCM_FORMAT_U32_LE	((__force snd_pcm_format_t) 12)
-#define	SNDRV_PCM_FORMAT_U32_BE	((__force snd_pcm_format_t) 13)
-#define	SNDRV_PCM_FORMAT_FLOAT_LE	((__force snd_pcm_format_t) 14) /* 4-byte float, IEEE-754 32-bit, range -1.0 to 1.0 */
-#define	SNDRV_PCM_FORMAT_FLOAT_BE	((__force snd_pcm_format_t) 15) /* 4-byte float, IEEE-754 32-bit, range -1.0 to 1.0 */
-#define	SNDRV_PCM_FORMAT_FLOAT64_LE	((__force snd_pcm_format_t) 16) /* 8-byte float, IEEE-754 64-bit, range -1.0 to 1.0 */
-#define	SNDRV_PCM_FORMAT_FLOAT64_BE	((__force snd_pcm_format_t) 17) /* 8-byte float, IEEE-754 64-bit, range -1.0 to 1.0 */
-#define	SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE ((__force snd_pcm_format_t) 18) /* IEC-958 subframe, Little Endian */
-#define	SNDRV_PCM_FORMAT_IEC958_SUBFRAME_BE ((__force snd_pcm_format_t) 19) /* IEC-958 subframe, Big Endian */
-#define	SNDRV_PCM_FORMAT_MU_LAW		((__force snd_pcm_format_t) 20)
-#define	SNDRV_PCM_FORMAT_A_LAW		((__force snd_pcm_format_t) 21)
-#define	SNDRV_PCM_FORMAT_IMA_ADPCM	((__force snd_pcm_format_t) 22)
-#define	SNDRV_PCM_FORMAT_MPEG		((__force snd_pcm_format_t) 23)
-#define	SNDRV_PCM_FORMAT_GSM		((__force snd_pcm_format_t) 24)
-#define	SNDRV_PCM_FORMAT_SPECIAL	((__force snd_pcm_format_t) 31)
-#define	SNDRV_PCM_FORMAT_S24_3LE	((__force snd_pcm_format_t) 32)	/* in three bytes */
-#define	SNDRV_PCM_FORMAT_S24_3BE	((__force snd_pcm_format_t) 33)	/* in three bytes */
-#define	SNDRV_PCM_FORMAT_U24_3LE	((__force snd_pcm_format_t) 34)	/* in three bytes */
-#define	SNDRV_PCM_FORMAT_U24_3BE	((__force snd_pcm_format_t) 35)	/* in three bytes */
-#define	SNDRV_PCM_FORMAT_S20_3LE	((__force snd_pcm_format_t) 36)	/* in three bytes */
-#define	SNDRV_PCM_FORMAT_S20_3BE	((__force snd_pcm_format_t) 37)	/* in three bytes */
-#define	SNDRV_PCM_FORMAT_U20_3LE	((__force snd_pcm_format_t) 38)	/* in three bytes */
-#define	SNDRV_PCM_FORMAT_U20_3BE	((__force snd_pcm_format_t) 39)	/* in three bytes */
-#define	SNDRV_PCM_FORMAT_S18_3LE	((__force snd_pcm_format_t) 40)	/* in three bytes */
-#define	SNDRV_PCM_FORMAT_S18_3BE	((__force snd_pcm_format_t) 41)	/* in three bytes */
-#define	SNDRV_PCM_FORMAT_U18_3LE	((__force snd_pcm_format_t) 42)	/* in three bytes */
-#define	SNDRV_PCM_FORMAT_U18_3BE	((__force snd_pcm_format_t) 43)	/* in three bytes */
-#define	SNDRV_PCM_FORMAT_G723_24	((__force snd_pcm_format_t) 44) /* 8 samples in 3 bytes */
-#define	SNDRV_PCM_FORMAT_G723_24_1B	((__force snd_pcm_format_t) 45) /* 1 sample in 1 byte */
-#define	SNDRV_PCM_FORMAT_G723_40	((__force snd_pcm_format_t) 46) /* 8 Samples in 5 bytes */
-#define	SNDRV_PCM_FORMAT_G723_40_1B	((__force snd_pcm_format_t) 47) /* 1 sample in 1 byte */
-#define	SNDRV_PCM_FORMAT_LAST		SNDRV_PCM_FORMAT_G723_40_1B
-
-#ifdef SNDRV_LITTLE_ENDIAN
-#define	SNDRV_PCM_FORMAT_S16		SNDRV_PCM_FORMAT_S16_LE
-#define	SNDRV_PCM_FORMAT_U16		SNDRV_PCM_FORMAT_U16_LE
-#define	SNDRV_PCM_FORMAT_S24		SNDRV_PCM_FORMAT_S24_LE
-#define	SNDRV_PCM_FORMAT_U24		SNDRV_PCM_FORMAT_U24_LE
-#define	SNDRV_PCM_FORMAT_S32		SNDRV_PCM_FORMAT_S32_LE
-#define	SNDRV_PCM_FORMAT_U32		SNDRV_PCM_FORMAT_U32_LE
-#define	SNDRV_PCM_FORMAT_FLOAT		SNDRV_PCM_FORMAT_FLOAT_LE
-#define	SNDRV_PCM_FORMAT_FLOAT64	SNDRV_PCM_FORMAT_FLOAT64_LE
-#define	SNDRV_PCM_FORMAT_IEC958_SUBFRAME SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE
-#endif
-#ifdef SNDRV_BIG_ENDIAN
-#define	SNDRV_PCM_FORMAT_S16		SNDRV_PCM_FORMAT_S16_BE
-#define	SNDRV_PCM_FORMAT_U16		SNDRV_PCM_FORMAT_U16_BE
-#define	SNDRV_PCM_FORMAT_S24		SNDRV_PCM_FORMAT_S24_BE
-#define	SNDRV_PCM_FORMAT_U24		SNDRV_PCM_FORMAT_U24_BE
-#define	SNDRV_PCM_FORMAT_S32		SNDRV_PCM_FORMAT_S32_BE
-#define	SNDRV_PCM_FORMAT_U32		SNDRV_PCM_FORMAT_U32_BE
-#define	SNDRV_PCM_FORMAT_FLOAT		SNDRV_PCM_FORMAT_FLOAT_BE
-#define	SNDRV_PCM_FORMAT_FLOAT64	SNDRV_PCM_FORMAT_FLOAT64_BE
-#define	SNDRV_PCM_FORMAT_IEC958_SUBFRAME SNDRV_PCM_FORMAT_IEC958_SUBFRAME_BE
-#endif
-
-typedef int __bitwise snd_pcm_subformat_t;
-#define	SNDRV_PCM_SUBFORMAT_STD		((__force snd_pcm_subformat_t) 0)
-#define	SNDRV_PCM_SUBFORMAT_LAST	SNDRV_PCM_SUBFORMAT_STD
-
-#define SNDRV_PCM_INFO_MMAP		0x00000001	/* hardware supports mmap */
-#define SNDRV_PCM_INFO_MMAP_VALID	0x00000002	/* period data are valid during transfer */
-#define SNDRV_PCM_INFO_DOUBLE		0x00000004	/* Double buffering needed for PCM start/stop */
-#define SNDRV_PCM_INFO_BATCH		0x00000010	/* double buffering */
-#define SNDRV_PCM_INFO_INTERLEAVED	0x00000100	/* channels are interleaved */
-#define SNDRV_PCM_INFO_NONINTERLEAVED	0x00000200	/* channels are not interleaved */
-#define SNDRV_PCM_INFO_COMPLEX		0x00000400	/* complex frame organization (mmap only) */
-#define SNDRV_PCM_INFO_BLOCK_TRANSFER	0x00010000	/* hardware transfer block of samples */
-#define SNDRV_PCM_INFO_OVERRANGE	0x00020000	/* hardware supports ADC (capture) overrange detection */
-#define SNDRV_PCM_INFO_RESUME		0x00040000	/* hardware supports stream resume after suspend */
-#define SNDRV_PCM_INFO_PAUSE		0x00080000	/* pause ioctl is supported */
-#define SNDRV_PCM_INFO_HALF_DUPLEX	0x00100000	/* only half duplex */
-#define SNDRV_PCM_INFO_JOINT_DUPLEX	0x00200000	/* playback and capture stream are somewhat correlated */
-#define SNDRV_PCM_INFO_SYNC_START	0x00400000	/* pcm support some kind of sync go */
-#define SNDRV_PCM_INFO_NO_PERIOD_WAKEUP	0x00800000	/* period wakeup can be disabled */
-#define SNDRV_PCM_INFO_FIFO_IN_FRAMES	0x80000000	/* internal kernel flag - FIFO size is in frames */
-
-typedef int __bitwise snd_pcm_state_t;
-#define	SNDRV_PCM_STATE_OPEN		((__force snd_pcm_state_t) 0) /* stream is open */
-#define	SNDRV_PCM_STATE_SETUP		((__force snd_pcm_state_t) 1) /* stream has a setup */
-#define	SNDRV_PCM_STATE_PREPARED	((__force snd_pcm_state_t) 2) /* stream is ready to start */
-#define	SNDRV_PCM_STATE_RUNNING		((__force snd_pcm_state_t) 3) /* stream is running */
-#define	SNDRV_PCM_STATE_XRUN		((__force snd_pcm_state_t) 4) /* stream reached an xrun */
-#define	SNDRV_PCM_STATE_DRAINING	((__force snd_pcm_state_t) 5) /* stream is draining */
-#define	SNDRV_PCM_STATE_PAUSED		((__force snd_pcm_state_t) 6) /* stream is paused */
-#define	SNDRV_PCM_STATE_SUSPENDED	((__force snd_pcm_state_t) 7) /* hardware is suspended */
-#define	SNDRV_PCM_STATE_DISCONNECTED	((__force snd_pcm_state_t) 8) /* hardware is disconnected */
-#define	SNDRV_PCM_STATE_LAST		SNDRV_PCM_STATE_DISCONNECTED
-
-enum {
-	SNDRV_PCM_MMAP_OFFSET_DATA = 0x00000000,
-	SNDRV_PCM_MMAP_OFFSET_STATUS = 0x80000000,
-	SNDRV_PCM_MMAP_OFFSET_CONTROL = 0x81000000,
-};
-
-union snd_pcm_sync_id {
-	unsigned char id[16];
-	unsigned short id16[8];
-	unsigned int id32[4];
-};
-
-struct snd_pcm_info {
-	unsigned int device;		/* RO/WR (control): device number */
-	unsigned int subdevice;		/* RO/WR (control): subdevice number */
-	int stream;			/* RO/WR (control): stream direction */
-	int card;			/* R: card number */
-	unsigned char id[64];		/* ID (user selectable) */
-	unsigned char name[80];		/* name of this device */
-	unsigned char subname[32];	/* subdevice name */
-	int dev_class;			/* SNDRV_PCM_CLASS_* */
-	int dev_subclass;		/* SNDRV_PCM_SUBCLASS_* */
-	unsigned int subdevices_count;
-	unsigned int subdevices_avail;
-	union snd_pcm_sync_id sync;	/* hardware synchronization ID */
-	unsigned char reserved[64];	/* reserved for future... */
-};
-
-typedef int snd_pcm_hw_param_t;
-#define	SNDRV_PCM_HW_PARAM_ACCESS	0	/* Access type */
-#define	SNDRV_PCM_HW_PARAM_FORMAT	1	/* Format */
-#define	SNDRV_PCM_HW_PARAM_SUBFORMAT	2	/* Subformat */
-#define	SNDRV_PCM_HW_PARAM_FIRST_MASK	SNDRV_PCM_HW_PARAM_ACCESS
-#define	SNDRV_PCM_HW_PARAM_LAST_MASK	SNDRV_PCM_HW_PARAM_SUBFORMAT
-
-#define	SNDRV_PCM_HW_PARAM_SAMPLE_BITS	8	/* Bits per sample */
-#define	SNDRV_PCM_HW_PARAM_FRAME_BITS	9	/* Bits per frame */
-#define	SNDRV_PCM_HW_PARAM_CHANNELS	10	/* Channels */
-#define	SNDRV_PCM_HW_PARAM_RATE		11	/* Approx rate */
-#define	SNDRV_PCM_HW_PARAM_PERIOD_TIME	12	/* Approx distance between
-						 * interrupts in us
-						 */
-#define	SNDRV_PCM_HW_PARAM_PERIOD_SIZE	13	/* Approx frames between
-						 * interrupts
-						 */
-#define	SNDRV_PCM_HW_PARAM_PERIOD_BYTES	14	/* Approx bytes between
-						 * interrupts
-						 */
-#define	SNDRV_PCM_HW_PARAM_PERIODS	15	/* Approx interrupts per
-						 * buffer
-						 */
-#define	SNDRV_PCM_HW_PARAM_BUFFER_TIME	16	/* Approx duration of buffer
-						 * in us
-						 */
-#define	SNDRV_PCM_HW_PARAM_BUFFER_SIZE	17	/* Size of buffer in frames */
-#define	SNDRV_PCM_HW_PARAM_BUFFER_BYTES	18	/* Size of buffer in bytes */
-#define	SNDRV_PCM_HW_PARAM_TICK_TIME	19	/* Approx tick duration in us */
-#define	SNDRV_PCM_HW_PARAM_FIRST_INTERVAL	SNDRV_PCM_HW_PARAM_SAMPLE_BITS
-#define	SNDRV_PCM_HW_PARAM_LAST_INTERVAL	SNDRV_PCM_HW_PARAM_TICK_TIME
-
-#define SNDRV_PCM_HW_PARAMS_NORESAMPLE	(1<<0)	/* avoid rate resampling */
-#define SNDRV_PCM_HW_PARAMS_EXPORT_BUFFER	(1<<1)	/* export buffer */
-#define SNDRV_PCM_HW_PARAMS_NO_PERIOD_WAKEUP	(1<<2)	/* disable period wakeups */
-
-struct snd_interval {
-	unsigned int min, max;
-	unsigned int openmin:1,
-		     openmax:1,
-		     integer:1,
-		     empty:1;
-};
-
-#define SNDRV_MASK_MAX	256
-
-struct snd_mask {
-	__u32 bits[(SNDRV_MASK_MAX+31)/32];
-};
-
-struct snd_pcm_hw_params {
-	unsigned int flags;
-	struct snd_mask masks[SNDRV_PCM_HW_PARAM_LAST_MASK - 
-			       SNDRV_PCM_HW_PARAM_FIRST_MASK + 1];
-	struct snd_mask mres[5];	/* reserved masks */
-	struct snd_interval intervals[SNDRV_PCM_HW_PARAM_LAST_INTERVAL -
-				        SNDRV_PCM_HW_PARAM_FIRST_INTERVAL + 1];
-	struct snd_interval ires[9];	/* reserved intervals */
-	unsigned int rmask;		/* W: requested masks */
-	unsigned int cmask;		/* R: changed masks */
-	unsigned int info;		/* R: Info flags for returned setup */
-	unsigned int msbits;		/* R: used most significant bits */
-	unsigned int rate_num;		/* R: rate numerator */
-	unsigned int rate_den;		/* R: rate denominator */
-	snd_pcm_uframes_t fifo_size;	/* R: chip FIFO size in frames */
-	unsigned char reserved[64];	/* reserved for future */
-};
-
-enum {
-	SNDRV_PCM_TSTAMP_NONE = 0,
-	SNDRV_PCM_TSTAMP_ENABLE,
-	SNDRV_PCM_TSTAMP_LAST = SNDRV_PCM_TSTAMP_ENABLE,
-};
-
-struct snd_pcm_sw_params {
-	int tstamp_mode;			/* timestamp mode */
-	unsigned int period_step;
-	unsigned int sleep_min;			/* min ticks to sleep */
-	snd_pcm_uframes_t avail_min;		/* min avail frames for wakeup */
-	snd_pcm_uframes_t xfer_align;		/* obsolete: xfer size need to be a multiple */
-	snd_pcm_uframes_t start_threshold;	/* min hw_avail frames for automatic start */
-	snd_pcm_uframes_t stop_threshold;	/* min avail frames for automatic stop */
-	snd_pcm_uframes_t silence_threshold;	/* min distance from noise for silence filling */
-	snd_pcm_uframes_t silence_size;		/* silence block size */
-	snd_pcm_uframes_t boundary;		/* pointers wrap point */
-	unsigned char reserved[64];		/* reserved for future */
-};
-
-struct snd_pcm_channel_info {
-	unsigned int channel;
-	__kernel_off_t offset;		/* mmap offset */
-	unsigned int first;		/* offset to first sample in bits */
-	unsigned int step;		/* samples distance in bits */
-};
-
-struct snd_pcm_status {
-	snd_pcm_state_t state;		/* stream state */
-	struct timespec trigger_tstamp;	/* time when stream was started/stopped/paused */
-	struct timespec tstamp;		/* reference timestamp */
-	snd_pcm_uframes_t appl_ptr;	/* appl ptr */
-	snd_pcm_uframes_t hw_ptr;	/* hw ptr */
-	snd_pcm_sframes_t delay;	/* current delay in frames */
-	snd_pcm_uframes_t avail;	/* number of frames available */
-	snd_pcm_uframes_t avail_max;	/* max frames available on hw since last status */
-	snd_pcm_uframes_t overrange;	/* count of ADC (capture) overrange detections from last status */
-	snd_pcm_state_t suspended_state; /* suspended stream state */
-	unsigned char reserved[60];	/* must be filled with zero */
-};
-
-struct snd_pcm_mmap_status {
-	snd_pcm_state_t state;		/* RO: state - SNDRV_PCM_STATE_XXXX */
-	int pad1;			/* Needed for 64 bit alignment */
-	snd_pcm_uframes_t hw_ptr;	/* RO: hw ptr (0...boundary-1) */
-	struct timespec tstamp;		/* Timestamp */
-	snd_pcm_state_t suspended_state; /* RO: suspended stream state */
-};
-
-struct snd_pcm_mmap_control {
-	snd_pcm_uframes_t appl_ptr;	/* RW: appl ptr (0...boundary-1) */
-	snd_pcm_uframes_t avail_min;	/* RW: min available frames for wakeup */
-};
-
-#define SNDRV_PCM_SYNC_PTR_HWSYNC	(1<<0)	/* execute hwsync */
-#define SNDRV_PCM_SYNC_PTR_APPL		(1<<1)	/* get appl_ptr from driver (r/w op) */
-#define SNDRV_PCM_SYNC_PTR_AVAIL_MIN	(1<<2)	/* get avail_min from driver */
-
-struct snd_pcm_sync_ptr {
-	unsigned int flags;
-	union {
-		struct snd_pcm_mmap_status status;
-		unsigned char reserved[64];
-	} s;
-	union {
-		struct snd_pcm_mmap_control control;
-		unsigned char reserved[64];
-	} c;
-};
-
-struct snd_xferi {
-	snd_pcm_sframes_t result;
-	void __user *buf;
-	snd_pcm_uframes_t frames;
-};
-
-struct snd_xfern {
-	snd_pcm_sframes_t result;
-	void __user * __user *bufs;
-	snd_pcm_uframes_t frames;
-};
-
-enum {
-	SNDRV_PCM_TSTAMP_TYPE_GETTIMEOFDAY = 0,	/* gettimeofday equivalent */
-	SNDRV_PCM_TSTAMP_TYPE_MONOTONIC,	/* posix_clock_monotonic equivalent */
-	SNDRV_PCM_TSTAMP_TYPE_LAST = SNDRV_PCM_TSTAMP_TYPE_MONOTONIC,
-};
-
-/* channel positions */
-enum {
-	SNDRV_CHMAP_UNKNOWN = 0,
-	SNDRV_CHMAP_NA,		/* N/A, silent */
-	SNDRV_CHMAP_MONO,	/* mono stream */
-	/* this follows the alsa-lib mixer channel value + 3 */
-	SNDRV_CHMAP_FL,		/* front left */
-	SNDRV_CHMAP_FR,		/* front right */
-	SNDRV_CHMAP_RL,		/* rear left */
-	SNDRV_CHMAP_RR,		/* rear right */
-	SNDRV_CHMAP_FC,		/* front center */
-	SNDRV_CHMAP_LFE,	/* LFE */
-	SNDRV_CHMAP_SL,		/* side left */
-	SNDRV_CHMAP_SR,		/* side right */
-	SNDRV_CHMAP_RC,		/* rear center */
-	/* new definitions */
-	SNDRV_CHMAP_FLC,	/* front left center */
-	SNDRV_CHMAP_FRC,	/* front right center */
-	SNDRV_CHMAP_RLC,	/* rear left center */
-	SNDRV_CHMAP_RRC,	/* rear right center */
-	SNDRV_CHMAP_FLW,	/* front left wide */
-	SNDRV_CHMAP_FRW,	/* front right wide */
-	SNDRV_CHMAP_FLH,	/* front left high */
-	SNDRV_CHMAP_FCH,	/* front center high */
-	SNDRV_CHMAP_FRH,	/* front right high */
-	SNDRV_CHMAP_TC,		/* top center */
-	SNDRV_CHMAP_TFL,	/* top front left */
-	SNDRV_CHMAP_TFR,	/* top front right */
-	SNDRV_CHMAP_TFC,	/* top front center */
-	SNDRV_CHMAP_TRL,	/* top rear left */
-	SNDRV_CHMAP_TRR,	/* top rear right */
-	SNDRV_CHMAP_TRC,	/* top rear center */
-	SNDRV_CHMAP_LAST = SNDRV_CHMAP_TRC,
-};
-
-#define SNDRV_CHMAP_POSITION_MASK	0xffff
-#define SNDRV_CHMAP_PHASE_INVERSE	(0x01 << 16)
-#define SNDRV_CHMAP_DRIVER_SPEC		(0x02 << 16)
-
-#define SNDRV_PCM_IOCTL_PVERSION	_IOR('A', 0x00, int)
-#define SNDRV_PCM_IOCTL_INFO		_IOR('A', 0x01, struct snd_pcm_info)
-#define SNDRV_PCM_IOCTL_TSTAMP		_IOW('A', 0x02, int)
-#define SNDRV_PCM_IOCTL_TTSTAMP		_IOW('A', 0x03, int)
-#define SNDRV_PCM_IOCTL_HW_REFINE	_IOWR('A', 0x10, struct snd_pcm_hw_params)
-#define SNDRV_PCM_IOCTL_HW_PARAMS	_IOWR('A', 0x11, struct snd_pcm_hw_params)
-#define SNDRV_PCM_IOCTL_HW_FREE		_IO('A', 0x12)
-#define SNDRV_PCM_IOCTL_SW_PARAMS	_IOWR('A', 0x13, struct snd_pcm_sw_params)
-#define SNDRV_PCM_IOCTL_STATUS		_IOR('A', 0x20, struct snd_pcm_status)
-#define SNDRV_PCM_IOCTL_DELAY		_IOR('A', 0x21, snd_pcm_sframes_t)
-#define SNDRV_PCM_IOCTL_HWSYNC		_IO('A', 0x22)
-#define SNDRV_PCM_IOCTL_SYNC_PTR	_IOWR('A', 0x23, struct snd_pcm_sync_ptr)
-#define SNDRV_PCM_IOCTL_CHANNEL_INFO	_IOR('A', 0x32, struct snd_pcm_channel_info)
-#define SNDRV_PCM_IOCTL_PREPARE		_IO('A', 0x40)
-#define SNDRV_PCM_IOCTL_RESET		_IO('A', 0x41)
-#define SNDRV_PCM_IOCTL_START		_IO('A', 0x42)
-#define SNDRV_PCM_IOCTL_DROP		_IO('A', 0x43)
-#define SNDRV_PCM_IOCTL_DRAIN		_IO('A', 0x44)
-#define SNDRV_PCM_IOCTL_PAUSE		_IOW('A', 0x45, int)
-#define SNDRV_PCM_IOCTL_REWIND		_IOW('A', 0x46, snd_pcm_uframes_t)
-#define SNDRV_PCM_IOCTL_RESUME		_IO('A', 0x47)
-#define SNDRV_PCM_IOCTL_XRUN		_IO('A', 0x48)
-#define SNDRV_PCM_IOCTL_FORWARD		_IOW('A', 0x49, snd_pcm_uframes_t)
-#define SNDRV_PCM_IOCTL_WRITEI_FRAMES	_IOW('A', 0x50, struct snd_xferi)
-#define SNDRV_PCM_IOCTL_READI_FRAMES	_IOR('A', 0x51, struct snd_xferi)
-#define SNDRV_PCM_IOCTL_WRITEN_FRAMES	_IOW('A', 0x52, struct snd_xfern)
-#define SNDRV_PCM_IOCTL_READN_FRAMES	_IOR('A', 0x53, struct snd_xfern)
-#define SNDRV_PCM_IOCTL_LINK		_IOW('A', 0x60, int)
-#define SNDRV_PCM_IOCTL_UNLINK		_IO('A', 0x61)
-
-/*****************************************************************************
- *                                                                           *
- *                            MIDI v1.0 interface                            *
- *                                                                           *
- *****************************************************************************/
-
-/*
- *  Raw MIDI section - /dev/snd/midi??
- */
-
-#define SNDRV_RAWMIDI_VERSION		SNDRV_PROTOCOL_VERSION(2, 0, 0)
-
-enum {
-	SNDRV_RAWMIDI_STREAM_OUTPUT = 0,
-	SNDRV_RAWMIDI_STREAM_INPUT,
-	SNDRV_RAWMIDI_STREAM_LAST = SNDRV_RAWMIDI_STREAM_INPUT,
-};
-
-#define SNDRV_RAWMIDI_INFO_OUTPUT		0x00000001
-#define SNDRV_RAWMIDI_INFO_INPUT		0x00000002
-#define SNDRV_RAWMIDI_INFO_DUPLEX		0x00000004
-
-struct snd_rawmidi_info {
-	unsigned int device;		/* RO/WR (control): device number */
-	unsigned int subdevice;		/* RO/WR (control): subdevice number */
-	int stream;			/* WR: stream */
-	int card;			/* R: card number */
-	unsigned int flags;		/* SNDRV_RAWMIDI_INFO_XXXX */
-	unsigned char id[64];		/* ID (user selectable) */
-	unsigned char name[80];		/* name of device */
-	unsigned char subname[32];	/* name of active or selected subdevice */
-	unsigned int subdevices_count;
-	unsigned int subdevices_avail;
-	unsigned char reserved[64];	/* reserved for future use */
-};
-
-struct snd_rawmidi_params {
-	int stream;
-	size_t buffer_size;		/* queue size in bytes */
-	size_t avail_min;		/* minimum avail bytes for wakeup */
-	unsigned int no_active_sensing: 1; /* do not send active sensing byte in close() */
-	unsigned char reserved[16];	/* reserved for future use */
-};
-
-struct snd_rawmidi_status {
-	int stream;
-	struct timespec tstamp;		/* Timestamp */
-	size_t avail;			/* available bytes */
-	size_t xruns;			/* count of overruns since last status (in bytes) */
-	unsigned char reserved[16];	/* reserved for future use */
-};
-
-#define SNDRV_RAWMIDI_IOCTL_PVERSION	_IOR('W', 0x00, int)
-#define SNDRV_RAWMIDI_IOCTL_INFO	_IOR('W', 0x01, struct snd_rawmidi_info)
-#define SNDRV_RAWMIDI_IOCTL_PARAMS	_IOWR('W', 0x10, struct snd_rawmidi_params)
-#define SNDRV_RAWMIDI_IOCTL_STATUS	_IOWR('W', 0x20, struct snd_rawmidi_status)
-#define SNDRV_RAWMIDI_IOCTL_DROP	_IOW('W', 0x30, int)
-#define SNDRV_RAWMIDI_IOCTL_DRAIN	_IOW('W', 0x31, int)
-
-/*
- *  Timer section - /dev/snd/timer
- */
-
-#define SNDRV_TIMER_VERSION		SNDRV_PROTOCOL_VERSION(2, 0, 6)
-
-enum {
-	SNDRV_TIMER_CLASS_NONE = -1,
-	SNDRV_TIMER_CLASS_SLAVE = 0,
-	SNDRV_TIMER_CLASS_GLOBAL,
-	SNDRV_TIMER_CLASS_CARD,
-	SNDRV_TIMER_CLASS_PCM,
-	SNDRV_TIMER_CLASS_LAST = SNDRV_TIMER_CLASS_PCM,
-};
-
-/* slave timer classes */
-enum {
-	SNDRV_TIMER_SCLASS_NONE = 0,
-	SNDRV_TIMER_SCLASS_APPLICATION,
-	SNDRV_TIMER_SCLASS_SEQUENCER,		/* alias */
-	SNDRV_TIMER_SCLASS_OSS_SEQUENCER,	/* alias */
-	SNDRV_TIMER_SCLASS_LAST = SNDRV_TIMER_SCLASS_OSS_SEQUENCER,
-};
-
-/* global timers (device member) */
-#define SNDRV_TIMER_GLOBAL_SYSTEM	0
-#define SNDRV_TIMER_GLOBAL_RTC		1
-#define SNDRV_TIMER_GLOBAL_HPET		2
-#define SNDRV_TIMER_GLOBAL_HRTIMER	3
-
-/* info flags */
-#define SNDRV_TIMER_FLG_SLAVE		(1<<0)	/* cannot be controlled */
-
-struct snd_timer_id {
-	int dev_class;
-	int dev_sclass;
-	int card;
-	int device;
-	int subdevice;
-};
-
-struct snd_timer_ginfo {
-	struct snd_timer_id tid;	/* requested timer ID */
-	unsigned int flags;		/* timer flags - SNDRV_TIMER_FLG_* */
-	int card;			/* card number */
-	unsigned char id[64];		/* timer identification */
-	unsigned char name[80];		/* timer name */
-	unsigned long reserved0;	/* reserved for future use */
-	unsigned long resolution;	/* average period resolution in ns */
-	unsigned long resolution_min;	/* minimal period resolution in ns */
-	unsigned long resolution_max;	/* maximal period resolution in ns */
-	unsigned int clients;		/* active timer clients */
-	unsigned char reserved[32];
-};
-
-struct snd_timer_gparams {
-	struct snd_timer_id tid;	/* requested timer ID */
-	unsigned long period_num;	/* requested precise period duration (in seconds) - numerator */
-	unsigned long period_den;	/* requested precise period duration (in seconds) - denominator */
-	unsigned char reserved[32];
-};
-
-struct snd_timer_gstatus {
-	struct snd_timer_id tid;	/* requested timer ID */
-	unsigned long resolution;	/* current period resolution in ns */
-	unsigned long resolution_num;	/* precise current period resolution (in seconds) - numerator */
-	unsigned long resolution_den;	/* precise current period resolution (in seconds) - denominator */
-	unsigned char reserved[32];
-};
-
-struct snd_timer_select {
-	struct snd_timer_id id;	/* bind to timer ID */
-	unsigned char reserved[32];	/* reserved */
-};
-
-struct snd_timer_info {
-	unsigned int flags;		/* timer flags - SNDRV_TIMER_FLG_* */
-	int card;			/* card number */
-	unsigned char id[64];		/* timer identificator */
-	unsigned char name[80];		/* timer name */
-	unsigned long reserved0;	/* reserved for future use */
-	unsigned long resolution;	/* average period resolution in ns */
-	unsigned char reserved[64];	/* reserved */
-};
-
-#define SNDRV_TIMER_PSFLG_AUTO		(1<<0)	/* auto start, otherwise one-shot */
-#define SNDRV_TIMER_PSFLG_EXCLUSIVE	(1<<1)	/* exclusive use, precise start/stop/pause/continue */
-#define SNDRV_TIMER_PSFLG_EARLY_EVENT	(1<<2)	/* write early event to the poll queue */
-
-struct snd_timer_params {
-	unsigned int flags;		/* flags - SNDRV_MIXER_PSFLG_* */
-	unsigned int ticks;		/* requested resolution in ticks */
-	unsigned int queue_size;	/* total size of queue (32-1024) */
-	unsigned int reserved0;		/* reserved, was: failure locations */
-	unsigned int filter;		/* event filter (bitmask of SNDRV_TIMER_EVENT_*) */
-	unsigned char reserved[60];	/* reserved */
-};
-
-struct snd_timer_status {
-	struct timespec tstamp;		/* Timestamp - last update */
-	unsigned int resolution;	/* current period resolution in ns */
-	unsigned int lost;		/* counter of master tick lost */
-	unsigned int overrun;		/* count of read queue overruns */
-	unsigned int queue;		/* used queue size */
-	unsigned char reserved[64];	/* reserved */
-};
-
-#define SNDRV_TIMER_IOCTL_PVERSION	_IOR('T', 0x00, int)
-#define SNDRV_TIMER_IOCTL_NEXT_DEVICE	_IOWR('T', 0x01, struct snd_timer_id)
-#define SNDRV_TIMER_IOCTL_TREAD		_IOW('T', 0x02, int)
-#define SNDRV_TIMER_IOCTL_GINFO		_IOWR('T', 0x03, struct snd_timer_ginfo)
-#define SNDRV_TIMER_IOCTL_GPARAMS	_IOW('T', 0x04, struct snd_timer_gparams)
-#define SNDRV_TIMER_IOCTL_GSTATUS	_IOWR('T', 0x05, struct snd_timer_gstatus)
-#define SNDRV_TIMER_IOCTL_SELECT	_IOW('T', 0x10, struct snd_timer_select)
-#define SNDRV_TIMER_IOCTL_INFO		_IOR('T', 0x11, struct snd_timer_info)
-#define SNDRV_TIMER_IOCTL_PARAMS	_IOW('T', 0x12, struct snd_timer_params)
-#define SNDRV_TIMER_IOCTL_STATUS	_IOR('T', 0x14, struct snd_timer_status)
-/* The following four ioctls are changed since 1.0.9 due to confliction */
-#define SNDRV_TIMER_IOCTL_START		_IO('T', 0xa0)
-#define SNDRV_TIMER_IOCTL_STOP		_IO('T', 0xa1)
-#define SNDRV_TIMER_IOCTL_CONTINUE	_IO('T', 0xa2)
-#define SNDRV_TIMER_IOCTL_PAUSE		_IO('T', 0xa3)
-
-struct snd_timer_read {
-	unsigned int resolution;
-	unsigned int ticks;
-};
-
-enum {
-	SNDRV_TIMER_EVENT_RESOLUTION = 0,	/* val = resolution in ns */
-	SNDRV_TIMER_EVENT_TICK,			/* val = ticks */
-	SNDRV_TIMER_EVENT_START,		/* val = resolution in ns */
-	SNDRV_TIMER_EVENT_STOP,			/* val = 0 */
-	SNDRV_TIMER_EVENT_CONTINUE,		/* val = resolution in ns */
-	SNDRV_TIMER_EVENT_PAUSE,		/* val = 0 */
-	SNDRV_TIMER_EVENT_EARLY,		/* val = 0, early event */
-	SNDRV_TIMER_EVENT_SUSPEND,		/* val = 0 */
-	SNDRV_TIMER_EVENT_RESUME,		/* val = resolution in ns */
-	/* master timer events for slave timer instances */
-	SNDRV_TIMER_EVENT_MSTART = SNDRV_TIMER_EVENT_START + 10,
-	SNDRV_TIMER_EVENT_MSTOP = SNDRV_TIMER_EVENT_STOP + 10,
-	SNDRV_TIMER_EVENT_MCONTINUE = SNDRV_TIMER_EVENT_CONTINUE + 10,
-	SNDRV_TIMER_EVENT_MPAUSE = SNDRV_TIMER_EVENT_PAUSE + 10,
-	SNDRV_TIMER_EVENT_MSUSPEND = SNDRV_TIMER_EVENT_SUSPEND + 10,
-	SNDRV_TIMER_EVENT_MRESUME = SNDRV_TIMER_EVENT_RESUME + 10,
-};
-
-struct snd_timer_tread {
-	int event;
-	struct timespec tstamp;
-	unsigned int val;
-};
-
-/****************************************************************************
- *                                                                          *
- *        Section for driver control interface - /dev/snd/control?          *
- *                                                                          *
- ****************************************************************************/
-
-#define SNDRV_CTL_VERSION		SNDRV_PROTOCOL_VERSION(2, 0, 7)
-
-struct snd_ctl_card_info {
-	int card;			/* card number */
-	int pad;			/* reserved for future (was type) */
-	unsigned char id[16];		/* ID of card (user selectable) */
-	unsigned char driver[16];	/* Driver name */
-	unsigned char name[32];		/* Short name of soundcard */
-	unsigned char longname[80];	/* name + info text about soundcard */
-	unsigned char reserved_[16];	/* reserved for future (was ID of mixer) */
-	unsigned char mixername[80];	/* visual mixer identification */
-	unsigned char components[128];	/* card components / fine identification, delimited with one space (AC97 etc..) */
-};
-
-typedef int __bitwise snd_ctl_elem_type_t;
-#define	SNDRV_CTL_ELEM_TYPE_NONE	((__force snd_ctl_elem_type_t) 0) /* invalid */
-#define	SNDRV_CTL_ELEM_TYPE_BOOLEAN	((__force snd_ctl_elem_type_t) 1) /* boolean type */
-#define	SNDRV_CTL_ELEM_TYPE_INTEGER	((__force snd_ctl_elem_type_t) 2) /* integer type */
-#define	SNDRV_CTL_ELEM_TYPE_ENUMERATED	((__force snd_ctl_elem_type_t) 3) /* enumerated type */
-#define	SNDRV_CTL_ELEM_TYPE_BYTES	((__force snd_ctl_elem_type_t) 4) /* byte array */
-#define	SNDRV_CTL_ELEM_TYPE_IEC958	((__force snd_ctl_elem_type_t) 5) /* IEC958 (S/PDIF) setup */
-#define	SNDRV_CTL_ELEM_TYPE_INTEGER64	((__force snd_ctl_elem_type_t) 6) /* 64-bit integer type */
-#define	SNDRV_CTL_ELEM_TYPE_LAST	SNDRV_CTL_ELEM_TYPE_INTEGER64
-
-typedef int __bitwise snd_ctl_elem_iface_t;
-#define	SNDRV_CTL_ELEM_IFACE_CARD	((__force snd_ctl_elem_iface_t) 0) /* global control */
-#define	SNDRV_CTL_ELEM_IFACE_HWDEP	((__force snd_ctl_elem_iface_t) 1) /* hardware dependent device */
-#define	SNDRV_CTL_ELEM_IFACE_MIXER	((__force snd_ctl_elem_iface_t) 2) /* virtual mixer device */
-#define	SNDRV_CTL_ELEM_IFACE_PCM	((__force snd_ctl_elem_iface_t) 3) /* PCM device */
-#define	SNDRV_CTL_ELEM_IFACE_RAWMIDI	((__force snd_ctl_elem_iface_t) 4) /* RawMidi device */
-#define	SNDRV_CTL_ELEM_IFACE_TIMER	((__force snd_ctl_elem_iface_t) 5) /* timer device */
-#define	SNDRV_CTL_ELEM_IFACE_SEQUENCER	((__force snd_ctl_elem_iface_t) 6) /* sequencer client */
-#define	SNDRV_CTL_ELEM_IFACE_LAST	SNDRV_CTL_ELEM_IFACE_SEQUENCER
-
-#define SNDRV_CTL_ELEM_ACCESS_READ		(1<<0)
-#define SNDRV_CTL_ELEM_ACCESS_WRITE		(1<<1)
-#define SNDRV_CTL_ELEM_ACCESS_READWRITE		(SNDRV_CTL_ELEM_ACCESS_READ|SNDRV_CTL_ELEM_ACCESS_WRITE)
-#define SNDRV_CTL_ELEM_ACCESS_VOLATILE		(1<<2)	/* control value may be changed without a notification */
-#define SNDRV_CTL_ELEM_ACCESS_TIMESTAMP		(1<<3)	/* when was control changed */
-#define SNDRV_CTL_ELEM_ACCESS_TLV_READ		(1<<4)	/* TLV read is possible */
-#define SNDRV_CTL_ELEM_ACCESS_TLV_WRITE		(1<<5)	/* TLV write is possible */
-#define SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE	(SNDRV_CTL_ELEM_ACCESS_TLV_READ|SNDRV_CTL_ELEM_ACCESS_TLV_WRITE)
-#define SNDRV_CTL_ELEM_ACCESS_TLV_COMMAND	(1<<6)	/* TLV command is possible */
-#define SNDRV_CTL_ELEM_ACCESS_INACTIVE		(1<<8)	/* control does actually nothing, but may be updated */
-#define SNDRV_CTL_ELEM_ACCESS_LOCK		(1<<9)	/* write lock */
-#define SNDRV_CTL_ELEM_ACCESS_OWNER		(1<<10)	/* write lock owner */
-#define SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK	(1<<28)	/* kernel use a TLV callback */ 
-#define SNDRV_CTL_ELEM_ACCESS_USER		(1<<29) /* user space element */
-/* bits 30 and 31 are obsoleted (for indirect access) */
-
-/* for further details see the ACPI and PCI power management specification */
-#define SNDRV_CTL_POWER_D0		0x0000	/* full On */
-#define SNDRV_CTL_POWER_D1		0x0100	/* partial On */
-#define SNDRV_CTL_POWER_D2		0x0200	/* partial On */
-#define SNDRV_CTL_POWER_D3		0x0300	/* Off */
-#define SNDRV_CTL_POWER_D3hot		(SNDRV_CTL_POWER_D3|0x0000)	/* Off, with power */
-#define SNDRV_CTL_POWER_D3cold		(SNDRV_CTL_POWER_D3|0x0001)	/* Off, without power */
-
-struct snd_ctl_elem_id {
-	unsigned int numid;		/* numeric identifier, zero = invalid */
-	snd_ctl_elem_iface_t iface;	/* interface identifier */
-	unsigned int device;		/* device/client number */
-	unsigned int subdevice;		/* subdevice (substream) number */
-	unsigned char name[44];		/* ASCII name of item */
-	unsigned int index;		/* index of item */
-};
-
-struct snd_ctl_elem_list {
-	unsigned int offset;		/* W: first element ID to get */
-	unsigned int space;		/* W: count of element IDs to get */
-	unsigned int used;		/* R: count of element IDs set */
-	unsigned int count;		/* R: count of all elements */
-	struct snd_ctl_elem_id __user *pids; /* R: IDs */
-	unsigned char reserved[50];
-};
-
-struct snd_ctl_elem_info {
-	struct snd_ctl_elem_id id;	/* W: element ID */
-	snd_ctl_elem_type_t type;	/* R: value type - SNDRV_CTL_ELEM_TYPE_* */
-	unsigned int access;		/* R: value access (bitmask) - SNDRV_CTL_ELEM_ACCESS_* */
-	unsigned int count;		/* count of values */
-	__kernel_pid_t owner;		/* owner's PID of this control */
-	union {
-		struct {
-			long min;		/* R: minimum value */
-			long max;		/* R: maximum value */
-			long step;		/* R: step (0 variable) */
-		} integer;
-		struct {
-			long long min;		/* R: minimum value */
-			long long max;		/* R: maximum value */
-			long long step;		/* R: step (0 variable) */
-		} integer64;
-		struct {
-			unsigned int items;	/* R: number of items */
-			unsigned int item;	/* W: item number */
-			char name[64];		/* R: value name */
-			__u64 names_ptr;	/* W: names list (ELEM_ADD only) */
-			unsigned int names_length;
-		} enumerated;
-		unsigned char reserved[128];
-	} value;
-	union {
-		unsigned short d[4];		/* dimensions */
-		unsigned short *d_ptr;		/* indirect - obsoleted */
-	} dimen;
-	unsigned char reserved[64-4*sizeof(unsigned short)];
-};
-
-struct snd_ctl_elem_value {
-	struct snd_ctl_elem_id id;	/* W: element ID */
-	unsigned int indirect: 1;	/* W: indirect access - obsoleted */
-	union {
-		union {
-			long value[128];
-			long *value_ptr;	/* obsoleted */
-		} integer;
-		union {
-			long long value[64];
-			long long *value_ptr;	/* obsoleted */
-		} integer64;
-		union {
-			unsigned int item[128];
-			unsigned int *item_ptr;	/* obsoleted */
-		} enumerated;
-		union {
-			unsigned char data[512];
-			unsigned char *data_ptr;	/* obsoleted */
-		} bytes;
-		struct snd_aes_iec958 iec958;
-	} value;		/* RO */
-	struct timespec tstamp;
-	unsigned char reserved[128-sizeof(struct timespec)];
-};
-
-struct snd_ctl_tlv {
-	unsigned int numid;	/* control element numeric identification */
-	unsigned int length;	/* in bytes aligned to 4 */
-	unsigned int tlv[0];	/* first TLV */
-};
-
-#define SNDRV_CTL_IOCTL_PVERSION	_IOR('U', 0x00, int)
-#define SNDRV_CTL_IOCTL_CARD_INFO	_IOR('U', 0x01, struct snd_ctl_card_info)
-#define SNDRV_CTL_IOCTL_ELEM_LIST	_IOWR('U', 0x10, struct snd_ctl_elem_list)
-#define SNDRV_CTL_IOCTL_ELEM_INFO	_IOWR('U', 0x11, struct snd_ctl_elem_info)
-#define SNDRV_CTL_IOCTL_ELEM_READ	_IOWR('U', 0x12, struct snd_ctl_elem_value)
-#define SNDRV_CTL_IOCTL_ELEM_WRITE	_IOWR('U', 0x13, struct snd_ctl_elem_value)
-#define SNDRV_CTL_IOCTL_ELEM_LOCK	_IOW('U', 0x14, struct snd_ctl_elem_id)
-#define SNDRV_CTL_IOCTL_ELEM_UNLOCK	_IOW('U', 0x15, struct snd_ctl_elem_id)
-#define SNDRV_CTL_IOCTL_SUBSCRIBE_EVENTS _IOWR('U', 0x16, int)
-#define SNDRV_CTL_IOCTL_ELEM_ADD	_IOWR('U', 0x17, struct snd_ctl_elem_info)
-#define SNDRV_CTL_IOCTL_ELEM_REPLACE	_IOWR('U', 0x18, struct snd_ctl_elem_info)
-#define SNDRV_CTL_IOCTL_ELEM_REMOVE	_IOWR('U', 0x19, struct snd_ctl_elem_id)
-#define SNDRV_CTL_IOCTL_TLV_READ	_IOWR('U', 0x1a, struct snd_ctl_tlv)
-#define SNDRV_CTL_IOCTL_TLV_WRITE	_IOWR('U', 0x1b, struct snd_ctl_tlv)
-#define SNDRV_CTL_IOCTL_TLV_COMMAND	_IOWR('U', 0x1c, struct snd_ctl_tlv)
-#define SNDRV_CTL_IOCTL_HWDEP_NEXT_DEVICE _IOWR('U', 0x20, int)
-#define SNDRV_CTL_IOCTL_HWDEP_INFO	_IOR('U', 0x21, struct snd_hwdep_info)
-#define SNDRV_CTL_IOCTL_PCM_NEXT_DEVICE	_IOR('U', 0x30, int)
-#define SNDRV_CTL_IOCTL_PCM_INFO	_IOWR('U', 0x31, struct snd_pcm_info)
-#define SNDRV_CTL_IOCTL_PCM_PREFER_SUBDEVICE _IOW('U', 0x32, int)
-#define SNDRV_CTL_IOCTL_RAWMIDI_NEXT_DEVICE _IOWR('U', 0x40, int)
-#define SNDRV_CTL_IOCTL_RAWMIDI_INFO	_IOWR('U', 0x41, struct snd_rawmidi_info)
-#define SNDRV_CTL_IOCTL_RAWMIDI_PREFER_SUBDEVICE _IOW('U', 0x42, int)
-#define SNDRV_CTL_IOCTL_POWER		_IOWR('U', 0xd0, int)
-#define SNDRV_CTL_IOCTL_POWER_STATE	_IOR('U', 0xd1, int)
-
-/*
- *  Read interface.
- */
-
-enum sndrv_ctl_event_type {
-	SNDRV_CTL_EVENT_ELEM = 0,
-	SNDRV_CTL_EVENT_LAST = SNDRV_CTL_EVENT_ELEM,
-};
-
-#define SNDRV_CTL_EVENT_MASK_VALUE	(1<<0)	/* element value was changed */
-#define SNDRV_CTL_EVENT_MASK_INFO	(1<<1)	/* element info was changed */
-#define SNDRV_CTL_EVENT_MASK_ADD	(1<<2)	/* element was added */
-#define SNDRV_CTL_EVENT_MASK_TLV	(1<<3)	/* element TLV tree was changed */
-#define SNDRV_CTL_EVENT_MASK_REMOVE	(~0U)	/* element was removed */
-
-struct snd_ctl_event {
-	int type;	/* event type - SNDRV_CTL_EVENT_* */
-	union {
-		struct {
-			unsigned int mask;
-			struct snd_ctl_elem_id id;
-		} elem;
-		unsigned char data8[60];
-	} data;
-};
-
-/*
- *  Control names
- */
-
-#define SNDRV_CTL_NAME_NONE				""
-#define SNDRV_CTL_NAME_PLAYBACK				"Playback "
-#define SNDRV_CTL_NAME_CAPTURE				"Capture "
-
-#define SNDRV_CTL_NAME_IEC958_NONE			""
-#define SNDRV_CTL_NAME_IEC958_SWITCH			"Switch"
-#define SNDRV_CTL_NAME_IEC958_VOLUME			"Volume"
-#define SNDRV_CTL_NAME_IEC958_DEFAULT			"Default"
-#define SNDRV_CTL_NAME_IEC958_MASK			"Mask"
-#define SNDRV_CTL_NAME_IEC958_CON_MASK			"Con Mask"
-#define SNDRV_CTL_NAME_IEC958_PRO_MASK			"Pro Mask"
-#define SNDRV_CTL_NAME_IEC958_PCM_STREAM		"PCM Stream"
-#define SNDRV_CTL_NAME_IEC958(expl,direction,what)	"IEC958 " expl SNDRV_CTL_NAME_##direction SNDRV_CTL_NAME_IEC958_##what
-
+#include <uapi/sound/asound.h>
 #endif /* __SOUND_ASOUND_H */
diff --git a/include/sound/cs4271.h b/include/sound/cs4271.h
index 50a059e..6d9e15e 100644
--- a/include/sound/cs4271.h
+++ b/include/sound/cs4271.h
@@ -19,6 +19,7 @@
 
 struct cs4271_platform_data {
 	int gpio_nreset;	/* GPIO driving Reset pin, if any */
+	int amutec_eq_bmutec:1;	/* flag to enable AMUTEC=BMUTEC */
 };
 
 #endif /* __CS4271_H */
diff --git a/include/sound/emu10k1.h b/include/sound/emu10k1.h
index 1a33f48..f841ba4 100644
--- a/include/sound/emu10k1.h
+++ b/include/sound/emu10k1.h
@@ -1,8 +1,3 @@
-#ifndef __SOUND_EMU10K1_H
-#define __SOUND_EMU10K1_H
-
-#include <linux/types.h>
-
 /*
  *  Copyright (c) by Jaroslav Kysela <perex@perex.cz>,
  *		     Creative Labs, Inc.
@@ -24,8 +19,9 @@
  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  *
  */
+#ifndef __SOUND_EMU10K1_H
+#define __SOUND_EMU10K1_H
 
-#ifdef __KERNEL__
 
 #include <sound/pcm.h>
 #include <sound/rawmidi.h>
@@ -36,8 +32,10 @@
 #include <sound/timer.h>
 #include <linux/interrupt.h>
 #include <linux/mutex.h>
+#include <linux/firmware.h>
 
 #include <asm/io.h>
+#include <uapi/sound/emu10k1.h>
 
 /* ------------------- DEFINES -------------------- */
 
@@ -1788,6 +1786,8 @@
 	unsigned int efx_voices_mask[2];
 	unsigned int next_free_voice;
 
+	const struct firmware *firmware;
+
 #ifdef CONFIG_PM_SLEEP
 	unsigned int *saved_ptr;
 	unsigned int *saved_gpr;
@@ -1796,6 +1796,7 @@
 	unsigned int *saved_icode;
 	unsigned int *p16v_saved;
 	unsigned int saved_a_iocfg, saved_hcfg;
+	bool suspend;
 #endif
 
 };
@@ -1899,350 +1900,4 @@
 int snd_emu10k1_fx8010_unregister_irq_handler(struct snd_emu10k1 *emu,
 					      struct snd_emu10k1_fx8010_irq *irq);
 
-#endif /* __KERNEL__ */
-
-/*
- * ---- FX8010 ----
- */
-
-#define EMU10K1_CARD_CREATIVE			0x00000000
-#define EMU10K1_CARD_EMUAPS			0x00000001
-
-#define EMU10K1_FX8010_PCM_COUNT		8
-
-/* instruction set */
-#define iMAC0	 0x00	/* R = A + (X * Y >> 31)   ; saturation */
-#define iMAC1	 0x01	/* R = A + (-X * Y >> 31)  ; saturation */
-#define iMAC2	 0x02	/* R = A + (X * Y >> 31)   ; wraparound */
-#define iMAC3	 0x03	/* R = A + (-X * Y >> 31)  ; wraparound */
-#define iMACINT0 0x04	/* R = A + X * Y	   ; saturation */
-#define iMACINT1 0x05	/* R = A + X * Y	   ; wraparound (31-bit) */
-#define iACC3	 0x06	/* R = A + X + Y	   ; saturation */
-#define iMACMV   0x07	/* R = A, acc += X * Y >> 31 */
-#define iANDXOR  0x08	/* R = (A & X) ^ Y */
-#define iTSTNEG  0x09	/* R = (A >= Y) ? X : ~X */
-#define iLIMITGE 0x0a	/* R = (A >= Y) ? X : Y */
-#define iLIMITLT 0x0b	/* R = (A < Y) ? X : Y */
-#define iLOG	 0x0c	/* R = linear_data, A (log_data), X (max_exp), Y (format_word) */
-#define iEXP	 0x0d	/* R = log_data, A (linear_data), X (max_exp), Y (format_word) */
-#define iINTERP  0x0e	/* R = A + (X * (Y - A) >> 31)  ; saturation */
-#define iSKIP    0x0f	/* R = A (cc_reg), X (count), Y (cc_test) */
-
-/* GPRs */
-#define FXBUS(x)	(0x00 + (x))	/* x = 0x00 - 0x0f */
-#define EXTIN(x)	(0x10 + (x))	/* x = 0x00 - 0x0f */
-#define EXTOUT(x)	(0x20 + (x))	/* x = 0x00 - 0x0f physical outs -> FXWC low 16 bits */
-#define FXBUS2(x)	(0x30 + (x))	/* x = 0x00 - 0x0f copies of fx buses for capture -> FXWC high 16 bits */
-					/* NB: 0x31 and 0x32 are shared with Center/LFE on SB live 5.1 */
-
-#define C_00000000	0x40
-#define C_00000001	0x41
-#define C_00000002	0x42
-#define C_00000003	0x43
-#define C_00000004	0x44
-#define C_00000008	0x45
-#define C_00000010	0x46
-#define C_00000020	0x47
-#define C_00000100	0x48
-#define C_00010000	0x49
-#define C_00080000	0x4a
-#define C_10000000	0x4b
-#define C_20000000	0x4c
-#define C_40000000	0x4d
-#define C_80000000	0x4e
-#define C_7fffffff	0x4f
-#define C_ffffffff	0x50
-#define C_fffffffe	0x51
-#define C_c0000000	0x52
-#define C_4f1bbcdc	0x53
-#define C_5a7ef9db	0x54
-#define C_00100000	0x55		/* ?? */
-#define GPR_ACCU	0x56		/* ACCUM, accumulator */
-#define GPR_COND	0x57		/* CCR, condition register */
-#define GPR_NOISE0	0x58		/* noise source */
-#define GPR_NOISE1	0x59		/* noise source */
-#define GPR_IRQ		0x5a		/* IRQ register */
-#define GPR_DBAC	0x5b		/* TRAM Delay Base Address Counter */
-#define GPR(x)		(FXGPREGBASE + (x)) /* free GPRs: x = 0x00 - 0xff */
-#define ITRAM_DATA(x)	(TANKMEMDATAREGBASE + 0x00 + (x)) /* x = 0x00 - 0x7f */
-#define ETRAM_DATA(x)	(TANKMEMDATAREGBASE + 0x80 + (x)) /* x = 0x00 - 0x1f */
-#define ITRAM_ADDR(x)	(TANKMEMADDRREGBASE + 0x00 + (x)) /* x = 0x00 - 0x7f */
-#define ETRAM_ADDR(x)	(TANKMEMADDRREGBASE + 0x80 + (x)) /* x = 0x00 - 0x1f */
-
-#define A_ITRAM_DATA(x)	(TANKMEMDATAREGBASE + 0x00 + (x)) /* x = 0x00 - 0xbf */
-#define A_ETRAM_DATA(x)	(TANKMEMDATAREGBASE + 0xc0 + (x)) /* x = 0x00 - 0x3f */
-#define A_ITRAM_ADDR(x)	(TANKMEMADDRREGBASE + 0x00 + (x)) /* x = 0x00 - 0xbf */
-#define A_ETRAM_ADDR(x)	(TANKMEMADDRREGBASE + 0xc0 + (x)) /* x = 0x00 - 0x3f */
-#define A_ITRAM_CTL(x)	(A_TANKMEMCTLREGBASE + 0x00 + (x)) /* x = 0x00 - 0xbf */
-#define A_ETRAM_CTL(x)	(A_TANKMEMCTLREGBASE + 0xc0 + (x)) /* x = 0x00 - 0x3f */
-
-#define A_FXBUS(x)	(0x00 + (x))	/* x = 0x00 - 0x3f FX buses */
-#define A_EXTIN(x)	(0x40 + (x))	/* x = 0x00 - 0x0f physical ins */
-#define A_P16VIN(x)	(0x50 + (x))	/* x = 0x00 - 0x0f p16v ins (A2 only) "EMU32 inputs" */
-#define A_EXTOUT(x)	(0x60 + (x))	/* x = 0x00 - 0x1f physical outs -> A_FXWC1 0x79-7f unknown   */
-#define A_FXBUS2(x)	(0x80 + (x))	/* x = 0x00 - 0x1f extra outs used for EFX capture -> A_FXWC2 */
-#define A_EMU32OUTH(x)	(0xa0 + (x))	/* x = 0x00 - 0x0f "EMU32_OUT_10 - _1F" - ??? */
-#define A_EMU32OUTL(x)	(0xb0 + (x))	/* x = 0x00 - 0x0f "EMU32_OUT_1 - _F" - ??? */
-#define A3_EMU32IN(x)	(0x160 + (x))	/* x = 0x00 - 0x3f "EMU32_IN_00 - _3F" - Only when .device = 0x0008 */
-#define A3_EMU32OUT(x)	(0x1E0 + (x))	/* x = 0x00 - 0x0f "EMU32_OUT_00 - _3F" - Only when .device = 0x0008 */
-#define A_GPR(x)	(A_FXGPREGBASE + (x))
-
-/* cc_reg constants */
-#define CC_REG_NORMALIZED C_00000001
-#define CC_REG_BORROW	C_00000002
-#define CC_REG_MINUS	C_00000004
-#define CC_REG_ZERO	C_00000008
-#define CC_REG_SATURATE	C_00000010
-#define CC_REG_NONZERO	C_00000100
-
-/* FX buses */
-#define FXBUS_PCM_LEFT		0x00
-#define FXBUS_PCM_RIGHT		0x01
-#define FXBUS_PCM_LEFT_REAR	0x02
-#define FXBUS_PCM_RIGHT_REAR	0x03
-#define FXBUS_MIDI_LEFT		0x04
-#define FXBUS_MIDI_RIGHT	0x05
-#define FXBUS_PCM_CENTER	0x06
-#define FXBUS_PCM_LFE		0x07
-#define FXBUS_PCM_LEFT_FRONT	0x08
-#define FXBUS_PCM_RIGHT_FRONT	0x09
-#define FXBUS_MIDI_REVERB	0x0c
-#define FXBUS_MIDI_CHORUS	0x0d
-#define FXBUS_PCM_LEFT_SIDE	0x0e
-#define FXBUS_PCM_RIGHT_SIDE	0x0f
-#define FXBUS_PT_LEFT		0x14
-#define FXBUS_PT_RIGHT		0x15
-
-/* Inputs */
-#define EXTIN_AC97_L	   0x00	/* AC'97 capture channel - left */
-#define EXTIN_AC97_R	   0x01	/* AC'97 capture channel - right */
-#define EXTIN_SPDIF_CD_L   0x02	/* internal S/PDIF CD - onboard - left */
-#define EXTIN_SPDIF_CD_R   0x03	/* internal S/PDIF CD - onboard - right */
-#define EXTIN_ZOOM_L	   0x04	/* Zoom Video I2S - left */
-#define EXTIN_ZOOM_R	   0x05	/* Zoom Video I2S - right */
-#define EXTIN_TOSLINK_L	   0x06	/* LiveDrive - TOSLink Optical - left */
-#define EXTIN_TOSLINK_R    0x07	/* LiveDrive - TOSLink Optical - right */
-#define EXTIN_LINE1_L	   0x08	/* LiveDrive - Line/Mic 1 - left */
-#define EXTIN_LINE1_R	   0x09	/* LiveDrive - Line/Mic 1 - right */
-#define EXTIN_COAX_SPDIF_L 0x0a	/* LiveDrive - Coaxial S/PDIF - left */
-#define EXTIN_COAX_SPDIF_R 0x0b /* LiveDrive - Coaxial S/PDIF - right */
-#define EXTIN_LINE2_L	   0x0c	/* LiveDrive - Line/Mic 2 - left */
-#define EXTIN_LINE2_R	   0x0d	/* LiveDrive - Line/Mic 2 - right */
-
-/* Outputs */
-#define EXTOUT_AC97_L	   0x00	/* AC'97 playback channel - left */
-#define EXTOUT_AC97_R	   0x01	/* AC'97 playback channel - right */
-#define EXTOUT_TOSLINK_L   0x02	/* LiveDrive - TOSLink Optical - left */
-#define EXTOUT_TOSLINK_R   0x03	/* LiveDrive - TOSLink Optical - right */
-#define EXTOUT_AC97_CENTER 0x04	/* SB Live 5.1 - center */
-#define EXTOUT_AC97_LFE	   0x05 /* SB Live 5.1 - LFE */
-#define EXTOUT_HEADPHONE_L 0x06	/* LiveDrive - Headphone - left */
-#define EXTOUT_HEADPHONE_R 0x07	/* LiveDrive - Headphone - right */
-#define EXTOUT_REAR_L	   0x08	/* Rear channel - left */
-#define EXTOUT_REAR_R	   0x09	/* Rear channel - right */
-#define EXTOUT_ADC_CAP_L   0x0a	/* ADC Capture buffer - left */
-#define EXTOUT_ADC_CAP_R   0x0b	/* ADC Capture buffer - right */
-#define EXTOUT_MIC_CAP	   0x0c	/* MIC Capture buffer */
-#define EXTOUT_AC97_REAR_L 0x0d	/* SB Live 5.1 (c) 2003 - Rear Left */
-#define EXTOUT_AC97_REAR_R 0x0e	/* SB Live 5.1 (c) 2003 - Rear Right */
-#define EXTOUT_ACENTER	   0x11 /* Analog Center */
-#define EXTOUT_ALFE	   0x12 /* Analog LFE */
-
-/* Audigy Inputs */
-#define A_EXTIN_AC97_L		0x00	/* AC'97 capture channel - left */
-#define A_EXTIN_AC97_R		0x01	/* AC'97 capture channel - right */
-#define A_EXTIN_SPDIF_CD_L	0x02	/* digital CD left */
-#define A_EXTIN_SPDIF_CD_R	0x03	/* digital CD left */
-#define A_EXTIN_OPT_SPDIF_L     0x04    /* audigy drive Optical SPDIF - left */
-#define A_EXTIN_OPT_SPDIF_R     0x05    /*                              right */ 
-#define A_EXTIN_LINE2_L		0x08	/* audigy drive line2/mic2 - left */
-#define A_EXTIN_LINE2_R		0x09	/*                           right */
-#define A_EXTIN_ADC_L		0x0a    /* Philips ADC - left */
-#define A_EXTIN_ADC_R		0x0b    /*               right */
-#define A_EXTIN_AUX2_L		0x0c	/* audigy drive aux2 - left */
-#define A_EXTIN_AUX2_R		0x0d	/*                   - right */
-
-/* Audigiy Outputs */
-#define A_EXTOUT_FRONT_L	0x00	/* digital front left */
-#define A_EXTOUT_FRONT_R	0x01	/*               right */
-#define A_EXTOUT_CENTER		0x02	/* digital front center */
-#define A_EXTOUT_LFE		0x03	/* digital front lfe */
-#define A_EXTOUT_HEADPHONE_L	0x04	/* headphone audigy drive left */
-#define A_EXTOUT_HEADPHONE_R	0x05	/*                        right */
-#define A_EXTOUT_REAR_L		0x06	/* digital rear left */
-#define A_EXTOUT_REAR_R		0x07	/*              right */
-#define A_EXTOUT_AFRONT_L	0x08	/* analog front left */
-#define A_EXTOUT_AFRONT_R	0x09	/*              right */
-#define A_EXTOUT_ACENTER	0x0a	/* analog center */
-#define A_EXTOUT_ALFE		0x0b	/* analog LFE */
-#define A_EXTOUT_ASIDE_L	0x0c	/* analog side left  - Audigy 2 ZS */
-#define A_EXTOUT_ASIDE_R	0x0d	/*             right - Audigy 2 ZS */
-#define A_EXTOUT_AREAR_L	0x0e	/* analog rear left */
-#define A_EXTOUT_AREAR_R	0x0f	/*             right */
-#define A_EXTOUT_AC97_L		0x10	/* AC97 left (front) */
-#define A_EXTOUT_AC97_R		0x11	/*      right */
-#define A_EXTOUT_ADC_CAP_L	0x16	/* ADC capture buffer left */
-#define A_EXTOUT_ADC_CAP_R	0x17	/*                    right */
-#define A_EXTOUT_MIC_CAP	0x18	/* Mic capture buffer */
-
-/* Audigy constants */
-#define A_C_00000000	0xc0
-#define A_C_00000001	0xc1
-#define A_C_00000002	0xc2
-#define A_C_00000003	0xc3
-#define A_C_00000004	0xc4
-#define A_C_00000008	0xc5
-#define A_C_00000010	0xc6
-#define A_C_00000020	0xc7
-#define A_C_00000100	0xc8
-#define A_C_00010000	0xc9
-#define A_C_00000800	0xca
-#define A_C_10000000	0xcb
-#define A_C_20000000	0xcc
-#define A_C_40000000	0xcd
-#define A_C_80000000	0xce
-#define A_C_7fffffff	0xcf
-#define A_C_ffffffff	0xd0
-#define A_C_fffffffe	0xd1
-#define A_C_c0000000	0xd2
-#define A_C_4f1bbcdc	0xd3
-#define A_C_5a7ef9db	0xd4
-#define A_C_00100000	0xd5
-#define A_GPR_ACCU	0xd6		/* ACCUM, accumulator */
-#define A_GPR_COND	0xd7		/* CCR, condition register */
-#define A_GPR_NOISE0	0xd8		/* noise source */
-#define A_GPR_NOISE1	0xd9		/* noise source */
-#define A_GPR_IRQ	0xda		/* IRQ register */
-#define A_GPR_DBAC	0xdb		/* TRAM Delay Base Address Counter - internal */
-#define A_GPR_DBACE	0xde		/* TRAM Delay Base Address Counter - external */
-
-/* definitions for debug register */
-#define EMU10K1_DBG_ZC			0x80000000	/* zero tram counter */
-#define EMU10K1_DBG_SATURATION_OCCURED	0x02000000	/* saturation control */
-#define EMU10K1_DBG_SATURATION_ADDR	0x01ff0000	/* saturation address */
-#define EMU10K1_DBG_SINGLE_STEP		0x00008000	/* single step mode */
-#define EMU10K1_DBG_STEP		0x00004000	/* start single step */
-#define EMU10K1_DBG_CONDITION_CODE	0x00003e00	/* condition code */
-#define EMU10K1_DBG_SINGLE_STEP_ADDR	0x000001ff	/* single step address */
-
-/* tank memory address line */
-#ifndef __KERNEL__
-#define TANKMEMADDRREG_ADDR_MASK 0x000fffff	/* 20 bit tank address field			*/
-#define TANKMEMADDRREG_CLEAR	 0x00800000	/* Clear tank memory				*/
-#define TANKMEMADDRREG_ALIGN	 0x00400000	/* Align read or write relative to tank access	*/
-#define TANKMEMADDRREG_WRITE	 0x00200000	/* Write to tank memory				*/
-#define TANKMEMADDRREG_READ	 0x00100000	/* Read from tank memory			*/
-#endif
-
-struct snd_emu10k1_fx8010_info {
-	unsigned int internal_tram_size;	/* in samples */
-	unsigned int external_tram_size;	/* in samples */
-	char fxbus_names[16][32];		/* names of FXBUSes */
-	char extin_names[16][32];		/* names of external inputs */
-	char extout_names[32][32];		/* names of external outputs */
-	unsigned int gpr_controls;		/* count of GPR controls */
-};
-
-#define EMU10K1_GPR_TRANSLATION_NONE		0
-#define EMU10K1_GPR_TRANSLATION_TABLE100	1
-#define EMU10K1_GPR_TRANSLATION_BASS		2
-#define EMU10K1_GPR_TRANSLATION_TREBLE		3
-#define EMU10K1_GPR_TRANSLATION_ONOFF		4
-
-struct snd_emu10k1_fx8010_control_gpr {
-	struct snd_ctl_elem_id id;		/* full control ID definition */
-	unsigned int vcount;		/* visible count */
-	unsigned int count;		/* count of GPR (1..16) */
-	unsigned short gpr[32];		/* GPR number(s) */
-	unsigned int value[32];		/* initial values */
-	unsigned int min;		/* minimum range */
-	unsigned int max;		/* maximum range */
-	unsigned int translation;	/* translation type (EMU10K1_GPR_TRANSLATION*) */
-	const unsigned int *tlv;
-};
-
-/* old ABI without TLV support */
-struct snd_emu10k1_fx8010_control_old_gpr {
-	struct snd_ctl_elem_id id;
-	unsigned int vcount;
-	unsigned int count;
-	unsigned short gpr[32];
-	unsigned int value[32];
-	unsigned int min;
-	unsigned int max;
-	unsigned int translation;
-};
-
-struct snd_emu10k1_fx8010_code {
-	char name[128];
-
-	DECLARE_BITMAP(gpr_valid, 0x200); /* bitmask of valid initializers */
-	__u32 __user *gpr_map;		/* initializers */
-
-	unsigned int gpr_add_control_count; /* count of GPR controls to add/replace */
-	struct snd_emu10k1_fx8010_control_gpr __user *gpr_add_controls; /* GPR controls to add/replace */
-
-	unsigned int gpr_del_control_count; /* count of GPR controls to remove */
-	struct snd_ctl_elem_id __user *gpr_del_controls; /* IDs of GPR controls to remove */
-
-	unsigned int gpr_list_control_count; /* count of GPR controls to list */
-	unsigned int gpr_list_control_total; /* total count of GPR controls */
-	struct snd_emu10k1_fx8010_control_gpr __user *gpr_list_controls; /* listed GPR controls */
-
-	DECLARE_BITMAP(tram_valid, 0x100); /* bitmask of valid initializers */
-	__u32 __user *tram_data_map;	  /* data initializers */
-	__u32 __user *tram_addr_map;	  /* map initializers */
-
-	DECLARE_BITMAP(code_valid, 1024); /* bitmask of valid instructions */
-	__u32 __user *code;		  /* one instruction - 64 bits */
-};
-
-struct snd_emu10k1_fx8010_tram {
-	unsigned int address;		/* 31.bit == 1 -> external TRAM */
-	unsigned int size;		/* size in samples (4 bytes) */
-	unsigned int *samples;		/* pointer to samples (20-bit) */
-					/* NULL->clear memory */
-};
-
-struct snd_emu10k1_fx8010_pcm_rec {
-	unsigned int substream;		/* substream number */
-	unsigned int res1;		/* reserved */
-	unsigned int channels;		/* 16-bit channels count, zero = remove this substream */
-	unsigned int tram_start;	/* ring buffer position in TRAM (in samples) */
-	unsigned int buffer_size;	/* count of buffered samples */
-	unsigned short gpr_size;		/* GPR containing size of ringbuffer in samples (host) */
-	unsigned short gpr_ptr;		/* GPR containing current pointer in the ring buffer (host = reset, FX8010) */
-	unsigned short gpr_count;	/* GPR containing count of samples between two interrupts (host) */
-	unsigned short gpr_tmpcount;	/* GPR containing current count of samples to interrupt (host = set, FX8010) */
-	unsigned short gpr_trigger;	/* GPR containing trigger (activate) information (host) */
-	unsigned short gpr_running;	/* GPR containing info if PCM is running (FX8010) */
-	unsigned char pad;		/* reserved */
-	unsigned char etram[32];	/* external TRAM address & data (one per channel) */
-	unsigned int res2;		/* reserved */
-};
-
-#define SNDRV_EMU10K1_VERSION		SNDRV_PROTOCOL_VERSION(1, 0, 1)
-
-#define SNDRV_EMU10K1_IOCTL_INFO	_IOR ('H', 0x10, struct snd_emu10k1_fx8010_info)
-#define SNDRV_EMU10K1_IOCTL_CODE_POKE	_IOW ('H', 0x11, struct snd_emu10k1_fx8010_code)
-#define SNDRV_EMU10K1_IOCTL_CODE_PEEK	_IOWR('H', 0x12, struct snd_emu10k1_fx8010_code)
-#define SNDRV_EMU10K1_IOCTL_TRAM_SETUP	_IOW ('H', 0x20, int)
-#define SNDRV_EMU10K1_IOCTL_TRAM_POKE	_IOW ('H', 0x21, struct snd_emu10k1_fx8010_tram)
-#define SNDRV_EMU10K1_IOCTL_TRAM_PEEK	_IOWR('H', 0x22, struct snd_emu10k1_fx8010_tram)
-#define SNDRV_EMU10K1_IOCTL_PCM_POKE	_IOW ('H', 0x30, struct snd_emu10k1_fx8010_pcm_rec)
-#define SNDRV_EMU10K1_IOCTL_PCM_PEEK	_IOWR('H', 0x31, struct snd_emu10k1_fx8010_pcm_rec)
-#define SNDRV_EMU10K1_IOCTL_PVERSION	_IOR ('H', 0x40, int)
-#define SNDRV_EMU10K1_IOCTL_STOP	_IO  ('H', 0x80)
-#define SNDRV_EMU10K1_IOCTL_CONTINUE	_IO  ('H', 0x81)
-#define SNDRV_EMU10K1_IOCTL_ZERO_TRAM_COUNTER _IO ('H', 0x82)
-#define SNDRV_EMU10K1_IOCTL_SINGLE_STEP	_IOW ('H', 0x83, int)
-#define SNDRV_EMU10K1_IOCTL_DBG_READ	_IOR ('H', 0x84, int)
-
-/* typedefs for compatibility to user-space */
-typedef struct snd_emu10k1_fx8010_info emu10k1_fx8010_info_t;
-typedef struct snd_emu10k1_fx8010_control_gpr emu10k1_fx8010_control_gpr_t;
-typedef struct snd_emu10k1_fx8010_code emu10k1_fx8010_code_t;
-typedef struct snd_emu10k1_fx8010_tram emu10k1_fx8010_tram_t;
-typedef struct snd_emu10k1_fx8010_pcm_rec emu10k1_fx8010_pcm_t;
-
 #endif	/* __SOUND_EMU10K1_H */
diff --git a/include/sound/pcm.h b/include/sound/pcm.h
index 6268a41..45c1981 100644
--- a/include/sound/pcm.h
+++ b/include/sound/pcm.h
@@ -71,6 +71,8 @@
 	int (*prepare)(struct snd_pcm_substream *substream);
 	int (*trigger)(struct snd_pcm_substream *substream, int cmd);
 	snd_pcm_uframes_t (*pointer)(struct snd_pcm_substream *substream);
+	int (*wall_clock)(struct snd_pcm_substream *substream,
+			  struct timespec *audio_ts);
 	int (*copy)(struct snd_pcm_substream *substream, int channel,
 		    snd_pcm_uframes_t pos,
 		    void __user *buf, snd_pcm_uframes_t count);
@@ -281,6 +283,7 @@
 	unsigned long hw_ptr_jiffies;	/* Time when hw_ptr is updated */
 	unsigned long hw_ptr_buffer_jiffies; /* buffer time in jiffies */
 	snd_pcm_sframes_t delay;	/* extra delay; typically FIFO size */
+	u64 hw_ptr_wrap;                /* offset for hw_ptr due to boundary wrap-around */
 
 	/* -- HW params -- */
 	snd_pcm_access_t access;	/* access mode */
diff --git a/include/sound/sb16_csp.h b/include/sound/sb16_csp.h
index 7e95056..c7c7788 100644
--- a/include/sound/sb16_csp.h
+++ b/include/sound/sb16_csp.h
@@ -1,6 +1,3 @@
-#ifndef __SOUND_SB16_CSP_H
-#define __SOUND_SB16_CSP_H
-
 /*
  *  Copyright (c) 1999 by Uros Bizjak <uros@kss-loka.si>
  *                        Takashi Iwai <tiwai@suse.de>
@@ -22,106 +19,13 @@
  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  *
  */
+#ifndef __SOUND_SB16_CSP_H
+#define __SOUND_SB16_CSP_H
 
-/* CSP modes */
-#define SNDRV_SB_CSP_MODE_NONE		0x00
-#define SNDRV_SB_CSP_MODE_DSP_READ	0x01	/* Record from DSP */
-#define SNDRV_SB_CSP_MODE_DSP_WRITE	0x02	/* Play to DSP */
-#define SNDRV_SB_CSP_MODE_QSOUND		0x04	/* QSound */
-
-/* CSP load flags */
-#define SNDRV_SB_CSP_LOAD_FROMUSER	0x01
-#define SNDRV_SB_CSP_LOAD_INITBLOCK	0x02
-
-/* CSP sample width */
-#define SNDRV_SB_CSP_SAMPLE_8BIT		0x01
-#define SNDRV_SB_CSP_SAMPLE_16BIT		0x02
-
-/* CSP channels */
-#define SNDRV_SB_CSP_MONO			0x01
-#define SNDRV_SB_CSP_STEREO		0x02
-
-/* CSP rates */
-#define SNDRV_SB_CSP_RATE_8000		0x01
-#define SNDRV_SB_CSP_RATE_11025		0x02
-#define SNDRV_SB_CSP_RATE_22050		0x04
-#define SNDRV_SB_CSP_RATE_44100		0x08
-#define SNDRV_SB_CSP_RATE_ALL		0x0f
-
-/* CSP running state */
-#define SNDRV_SB_CSP_ST_IDLE		0x00
-#define SNDRV_SB_CSP_ST_LOADED		0x01
-#define SNDRV_SB_CSP_ST_RUNNING		0x02
-#define SNDRV_SB_CSP_ST_PAUSED		0x04
-#define SNDRV_SB_CSP_ST_AUTO		0x08
-#define SNDRV_SB_CSP_ST_QSOUND		0x10
-
-/* maximum QSound value (180 degrees right) */
-#define SNDRV_SB_CSP_QSOUND_MAX_RIGHT	0x20
-
-/* maximum microcode RIFF file size */
-#define SNDRV_SB_CSP_MAX_MICROCODE_FILE_SIZE	0x3000
-
-/* microcode header */
-struct snd_sb_csp_mc_header {
-	char codec_name[16];		/* id name of codec */
-	unsigned short func_req;	/* requested function */
-};
-
-/* microcode to be loaded */
-struct snd_sb_csp_microcode {
-	struct snd_sb_csp_mc_header info;
-	unsigned char data[SNDRV_SB_CSP_MAX_MICROCODE_FILE_SIZE];
-};
-
-/* start CSP with sample_width in mono/stereo */
-struct snd_sb_csp_start {
-	int sample_width;	/* sample width, look above */
-	int channels;		/* channels, look above */
-};
-
-/* CSP information */
-struct snd_sb_csp_info {
-	char codec_name[16];		/* id name of codec */
-	unsigned short func_nr;		/* function number */
-	unsigned int acc_format;	/* accepted PCM formats */
-	unsigned short acc_channels;	/* accepted channels */
-	unsigned short acc_width;	/* accepted sample width */
-	unsigned short acc_rates;	/* accepted sample rates */
-	unsigned short csp_mode;	/* CSP mode, see above */
-	unsigned short run_channels;	/* current channels  */
-	unsigned short run_width;	/* current sample width */
-	unsigned short version;		/* version id: 0x10 - 0x1f */
-	unsigned short state;		/* state bits */
-};
-
-/* HWDEP controls */
-/* get CSP information */
-#define SNDRV_SB_CSP_IOCTL_INFO		_IOR('H', 0x10, struct snd_sb_csp_info)
-/* load microcode to CSP */
-/* NOTE: struct snd_sb_csp_microcode overflows the max size (13 bits)
- * defined for some architectures like MIPS, and it leads to build errors.
- * (x86 and co have 14-bit size, thus it's valid, though.)
- * As a workaround for skipping the size-limit check, here we don't use the
- * normal _IOW() macro but _IOC() with the manual argument.
- */
-#define SNDRV_SB_CSP_IOCTL_LOAD_CODE	\
-	_IOC(_IOC_WRITE, 'H', 0x11, sizeof(struct snd_sb_csp_microcode))
-/* unload microcode from CSP */
-#define SNDRV_SB_CSP_IOCTL_UNLOAD_CODE	_IO('H', 0x12)
-/* start CSP */
-#define SNDRV_SB_CSP_IOCTL_START		_IOW('H', 0x13, struct snd_sb_csp_start)
-/* stop CSP */
-#define SNDRV_SB_CSP_IOCTL_STOP		_IO('H', 0x14)
-/* pause CSP and DMA transfer */
-#define SNDRV_SB_CSP_IOCTL_PAUSE		_IO('H', 0x15)
-/* restart CSP and DMA transfer */
-#define SNDRV_SB_CSP_IOCTL_RESTART	_IO('H', 0x16)
-
-#ifdef __KERNEL__
 #include <sound/sb.h>
 #include <sound/hwdep.h>
 #include <linux/firmware.h>
+#include <uapi/sound/sb16_csp.h>
 
 struct snd_sb_csp;
 
@@ -183,6 +87,4 @@
 };
 
 int snd_sb_csp_new(struct snd_sb *chip, int device, struct snd_hwdep ** rhwdep);
-#endif
-
 #endif /* __SOUND_SB16_CSP */
diff --git a/include/sound/sh_fsi.h b/include/sound/sh_fsi.h
index 9060103..cc1c919 100644
--- a/include/sound/sh_fsi.h
+++ b/include/sound/sh_fsi.h
@@ -26,6 +26,7 @@
  * A:  inversion
  * B:  format mode
  * C:  chip specific
+ * D:  clock selecter if master mode
  */
 
 /* A: clock inversion */
@@ -44,6 +45,11 @@
 #define SH_FSI_OPTION_MASK	0x00000F00
 #define SH_FSI_ENABLE_STREAM_MODE	(1 << 8) /* for 16bit data */
 
+/* D:  clock selecter if master mode */
+#define SH_FSI_CLK_MASK		0x0000F000
+#define SH_FSI_CLK_EXTERNAL	(0 << 12)
+#define SH_FSI_CLK_CPG		(1 << 12) /* FSIxCK + FSI-DIV */
+
 /*
  * set_rate return value
  *
diff --git a/include/sound/tlv320aic32x4.h b/include/sound/tlv320aic32x4.h
index c009f70b..24e5d99 100644
--- a/include/sound/tlv320aic32x4.h
+++ b/include/sound/tlv320aic32x4.h
@@ -26,6 +26,7 @@
 	u32 power_cfg;
 	u32 micpga_routing;
 	bool swapdacs;
+	int rstn_gpio;
 };
 
 #endif
diff --git a/include/sound/vx_core.h b/include/sound/vx_core.h
index 4f67c76..f634f8f 100644
--- a/include/sound/vx_core.h
+++ b/include/sound/vx_core.h
@@ -27,12 +27,6 @@
 #include <sound/hwdep.h>
 #include <linux/interrupt.h>
 
-#if defined(CONFIG_FW_LOADER) || defined(CONFIG_FW_LOADER_MODULE)
-#if !defined(CONFIG_USE_VXLOADER) && !defined(CONFIG_SND_VX_LIB) /* built-in kernel */
-#define SND_VX_FW_LOADER	/* use the standard firmware loader */
-#endif
-#endif
-
 struct firmware;
 struct device;
 
diff --git a/include/uapi/linux/input.h b/include/uapi/linux/input.h
index 5588285..935119c 100644
--- a/include/uapi/linux/input.h
+++ b/include/uapi/linux/input.h
@@ -851,6 +851,7 @@
 #define MSC_GESTURE		0x02
 #define MSC_RAW			0x03
 #define MSC_SCAN		0x04
+#define MSC_TIMESTAMP		0x05
 #define MSC_MAX			0x07
 #define MSC_CNT			(MSC_MAX+1)
 
diff --git a/include/uapi/linux/pci_regs.h b/include/uapi/linux/pci_regs.h
index 20ae747..6b7b6f1 100644
--- a/include/uapi/linux/pci_regs.h
+++ b/include/uapi/linux/pci_regs.h
@@ -349,7 +349,7 @@
 #define  PCI_AF_STATUS_TP	0x01
 #define PCI_CAP_AF_SIZEOF	6	/* size of AF registers */
 
-/* PCI-X registers */
+/* PCI-X registers (Type 0 (non-bridge) devices) */
 
 #define PCI_X_CMD		2	/* Modes & Features */
 #define  PCI_X_CMD_DPERR_E	0x0001	/* Data Parity Error Recovery Enable */
@@ -389,6 +389,19 @@
 #define PCI_CAP_PCIX_SIZEOF_V1	24	/* size for Version 1 */
 #define PCI_CAP_PCIX_SIZEOF_V2	PCI_CAP_PCIX_SIZEOF_V1	/* Same for v2 */
 
+/* PCI-X registers (Type 1 (bridge) devices) */
+
+#define PCI_X_BRIDGE_SSTATUS	2	/* Secondary Status */
+#define  PCI_X_SSTATUS_64BIT	0x0001	/* Secondary AD interface is 64 bits */
+#define  PCI_X_SSTATUS_133MHZ	0x0002	/* 133 MHz capable */
+#define  PCI_X_SSTATUS_FREQ	0x03c0	/* Secondary Bus Mode and Frequency */
+#define  PCI_X_SSTATUS_VERS	0x3000	/* PCI-X Capability Version */
+#define  PCI_X_SSTATUS_V1	0x1000	/* Mode 2, not Mode 1 */
+#define  PCI_X_SSTATUS_V2	0x2000	/* Mode 1 or Modes 1 and 2 */
+#define  PCI_X_SSTATUS_266MHZ	0x4000	/* 266 MHz capable */
+#define  PCI_X_SSTATUS_533MHZ	0x8000	/* 533 MHz capable */
+#define PCI_X_BRIDGE_STATUS	4	/* Bridge Status */
+
 /* PCI Bridge Subsystem ID registers */
 
 #define PCI_SSVID_VENDOR_ID     4	/* PCI-Bridge subsystem vendor id register */
@@ -456,6 +469,8 @@
 #define  PCI_EXP_LNKCAP_PN	0xff000000 /* Port Number */
 #define PCI_EXP_LNKCTL		16	/* Link Control */
 #define  PCI_EXP_LNKCTL_ASPMC	0x0003	/* ASPM Control */
+#define  PCI_EXP_LNKCTL_ASPM_L0S  0x01	/* L0s Enable */
+#define  PCI_EXP_LNKCTL_ASPM_L1   0x02	/* L1 Enable */
 #define  PCI_EXP_LNKCTL_RCB	0x0008	/* Read Completion Boundary */
 #define  PCI_EXP_LNKCTL_LD	0x0010	/* Link Disable */
 #define  PCI_EXP_LNKCTL_RL	0x0020	/* Retrain Link */
@@ -544,9 +559,9 @@
 #define  PCI_EXP_OBFF_WAKE_EN	0x6000	/* OBFF using WAKE# signaling */
 #define PCI_CAP_EXP_ENDPOINT_SIZEOF_V2	44	/* v2 endpoints end here */
 #define PCI_EXP_LNKCAP2		44	/* Link Capability 2 */
-#define  PCI_EXP_LNKCAP2_SLS_2_5GB 0x01	/* Current Link Speed 2.5GT/s */
-#define  PCI_EXP_LNKCAP2_SLS_5_0GB 0x02	/* Current Link Speed 5.0GT/s */
-#define  PCI_EXP_LNKCAP2_SLS_8_0GB 0x04	/* Current Link Speed 8.0GT/s */
+#define  PCI_EXP_LNKCAP2_SLS_2_5GB 0x02	/* Supported Link Speed 2.5GT/s */
+#define  PCI_EXP_LNKCAP2_SLS_5_0GB 0x04	/* Supported Link Speed 5.0GT/s */
+#define  PCI_EXP_LNKCAP2_SLS_8_0GB 0x08	/* Supported Link Speed 8.0GT/s */
 #define  PCI_EXP_LNKCAP2_CROSSLINK 0x100 /* Crosslink supported */
 #define PCI_EXP_LNKCTL2		48	/* Link Control 2 */
 #define PCI_EXP_LNKSTA2		50	/* Link Status 2 */
diff --git a/include/uapi/sound/Kbuild b/include/uapi/sound/Kbuild
index aafaa5a..0f7d279 100644
--- a/include/uapi/sound/Kbuild
+++ b/include/uapi/sound/Kbuild
@@ -1 +1,11 @@
 # UAPI Header export list
+header-y += asequencer.h
+header-y += asound.h
+header-y += asound_fm.h
+header-y += compress_offload.h
+header-y += compress_params.h
+header-y += emu10k1.h
+header-y += hdsp.h
+header-y += hdspm.h
+header-y += sb16_csp.h
+header-y += sfnt_info.h
diff --git a/include/uapi/sound/asequencer.h b/include/uapi/sound/asequencer.h
new file mode 100644
index 0000000..09c8a00
--- /dev/null
+++ b/include/uapi/sound/asequencer.h
@@ -0,0 +1,614 @@
+/*
+ *  Main header file for the ALSA sequencer
+ *  Copyright (c) 1998-1999 by Frank van de Pol <fvdpol@coil.demon.nl>
+ *            (c) 1998-1999 by Jaroslav Kysela <perex@perex.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., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ *
+ */
+#ifndef _UAPI__SOUND_ASEQUENCER_H
+#define _UAPI__SOUND_ASEQUENCER_H
+
+
+/** version of the sequencer */
+#define SNDRV_SEQ_VERSION SNDRV_PROTOCOL_VERSION (1, 0, 1)
+
+/**
+ * definition of sequencer event types
+ */
+
+/** system messages
+ * event data type = #snd_seq_result
+ */
+#define SNDRV_SEQ_EVENT_SYSTEM		0
+#define SNDRV_SEQ_EVENT_RESULT		1
+
+/** note messages (channel specific)
+ * event data type = #snd_seq_ev_note
+ */
+#define SNDRV_SEQ_EVENT_NOTE		5
+#define SNDRV_SEQ_EVENT_NOTEON		6
+#define SNDRV_SEQ_EVENT_NOTEOFF		7
+#define SNDRV_SEQ_EVENT_KEYPRESS	8
+	
+/** control messages (channel specific)
+ * event data type = #snd_seq_ev_ctrl
+ */
+#define SNDRV_SEQ_EVENT_CONTROLLER	10
+#define SNDRV_SEQ_EVENT_PGMCHANGE	11
+#define SNDRV_SEQ_EVENT_CHANPRESS	12
+#define SNDRV_SEQ_EVENT_PITCHBEND	13	/**< from -8192 to 8191 */
+#define SNDRV_SEQ_EVENT_CONTROL14	14	/**< 14 bit controller value */
+#define SNDRV_SEQ_EVENT_NONREGPARAM	15	/**< 14 bit NRPN address + 14 bit unsigned value */
+#define SNDRV_SEQ_EVENT_REGPARAM	16	/**< 14 bit RPN address + 14 bit unsigned value */
+
+/** synchronisation messages
+ * event data type = #snd_seq_ev_ctrl
+ */
+#define SNDRV_SEQ_EVENT_SONGPOS		20	/* Song Position Pointer with LSB and MSB values */
+#define SNDRV_SEQ_EVENT_SONGSEL		21	/* Song Select with song ID number */
+#define SNDRV_SEQ_EVENT_QFRAME		22	/* midi time code quarter frame */
+#define SNDRV_SEQ_EVENT_TIMESIGN	23	/* SMF Time Signature event */
+#define SNDRV_SEQ_EVENT_KEYSIGN		24	/* SMF Key Signature event */
+	        
+/** timer messages
+ * event data type = snd_seq_ev_queue_control
+ */
+#define SNDRV_SEQ_EVENT_START		30	/* midi Real Time Start message */
+#define SNDRV_SEQ_EVENT_CONTINUE	31	/* midi Real Time Continue message */
+#define SNDRV_SEQ_EVENT_STOP		32	/* midi Real Time Stop message */	
+#define	SNDRV_SEQ_EVENT_SETPOS_TICK	33	/* set tick queue position */
+#define SNDRV_SEQ_EVENT_SETPOS_TIME	34	/* set realtime queue position */
+#define SNDRV_SEQ_EVENT_TEMPO		35	/* (SMF) Tempo event */
+#define SNDRV_SEQ_EVENT_CLOCK		36	/* midi Real Time Clock message */
+#define SNDRV_SEQ_EVENT_TICK		37	/* midi Real Time Tick message */
+#define SNDRV_SEQ_EVENT_QUEUE_SKEW	38	/* skew queue tempo */
+
+/** others
+ * event data type = none
+ */
+#define SNDRV_SEQ_EVENT_TUNE_REQUEST	40	/* tune request */
+#define SNDRV_SEQ_EVENT_RESET		41	/* reset to power-on state */
+#define SNDRV_SEQ_EVENT_SENSING		42	/* "active sensing" event */
+
+/** echo back, kernel private messages
+ * event data type = any type
+ */
+#define SNDRV_SEQ_EVENT_ECHO		50	/* echo event */
+#define SNDRV_SEQ_EVENT_OSS		51	/* OSS raw event */
+
+/** system status messages (broadcast for subscribers)
+ * event data type = snd_seq_addr
+ */
+#define SNDRV_SEQ_EVENT_CLIENT_START	60	/* new client has connected */
+#define SNDRV_SEQ_EVENT_CLIENT_EXIT	61	/* client has left the system */
+#define SNDRV_SEQ_EVENT_CLIENT_CHANGE	62	/* client status/info has changed */
+#define SNDRV_SEQ_EVENT_PORT_START	63	/* new port was created */
+#define SNDRV_SEQ_EVENT_PORT_EXIT	64	/* port was deleted from system */
+#define SNDRV_SEQ_EVENT_PORT_CHANGE	65	/* port status/info has changed */
+
+/** port connection changes
+ * event data type = snd_seq_connect
+ */
+#define SNDRV_SEQ_EVENT_PORT_SUBSCRIBED	66	/* ports connected */
+#define SNDRV_SEQ_EVENT_PORT_UNSUBSCRIBED 67	/* ports disconnected */
+
+/* 70-89:  synthesizer events - obsoleted */
+
+/** user-defined events with fixed length
+ * event data type = any
+ */
+#define SNDRV_SEQ_EVENT_USR0		90
+#define SNDRV_SEQ_EVENT_USR1		91
+#define SNDRV_SEQ_EVENT_USR2		92
+#define SNDRV_SEQ_EVENT_USR3		93
+#define SNDRV_SEQ_EVENT_USR4		94
+#define SNDRV_SEQ_EVENT_USR5		95
+#define SNDRV_SEQ_EVENT_USR6		96
+#define SNDRV_SEQ_EVENT_USR7		97
+#define SNDRV_SEQ_EVENT_USR8		98
+#define SNDRV_SEQ_EVENT_USR9		99
+
+/* 100-118: instrument layer - obsoleted */
+/* 119-129: reserved */
+
+/* 130-139: variable length events
+ * event data type = snd_seq_ev_ext
+ * (SNDRV_SEQ_EVENT_LENGTH_VARIABLE must be set)
+ */
+#define SNDRV_SEQ_EVENT_SYSEX		130	/* system exclusive data (variable length) */
+#define SNDRV_SEQ_EVENT_BOUNCE		131	/* error event */
+/* 132-134: reserved */
+#define SNDRV_SEQ_EVENT_USR_VAR0	135
+#define SNDRV_SEQ_EVENT_USR_VAR1	136
+#define SNDRV_SEQ_EVENT_USR_VAR2	137
+#define SNDRV_SEQ_EVENT_USR_VAR3	138
+#define SNDRV_SEQ_EVENT_USR_VAR4	139
+
+/* 150-151: kernel events with quote - DO NOT use in user clients */
+#define SNDRV_SEQ_EVENT_KERNEL_ERROR	150
+#define SNDRV_SEQ_EVENT_KERNEL_QUOTE	151	/* obsolete */
+
+/* 152-191: reserved */
+
+/* 192-254: hardware specific events */
+
+/* 255: special event */
+#define SNDRV_SEQ_EVENT_NONE		255
+
+
+typedef unsigned char snd_seq_event_type_t;
+
+/** event address */
+struct snd_seq_addr {
+	unsigned char client;	/**< Client number:         0..255, 255 = broadcast to all clients */
+	unsigned char port;	/**< Port within client:    0..255, 255 = broadcast to all ports */
+};
+
+/** port connection */
+struct snd_seq_connect {
+	struct snd_seq_addr sender;
+	struct snd_seq_addr dest;
+};
+
+
+#define SNDRV_SEQ_ADDRESS_UNKNOWN	253	/* unknown source */
+#define SNDRV_SEQ_ADDRESS_SUBSCRIBERS	254	/* send event to all subscribed ports */
+#define SNDRV_SEQ_ADDRESS_BROADCAST	255	/* send event to all queues/clients/ports/channels */
+#define SNDRV_SEQ_QUEUE_DIRECT		253	/* direct dispatch */
+
+	/* event mode flag - NOTE: only 8 bits available! */
+#define SNDRV_SEQ_TIME_STAMP_TICK	(0<<0) /* timestamp in clock ticks */
+#define SNDRV_SEQ_TIME_STAMP_REAL	(1<<0) /* timestamp in real time */
+#define SNDRV_SEQ_TIME_STAMP_MASK	(1<<0)
+
+#define SNDRV_SEQ_TIME_MODE_ABS		(0<<1)	/* absolute timestamp */
+#define SNDRV_SEQ_TIME_MODE_REL		(1<<1)	/* relative to current time */
+#define SNDRV_SEQ_TIME_MODE_MASK	(1<<1)
+
+#define SNDRV_SEQ_EVENT_LENGTH_FIXED	(0<<2)	/* fixed event size */
+#define SNDRV_SEQ_EVENT_LENGTH_VARIABLE	(1<<2)	/* variable event size */
+#define SNDRV_SEQ_EVENT_LENGTH_VARUSR	(2<<2)	/* variable event size - user memory space */
+#define SNDRV_SEQ_EVENT_LENGTH_MASK	(3<<2)
+
+#define SNDRV_SEQ_PRIORITY_NORMAL	(0<<4)	/* normal priority */
+#define SNDRV_SEQ_PRIORITY_HIGH		(1<<4)	/* event should be processed before others */
+#define SNDRV_SEQ_PRIORITY_MASK		(1<<4)
+
+
+	/* note event */
+struct snd_seq_ev_note {
+	unsigned char channel;
+	unsigned char note;
+	unsigned char velocity;
+	unsigned char off_velocity;	/* only for SNDRV_SEQ_EVENT_NOTE */
+	unsigned int duration;		/* only for SNDRV_SEQ_EVENT_NOTE */
+};
+
+	/* controller event */
+struct snd_seq_ev_ctrl {
+	unsigned char channel;
+	unsigned char unused1, unused2, unused3;	/* pad */
+	unsigned int param;
+	signed int value;
+};
+
+	/* generic set of bytes (12x8 bit) */
+struct snd_seq_ev_raw8 {
+	unsigned char d[12];	/* 8 bit value */
+};
+
+	/* generic set of integers (3x32 bit) */
+struct snd_seq_ev_raw32 {
+	unsigned int d[3];	/* 32 bit value */
+};
+
+	/* external stored data */
+struct snd_seq_ev_ext {
+	unsigned int len;	/* length of data */
+	void *ptr;		/* pointer to data (note: maybe 64-bit) */
+} __attribute__((packed));
+
+struct snd_seq_result {
+	int event;		/* processed event type */
+	int result;
+};
+
+
+struct snd_seq_real_time {
+	unsigned int tv_sec;	/* seconds */
+	unsigned int tv_nsec;	/* nanoseconds */
+};
+
+typedef unsigned int snd_seq_tick_time_t;	/* midi ticks */
+
+union snd_seq_timestamp {
+	snd_seq_tick_time_t tick;
+	struct snd_seq_real_time time;
+};
+
+struct snd_seq_queue_skew {
+	unsigned int value;
+	unsigned int base;
+};
+
+	/* queue timer control */
+struct snd_seq_ev_queue_control {
+	unsigned char queue;			/* affected queue */
+	unsigned char pad[3];			/* reserved */
+	union {
+		signed int value;		/* affected value (e.g. tempo) */
+		union snd_seq_timestamp time;	/* time */
+		unsigned int position;		/* sync position */
+		struct snd_seq_queue_skew skew;
+		unsigned int d32[2];
+		unsigned char d8[8];
+	} param;
+};
+
+	/* quoted event - inside the kernel only */
+struct snd_seq_ev_quote {
+	struct snd_seq_addr origin;		/* original sender */
+	unsigned short value;		/* optional data */
+	struct snd_seq_event *event;		/* quoted event */
+} __attribute__((packed));
+
+
+	/* sequencer event */
+struct snd_seq_event {
+	snd_seq_event_type_t type;	/* event type */
+	unsigned char flags;		/* event flags */
+	char tag;
+	
+	unsigned char queue;		/* schedule queue */
+	union snd_seq_timestamp time;	/* schedule time */
+
+
+	struct snd_seq_addr source;	/* source address */
+	struct snd_seq_addr dest;	/* destination address */
+
+	union {				/* event data... */
+		struct snd_seq_ev_note note;
+		struct snd_seq_ev_ctrl control;
+		struct snd_seq_ev_raw8 raw8;
+		struct snd_seq_ev_raw32 raw32;
+		struct snd_seq_ev_ext ext;
+		struct snd_seq_ev_queue_control queue;
+		union snd_seq_timestamp time;
+		struct snd_seq_addr addr;
+		struct snd_seq_connect connect;
+		struct snd_seq_result result;
+		struct snd_seq_ev_quote quote;
+	} data;
+};
+
+
+/*
+ * bounce event - stored as variable size data
+ */
+struct snd_seq_event_bounce {
+	int err;
+	struct snd_seq_event event;
+	/* external data follows here. */
+};
+
+
+	/* system information */
+struct snd_seq_system_info {
+	int queues;			/* maximum queues count */
+	int clients;			/* maximum clients count */
+	int ports;			/* maximum ports per client */
+	int channels;			/* maximum channels per port */
+	int cur_clients;		/* current clients */
+	int cur_queues;			/* current queues */
+	char reserved[24];
+};
+
+
+	/* system running information */
+struct snd_seq_running_info {
+	unsigned char client;		/* client id */
+	unsigned char big_endian;	/* 1 = big-endian */
+	unsigned char cpu_mode;		/* 4 = 32bit, 8 = 64bit */
+	unsigned char pad;		/* reserved */
+	unsigned char reserved[12];
+};
+
+
+	/* known client numbers */
+#define SNDRV_SEQ_CLIENT_SYSTEM		0
+	/* internal client numbers */
+#define SNDRV_SEQ_CLIENT_DUMMY		14	/* midi through */
+#define SNDRV_SEQ_CLIENT_OSS		15	/* oss sequencer emulator */
+
+
+	/* client types */
+typedef int __bitwise snd_seq_client_type_t;
+#define	NO_CLIENT	((__force snd_seq_client_type_t) 0)
+#define	USER_CLIENT	((__force snd_seq_client_type_t) 1)
+#define	KERNEL_CLIENT	((__force snd_seq_client_type_t) 2)
+                        
+	/* event filter flags */
+#define SNDRV_SEQ_FILTER_BROADCAST	(1<<0)	/* accept broadcast messages */
+#define SNDRV_SEQ_FILTER_MULTICAST	(1<<1)	/* accept multicast messages */
+#define SNDRV_SEQ_FILTER_BOUNCE		(1<<2)	/* accept bounce event in error */
+#define SNDRV_SEQ_FILTER_USE_EVENT	(1<<31)	/* use event filter */
+
+struct snd_seq_client_info {
+	int client;			/* client number to inquire */
+	snd_seq_client_type_t type;	/* client type */
+	char name[64];			/* client name */
+	unsigned int filter;		/* filter flags */
+	unsigned char multicast_filter[8]; /* multicast filter bitmap */
+	unsigned char event_filter[32];	/* event filter bitmap */
+	int num_ports;			/* RO: number of ports */
+	int event_lost;			/* number of lost events */
+	char reserved[64];		/* for future use */
+};
+
+
+/* client pool size */
+struct snd_seq_client_pool {
+	int client;			/* client number to inquire */
+	int output_pool;		/* outgoing (write) pool size */
+	int input_pool;			/* incoming (read) pool size */
+	int output_room;		/* minimum free pool size for select/blocking mode */
+	int output_free;		/* unused size */
+	int input_free;			/* unused size */
+	char reserved[64];
+};
+
+
+/* Remove events by specified criteria */
+
+#define SNDRV_SEQ_REMOVE_INPUT		(1<<0)	/* Flush input queues */
+#define SNDRV_SEQ_REMOVE_OUTPUT		(1<<1)	/* Flush output queues */
+#define SNDRV_SEQ_REMOVE_DEST		(1<<2)	/* Restrict by destination q:client:port */
+#define SNDRV_SEQ_REMOVE_DEST_CHANNEL	(1<<3)	/* Restrict by channel */
+#define SNDRV_SEQ_REMOVE_TIME_BEFORE	(1<<4)	/* Restrict to before time */
+#define SNDRV_SEQ_REMOVE_TIME_AFTER	(1<<5)	/* Restrict to time or after */
+#define SNDRV_SEQ_REMOVE_TIME_TICK	(1<<6)	/* Time is in ticks */
+#define SNDRV_SEQ_REMOVE_EVENT_TYPE	(1<<7)	/* Restrict to event type */
+#define SNDRV_SEQ_REMOVE_IGNORE_OFF 	(1<<8)	/* Do not flush off events */
+#define SNDRV_SEQ_REMOVE_TAG_MATCH 	(1<<9)	/* Restrict to events with given tag */
+
+struct snd_seq_remove_events {
+	unsigned int  remove_mode;	/* Flags that determine what gets removed */
+
+	union snd_seq_timestamp time;
+
+	unsigned char queue;	/* Queue for REMOVE_DEST */
+	struct snd_seq_addr dest;	/* Address for REMOVE_DEST */
+	unsigned char channel;	/* Channel for REMOVE_DEST */
+
+	int  type;	/* For REMOVE_EVENT_TYPE */
+	char  tag;	/* Tag for REMOVE_TAG */
+
+	int  reserved[10];	/* To allow for future binary compatibility */
+
+};
+
+
+	/* known port numbers */
+#define SNDRV_SEQ_PORT_SYSTEM_TIMER	0
+#define SNDRV_SEQ_PORT_SYSTEM_ANNOUNCE	1
+
+	/* port capabilities (32 bits) */
+#define SNDRV_SEQ_PORT_CAP_READ		(1<<0)	/* readable from this port */
+#define SNDRV_SEQ_PORT_CAP_WRITE	(1<<1)	/* writable to this port */
+
+#define SNDRV_SEQ_PORT_CAP_SYNC_READ	(1<<2)
+#define SNDRV_SEQ_PORT_CAP_SYNC_WRITE	(1<<3)
+
+#define SNDRV_SEQ_PORT_CAP_DUPLEX	(1<<4)
+
+#define SNDRV_SEQ_PORT_CAP_SUBS_READ	(1<<5)	/* allow read subscription */
+#define SNDRV_SEQ_PORT_CAP_SUBS_WRITE	(1<<6)	/* allow write subscription */
+#define SNDRV_SEQ_PORT_CAP_NO_EXPORT	(1<<7)	/* routing not allowed */
+
+	/* port type */
+#define SNDRV_SEQ_PORT_TYPE_SPECIFIC	(1<<0)	/* hardware specific */
+#define SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC (1<<1)	/* generic MIDI device */
+#define SNDRV_SEQ_PORT_TYPE_MIDI_GM	(1<<2)	/* General MIDI compatible device */
+#define SNDRV_SEQ_PORT_TYPE_MIDI_GS	(1<<3)	/* GS compatible device */
+#define SNDRV_SEQ_PORT_TYPE_MIDI_XG	(1<<4)	/* XG compatible device */
+#define SNDRV_SEQ_PORT_TYPE_MIDI_MT32	(1<<5)	/* MT-32 compatible device */
+#define SNDRV_SEQ_PORT_TYPE_MIDI_GM2	(1<<6)	/* General MIDI 2 compatible device */
+
+/* other standards...*/
+#define SNDRV_SEQ_PORT_TYPE_SYNTH	(1<<10)	/* Synth device (no MIDI compatible - direct wavetable) */
+#define SNDRV_SEQ_PORT_TYPE_DIRECT_SAMPLE (1<<11)	/* Sampling device (support sample download) */
+#define SNDRV_SEQ_PORT_TYPE_SAMPLE	(1<<12)	/* Sampling device (sample can be downloaded at any time) */
+/*...*/
+#define SNDRV_SEQ_PORT_TYPE_HARDWARE	(1<<16)	/* driver for a hardware device */
+#define SNDRV_SEQ_PORT_TYPE_SOFTWARE	(1<<17)	/* implemented in software */
+#define SNDRV_SEQ_PORT_TYPE_SYNTHESIZER	(1<<18)	/* generates sound */
+#define SNDRV_SEQ_PORT_TYPE_PORT	(1<<19)	/* connects to other device(s) */
+#define SNDRV_SEQ_PORT_TYPE_APPLICATION	(1<<20)	/* application (sequencer/editor) */
+
+/* misc. conditioning flags */
+#define SNDRV_SEQ_PORT_FLG_GIVEN_PORT	(1<<0)
+#define SNDRV_SEQ_PORT_FLG_TIMESTAMP	(1<<1)
+#define SNDRV_SEQ_PORT_FLG_TIME_REAL	(1<<2)
+
+struct snd_seq_port_info {
+	struct snd_seq_addr addr;	/* client/port numbers */
+	char name[64];			/* port name */
+
+	unsigned int capability;	/* port capability bits */
+	unsigned int type;		/* port type bits */
+	int midi_channels;		/* channels per MIDI port */
+	int midi_voices;		/* voices per MIDI port */
+	int synth_voices;		/* voices per SYNTH port */
+
+	int read_use;			/* R/O: subscribers for output (from this port) */
+	int write_use;			/* R/O: subscribers for input (to this port) */
+
+	void *kernel;			/* reserved for kernel use (must be NULL) */
+	unsigned int flags;		/* misc. conditioning */
+	unsigned char time_queue;	/* queue # for timestamping */
+	char reserved[59];		/* for future use */
+};
+
+
+/* queue flags */
+#define SNDRV_SEQ_QUEUE_FLG_SYNC	(1<<0)	/* sync enabled */
+
+/* queue information */
+struct snd_seq_queue_info {
+	int queue;		/* queue id */
+
+	/*
+	 *  security settings, only owner of this queue can start/stop timer
+	 *  etc. if the queue is locked for other clients
+	 */
+	int owner;		/* client id for owner of the queue */
+	unsigned locked:1;	/* timing queue locked for other queues */
+	char name[64];		/* name of this queue */
+	unsigned int flags;	/* flags */
+	char reserved[60];	/* for future use */
+
+};
+
+/* queue info/status */
+struct snd_seq_queue_status {
+	int queue;			/* queue id */
+	int events;			/* read-only - queue size */
+	snd_seq_tick_time_t tick;	/* current tick */
+	struct snd_seq_real_time time;	/* current time */
+	int running;			/* running state of queue */
+	int flags;			/* various flags */
+	char reserved[64];		/* for the future */
+};
+
+
+/* queue tempo */
+struct snd_seq_queue_tempo {
+	int queue;			/* sequencer queue */
+	unsigned int tempo;		/* current tempo, us/tick */
+	int ppq;			/* time resolution, ticks/quarter */
+	unsigned int skew_value;	/* queue skew */
+	unsigned int skew_base;		/* queue skew base */
+	char reserved[24];		/* for the future */
+};
+
+
+/* sequencer timer sources */
+#define SNDRV_SEQ_TIMER_ALSA		0	/* ALSA timer */
+#define SNDRV_SEQ_TIMER_MIDI_CLOCK	1	/* Midi Clock (CLOCK event) */
+#define SNDRV_SEQ_TIMER_MIDI_TICK	2	/* Midi Timer Tick (TICK event) */
+
+/* queue timer info */
+struct snd_seq_queue_timer {
+	int queue;			/* sequencer queue */
+	int type;			/* source timer type */
+	union {
+		struct {
+			struct snd_timer_id id;	/* ALSA's timer ID */
+			unsigned int resolution;	/* resolution in Hz */
+		} alsa;
+	} u;
+	char reserved[64];		/* for the future use */
+};
+
+
+struct snd_seq_queue_client {
+	int queue;		/* sequencer queue */
+	int client;		/* sequencer client */
+	int used;		/* queue is used with this client
+				   (must be set for accepting events) */
+	/* per client watermarks */
+	char reserved[64];	/* for future use */
+};
+
+
+#define SNDRV_SEQ_PORT_SUBS_EXCLUSIVE	(1<<0)	/* exclusive connection */
+#define SNDRV_SEQ_PORT_SUBS_TIMESTAMP	(1<<1)
+#define SNDRV_SEQ_PORT_SUBS_TIME_REAL	(1<<2)
+
+struct snd_seq_port_subscribe {
+	struct snd_seq_addr sender;	/* sender address */
+	struct snd_seq_addr dest;	/* destination address */
+	unsigned int voices;		/* number of voices to be allocated (0 = don't care) */
+	unsigned int flags;		/* modes */
+	unsigned char queue;		/* input time-stamp queue (optional) */
+	unsigned char pad[3];		/* reserved */
+	char reserved[64];
+};
+
+/* type of query subscription */
+#define SNDRV_SEQ_QUERY_SUBS_READ	0
+#define SNDRV_SEQ_QUERY_SUBS_WRITE	1
+
+struct snd_seq_query_subs {
+	struct snd_seq_addr root;	/* client/port id to be searched */
+	int type;		/* READ or WRITE */
+	int index;		/* 0..N-1 */
+	int num_subs;		/* R/O: number of subscriptions on this port */
+	struct snd_seq_addr addr;	/* R/O: result */
+	unsigned char queue;	/* R/O: result */
+	unsigned int flags;	/* R/O: result */
+	char reserved[64];	/* for future use */
+};
+
+
+/*
+ *  IOCTL commands
+ */
+
+#define SNDRV_SEQ_IOCTL_PVERSION	_IOR ('S', 0x00, int)
+#define SNDRV_SEQ_IOCTL_CLIENT_ID	_IOR ('S', 0x01, int)
+#define SNDRV_SEQ_IOCTL_SYSTEM_INFO	_IOWR('S', 0x02, struct snd_seq_system_info)
+#define SNDRV_SEQ_IOCTL_RUNNING_MODE	_IOWR('S', 0x03, struct snd_seq_running_info)
+
+#define SNDRV_SEQ_IOCTL_GET_CLIENT_INFO	_IOWR('S', 0x10, struct snd_seq_client_info)
+#define SNDRV_SEQ_IOCTL_SET_CLIENT_INFO	_IOW ('S', 0x11, struct snd_seq_client_info)
+
+#define SNDRV_SEQ_IOCTL_CREATE_PORT	_IOWR('S', 0x20, struct snd_seq_port_info)
+#define SNDRV_SEQ_IOCTL_DELETE_PORT	_IOW ('S', 0x21, struct snd_seq_port_info)
+#define SNDRV_SEQ_IOCTL_GET_PORT_INFO	_IOWR('S', 0x22, struct snd_seq_port_info)
+#define SNDRV_SEQ_IOCTL_SET_PORT_INFO	_IOW ('S', 0x23, struct snd_seq_port_info)
+
+#define SNDRV_SEQ_IOCTL_SUBSCRIBE_PORT	_IOW ('S', 0x30, struct snd_seq_port_subscribe)
+#define SNDRV_SEQ_IOCTL_UNSUBSCRIBE_PORT _IOW ('S', 0x31, struct snd_seq_port_subscribe)
+
+#define SNDRV_SEQ_IOCTL_CREATE_QUEUE	_IOWR('S', 0x32, struct snd_seq_queue_info)
+#define SNDRV_SEQ_IOCTL_DELETE_QUEUE	_IOW ('S', 0x33, struct snd_seq_queue_info)
+#define SNDRV_SEQ_IOCTL_GET_QUEUE_INFO	_IOWR('S', 0x34, struct snd_seq_queue_info)
+#define SNDRV_SEQ_IOCTL_SET_QUEUE_INFO	_IOWR('S', 0x35, struct snd_seq_queue_info)
+#define SNDRV_SEQ_IOCTL_GET_NAMED_QUEUE	_IOWR('S', 0x36, struct snd_seq_queue_info)
+#define SNDRV_SEQ_IOCTL_GET_QUEUE_STATUS _IOWR('S', 0x40, struct snd_seq_queue_status)
+#define SNDRV_SEQ_IOCTL_GET_QUEUE_TEMPO	_IOWR('S', 0x41, struct snd_seq_queue_tempo)
+#define SNDRV_SEQ_IOCTL_SET_QUEUE_TEMPO	_IOW ('S', 0x42, struct snd_seq_queue_tempo)
+#define SNDRV_SEQ_IOCTL_GET_QUEUE_OWNER	_IOWR('S', 0x43, struct snd_seq_queue_owner)
+#define SNDRV_SEQ_IOCTL_SET_QUEUE_OWNER	_IOW ('S', 0x44, struct snd_seq_queue_owner)
+#define SNDRV_SEQ_IOCTL_GET_QUEUE_TIMER	_IOWR('S', 0x45, struct snd_seq_queue_timer)
+#define SNDRV_SEQ_IOCTL_SET_QUEUE_TIMER	_IOW ('S', 0x46, struct snd_seq_queue_timer)
+/* XXX
+#define SNDRV_SEQ_IOCTL_GET_QUEUE_SYNC	_IOWR('S', 0x53, struct snd_seq_queue_sync)
+#define SNDRV_SEQ_IOCTL_SET_QUEUE_SYNC	_IOW ('S', 0x54, struct snd_seq_queue_sync)
+*/
+#define SNDRV_SEQ_IOCTL_GET_QUEUE_CLIENT	_IOWR('S', 0x49, struct snd_seq_queue_client)
+#define SNDRV_SEQ_IOCTL_SET_QUEUE_CLIENT	_IOW ('S', 0x4a, struct snd_seq_queue_client)
+#define SNDRV_SEQ_IOCTL_GET_CLIENT_POOL	_IOWR('S', 0x4b, struct snd_seq_client_pool)
+#define SNDRV_SEQ_IOCTL_SET_CLIENT_POOL	_IOW ('S', 0x4c, struct snd_seq_client_pool)
+#define SNDRV_SEQ_IOCTL_REMOVE_EVENTS	_IOW ('S', 0x4e, struct snd_seq_remove_events)
+#define SNDRV_SEQ_IOCTL_QUERY_SUBS	_IOWR('S', 0x4f, struct snd_seq_query_subs)
+#define SNDRV_SEQ_IOCTL_GET_SUBSCRIPTION	_IOWR('S', 0x50, struct snd_seq_port_subscribe)
+#define SNDRV_SEQ_IOCTL_QUERY_NEXT_CLIENT	_IOWR('S', 0x51, struct snd_seq_client_info)
+#define SNDRV_SEQ_IOCTL_QUERY_NEXT_PORT	_IOWR('S', 0x52, struct snd_seq_port_info)
+
+#endif /* _UAPI__SOUND_ASEQUENCER_H */
diff --git a/include/uapi/sound/asound.h b/include/uapi/sound/asound.h
new file mode 100644
index 0000000..1774a5c
--- /dev/null
+++ b/include/uapi/sound/asound.h
@@ -0,0 +1,971 @@
+/*
+ *  Advanced Linux Sound Architecture - ALSA - Driver
+ *  Copyright (c) 1994-2003 by Jaroslav Kysela <perex@perex.cz>,
+ *                             Abramo Bagnara <abramo@alsa-project.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., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ *
+ */
+
+#ifndef _UAPI__SOUND_ASOUND_H
+#define _UAPI__SOUND_ASOUND_H
+
+#include <linux/types.h>
+
+
+/*
+ *  protocol version
+ */
+
+#define SNDRV_PROTOCOL_VERSION(major, minor, subminor) (((major)<<16)|((minor)<<8)|(subminor))
+#define SNDRV_PROTOCOL_MAJOR(version) (((version)>>16)&0xffff)
+#define SNDRV_PROTOCOL_MINOR(version) (((version)>>8)&0xff)
+#define SNDRV_PROTOCOL_MICRO(version) ((version)&0xff)
+#define SNDRV_PROTOCOL_INCOMPATIBLE(kversion, uversion) \
+	(SNDRV_PROTOCOL_MAJOR(kversion) != SNDRV_PROTOCOL_MAJOR(uversion) || \
+	 (SNDRV_PROTOCOL_MAJOR(kversion) == SNDRV_PROTOCOL_MAJOR(uversion) && \
+	   SNDRV_PROTOCOL_MINOR(kversion) != SNDRV_PROTOCOL_MINOR(uversion)))
+
+/****************************************************************************
+ *                                                                          *
+ *        Digital audio interface					    *
+ *                                                                          *
+ ****************************************************************************/
+
+struct snd_aes_iec958 {
+	unsigned char status[24];	/* AES/IEC958 channel status bits */
+	unsigned char subcode[147];	/* AES/IEC958 subcode bits */
+	unsigned char pad;		/* nothing */
+	unsigned char dig_subframe[4];	/* AES/IEC958 subframe bits */
+};
+
+/****************************************************************************
+ *                                                                          *
+ *        CEA-861 Audio InfoFrame. Used in HDMI and DisplayPort		    *
+ *                                                                          *
+ ****************************************************************************/
+
+struct snd_cea_861_aud_if {
+	unsigned char db1_ct_cc; /* coding type and channel count */
+	unsigned char db2_sf_ss; /* sample frequency and size */
+	unsigned char db3; /* not used, all zeros */
+	unsigned char db4_ca; /* channel allocation code */
+	unsigned char db5_dminh_lsv; /* downmix inhibit & level-shit values */
+};
+
+/****************************************************************************
+ *                                                                          *
+ *      Section for driver hardware dependent interface - /dev/snd/hw?      *
+ *                                                                          *
+ ****************************************************************************/
+
+#define SNDRV_HWDEP_VERSION		SNDRV_PROTOCOL_VERSION(1, 0, 1)
+
+enum {
+	SNDRV_HWDEP_IFACE_OPL2 = 0,
+	SNDRV_HWDEP_IFACE_OPL3,
+	SNDRV_HWDEP_IFACE_OPL4,
+	SNDRV_HWDEP_IFACE_SB16CSP,	/* Creative Signal Processor */
+	SNDRV_HWDEP_IFACE_EMU10K1,	/* FX8010 processor in EMU10K1 chip */
+	SNDRV_HWDEP_IFACE_YSS225,	/* Yamaha FX processor */
+	SNDRV_HWDEP_IFACE_ICS2115,	/* Wavetable synth */
+	SNDRV_HWDEP_IFACE_SSCAPE,	/* Ensoniq SoundScape ISA card (MC68EC000) */
+	SNDRV_HWDEP_IFACE_VX,		/* Digigram VX cards */
+	SNDRV_HWDEP_IFACE_MIXART,	/* Digigram miXart cards */
+	SNDRV_HWDEP_IFACE_USX2Y,	/* Tascam US122, US224 & US428 usb */
+	SNDRV_HWDEP_IFACE_EMUX_WAVETABLE, /* EmuX wavetable */	
+	SNDRV_HWDEP_IFACE_BLUETOOTH,	/* Bluetooth audio */
+	SNDRV_HWDEP_IFACE_USX2Y_PCM,	/* Tascam US122, US224 & US428 rawusb pcm */
+	SNDRV_HWDEP_IFACE_PCXHR,	/* Digigram PCXHR */
+	SNDRV_HWDEP_IFACE_SB_RC,	/* SB Extigy/Audigy2NX remote control */
+	SNDRV_HWDEP_IFACE_HDA,		/* HD-audio */
+	SNDRV_HWDEP_IFACE_USB_STREAM,	/* direct access to usb stream */
+
+	/* Don't forget to change the following: */
+	SNDRV_HWDEP_IFACE_LAST = SNDRV_HWDEP_IFACE_USB_STREAM
+};
+
+struct snd_hwdep_info {
+	unsigned int device;		/* WR: device number */
+	int card;			/* R: card number */
+	unsigned char id[64];		/* ID (user selectable) */
+	unsigned char name[80];		/* hwdep name */
+	int iface;			/* hwdep interface */
+	unsigned char reserved[64];	/* reserved for future */
+};
+
+/* generic DSP loader */
+struct snd_hwdep_dsp_status {
+	unsigned int version;		/* R: driver-specific version */
+	unsigned char id[32];		/* R: driver-specific ID string */
+	unsigned int num_dsps;		/* R: number of DSP images to transfer */
+	unsigned int dsp_loaded;	/* R: bit flags indicating the loaded DSPs */
+	unsigned int chip_ready;	/* R: 1 = initialization finished */
+	unsigned char reserved[16];	/* reserved for future use */
+};
+
+struct snd_hwdep_dsp_image {
+	unsigned int index;		/* W: DSP index */
+	unsigned char name[64];		/* W: ID (e.g. file name) */
+	unsigned char __user *image;	/* W: binary image */
+	size_t length;			/* W: size of image in bytes */
+	unsigned long driver_data;	/* W: driver-specific data */
+};
+
+#define SNDRV_HWDEP_IOCTL_PVERSION	_IOR ('H', 0x00, int)
+#define SNDRV_HWDEP_IOCTL_INFO		_IOR ('H', 0x01, struct snd_hwdep_info)
+#define SNDRV_HWDEP_IOCTL_DSP_STATUS	_IOR('H', 0x02, struct snd_hwdep_dsp_status)
+#define SNDRV_HWDEP_IOCTL_DSP_LOAD	_IOW('H', 0x03, struct snd_hwdep_dsp_image)
+
+/*****************************************************************************
+ *                                                                           *
+ *             Digital Audio (PCM) interface - /dev/snd/pcm??                *
+ *                                                                           *
+ *****************************************************************************/
+
+#define SNDRV_PCM_VERSION		SNDRV_PROTOCOL_VERSION(2, 0, 11)
+
+typedef unsigned long snd_pcm_uframes_t;
+typedef signed long snd_pcm_sframes_t;
+
+enum {
+	SNDRV_PCM_CLASS_GENERIC = 0,	/* standard mono or stereo device */
+	SNDRV_PCM_CLASS_MULTI,		/* multichannel device */
+	SNDRV_PCM_CLASS_MODEM,		/* software modem class */
+	SNDRV_PCM_CLASS_DIGITIZER,	/* digitizer class */
+	/* Don't forget to change the following: */
+	SNDRV_PCM_CLASS_LAST = SNDRV_PCM_CLASS_DIGITIZER,
+};
+
+enum {
+	SNDRV_PCM_SUBCLASS_GENERIC_MIX = 0, /* mono or stereo subdevices are mixed together */
+	SNDRV_PCM_SUBCLASS_MULTI_MIX,	/* multichannel subdevices are mixed together */
+	/* Don't forget to change the following: */
+	SNDRV_PCM_SUBCLASS_LAST = SNDRV_PCM_SUBCLASS_MULTI_MIX,
+};
+
+enum {
+	SNDRV_PCM_STREAM_PLAYBACK = 0,
+	SNDRV_PCM_STREAM_CAPTURE,
+	SNDRV_PCM_STREAM_LAST = SNDRV_PCM_STREAM_CAPTURE,
+};
+
+typedef int __bitwise snd_pcm_access_t;
+#define	SNDRV_PCM_ACCESS_MMAP_INTERLEAVED	((__force snd_pcm_access_t) 0) /* interleaved mmap */
+#define	SNDRV_PCM_ACCESS_MMAP_NONINTERLEAVED	((__force snd_pcm_access_t) 1) /* noninterleaved mmap */
+#define	SNDRV_PCM_ACCESS_MMAP_COMPLEX		((__force snd_pcm_access_t) 2) /* complex mmap */
+#define	SNDRV_PCM_ACCESS_RW_INTERLEAVED		((__force snd_pcm_access_t) 3) /* readi/writei */
+#define	SNDRV_PCM_ACCESS_RW_NONINTERLEAVED	((__force snd_pcm_access_t) 4) /* readn/writen */
+#define	SNDRV_PCM_ACCESS_LAST		SNDRV_PCM_ACCESS_RW_NONINTERLEAVED
+
+typedef int __bitwise snd_pcm_format_t;
+#define	SNDRV_PCM_FORMAT_S8	((__force snd_pcm_format_t) 0)
+#define	SNDRV_PCM_FORMAT_U8	((__force snd_pcm_format_t) 1)
+#define	SNDRV_PCM_FORMAT_S16_LE	((__force snd_pcm_format_t) 2)
+#define	SNDRV_PCM_FORMAT_S16_BE	((__force snd_pcm_format_t) 3)
+#define	SNDRV_PCM_FORMAT_U16_LE	((__force snd_pcm_format_t) 4)
+#define	SNDRV_PCM_FORMAT_U16_BE	((__force snd_pcm_format_t) 5)
+#define	SNDRV_PCM_FORMAT_S24_LE	((__force snd_pcm_format_t) 6) /* low three bytes */
+#define	SNDRV_PCM_FORMAT_S24_BE	((__force snd_pcm_format_t) 7) /* low three bytes */
+#define	SNDRV_PCM_FORMAT_U24_LE	((__force snd_pcm_format_t) 8) /* low three bytes */
+#define	SNDRV_PCM_FORMAT_U24_BE	((__force snd_pcm_format_t) 9) /* low three bytes */
+#define	SNDRV_PCM_FORMAT_S32_LE	((__force snd_pcm_format_t) 10)
+#define	SNDRV_PCM_FORMAT_S32_BE	((__force snd_pcm_format_t) 11)
+#define	SNDRV_PCM_FORMAT_U32_LE	((__force snd_pcm_format_t) 12)
+#define	SNDRV_PCM_FORMAT_U32_BE	((__force snd_pcm_format_t) 13)
+#define	SNDRV_PCM_FORMAT_FLOAT_LE	((__force snd_pcm_format_t) 14) /* 4-byte float, IEEE-754 32-bit, range -1.0 to 1.0 */
+#define	SNDRV_PCM_FORMAT_FLOAT_BE	((__force snd_pcm_format_t) 15) /* 4-byte float, IEEE-754 32-bit, range -1.0 to 1.0 */
+#define	SNDRV_PCM_FORMAT_FLOAT64_LE	((__force snd_pcm_format_t) 16) /* 8-byte float, IEEE-754 64-bit, range -1.0 to 1.0 */
+#define	SNDRV_PCM_FORMAT_FLOAT64_BE	((__force snd_pcm_format_t) 17) /* 8-byte float, IEEE-754 64-bit, range -1.0 to 1.0 */
+#define	SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE ((__force snd_pcm_format_t) 18) /* IEC-958 subframe, Little Endian */
+#define	SNDRV_PCM_FORMAT_IEC958_SUBFRAME_BE ((__force snd_pcm_format_t) 19) /* IEC-958 subframe, Big Endian */
+#define	SNDRV_PCM_FORMAT_MU_LAW		((__force snd_pcm_format_t) 20)
+#define	SNDRV_PCM_FORMAT_A_LAW		((__force snd_pcm_format_t) 21)
+#define	SNDRV_PCM_FORMAT_IMA_ADPCM	((__force snd_pcm_format_t) 22)
+#define	SNDRV_PCM_FORMAT_MPEG		((__force snd_pcm_format_t) 23)
+#define	SNDRV_PCM_FORMAT_GSM		((__force snd_pcm_format_t) 24)
+#define	SNDRV_PCM_FORMAT_SPECIAL	((__force snd_pcm_format_t) 31)
+#define	SNDRV_PCM_FORMAT_S24_3LE	((__force snd_pcm_format_t) 32)	/* in three bytes */
+#define	SNDRV_PCM_FORMAT_S24_3BE	((__force snd_pcm_format_t) 33)	/* in three bytes */
+#define	SNDRV_PCM_FORMAT_U24_3LE	((__force snd_pcm_format_t) 34)	/* in three bytes */
+#define	SNDRV_PCM_FORMAT_U24_3BE	((__force snd_pcm_format_t) 35)	/* in three bytes */
+#define	SNDRV_PCM_FORMAT_S20_3LE	((__force snd_pcm_format_t) 36)	/* in three bytes */
+#define	SNDRV_PCM_FORMAT_S20_3BE	((__force snd_pcm_format_t) 37)	/* in three bytes */
+#define	SNDRV_PCM_FORMAT_U20_3LE	((__force snd_pcm_format_t) 38)	/* in three bytes */
+#define	SNDRV_PCM_FORMAT_U20_3BE	((__force snd_pcm_format_t) 39)	/* in three bytes */
+#define	SNDRV_PCM_FORMAT_S18_3LE	((__force snd_pcm_format_t) 40)	/* in three bytes */
+#define	SNDRV_PCM_FORMAT_S18_3BE	((__force snd_pcm_format_t) 41)	/* in three bytes */
+#define	SNDRV_PCM_FORMAT_U18_3LE	((__force snd_pcm_format_t) 42)	/* in three bytes */
+#define	SNDRV_PCM_FORMAT_U18_3BE	((__force snd_pcm_format_t) 43)	/* in three bytes */
+#define	SNDRV_PCM_FORMAT_G723_24	((__force snd_pcm_format_t) 44) /* 8 samples in 3 bytes */
+#define	SNDRV_PCM_FORMAT_G723_24_1B	((__force snd_pcm_format_t) 45) /* 1 sample in 1 byte */
+#define	SNDRV_PCM_FORMAT_G723_40	((__force snd_pcm_format_t) 46) /* 8 Samples in 5 bytes */
+#define	SNDRV_PCM_FORMAT_G723_40_1B	((__force snd_pcm_format_t) 47) /* 1 sample in 1 byte */
+#define	SNDRV_PCM_FORMAT_LAST		SNDRV_PCM_FORMAT_G723_40_1B
+
+#ifdef SNDRV_LITTLE_ENDIAN
+#define	SNDRV_PCM_FORMAT_S16		SNDRV_PCM_FORMAT_S16_LE
+#define	SNDRV_PCM_FORMAT_U16		SNDRV_PCM_FORMAT_U16_LE
+#define	SNDRV_PCM_FORMAT_S24		SNDRV_PCM_FORMAT_S24_LE
+#define	SNDRV_PCM_FORMAT_U24		SNDRV_PCM_FORMAT_U24_LE
+#define	SNDRV_PCM_FORMAT_S32		SNDRV_PCM_FORMAT_S32_LE
+#define	SNDRV_PCM_FORMAT_U32		SNDRV_PCM_FORMAT_U32_LE
+#define	SNDRV_PCM_FORMAT_FLOAT		SNDRV_PCM_FORMAT_FLOAT_LE
+#define	SNDRV_PCM_FORMAT_FLOAT64	SNDRV_PCM_FORMAT_FLOAT64_LE
+#define	SNDRV_PCM_FORMAT_IEC958_SUBFRAME SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE
+#endif
+#ifdef SNDRV_BIG_ENDIAN
+#define	SNDRV_PCM_FORMAT_S16		SNDRV_PCM_FORMAT_S16_BE
+#define	SNDRV_PCM_FORMAT_U16		SNDRV_PCM_FORMAT_U16_BE
+#define	SNDRV_PCM_FORMAT_S24		SNDRV_PCM_FORMAT_S24_BE
+#define	SNDRV_PCM_FORMAT_U24		SNDRV_PCM_FORMAT_U24_BE
+#define	SNDRV_PCM_FORMAT_S32		SNDRV_PCM_FORMAT_S32_BE
+#define	SNDRV_PCM_FORMAT_U32		SNDRV_PCM_FORMAT_U32_BE
+#define	SNDRV_PCM_FORMAT_FLOAT		SNDRV_PCM_FORMAT_FLOAT_BE
+#define	SNDRV_PCM_FORMAT_FLOAT64	SNDRV_PCM_FORMAT_FLOAT64_BE
+#define	SNDRV_PCM_FORMAT_IEC958_SUBFRAME SNDRV_PCM_FORMAT_IEC958_SUBFRAME_BE
+#endif
+
+typedef int __bitwise snd_pcm_subformat_t;
+#define	SNDRV_PCM_SUBFORMAT_STD		((__force snd_pcm_subformat_t) 0)
+#define	SNDRV_PCM_SUBFORMAT_LAST	SNDRV_PCM_SUBFORMAT_STD
+
+#define SNDRV_PCM_INFO_MMAP		0x00000001	/* hardware supports mmap */
+#define SNDRV_PCM_INFO_MMAP_VALID	0x00000002	/* period data are valid during transfer */
+#define SNDRV_PCM_INFO_DOUBLE		0x00000004	/* Double buffering needed for PCM start/stop */
+#define SNDRV_PCM_INFO_BATCH		0x00000010	/* double buffering */
+#define SNDRV_PCM_INFO_INTERLEAVED	0x00000100	/* channels are interleaved */
+#define SNDRV_PCM_INFO_NONINTERLEAVED	0x00000200	/* channels are not interleaved */
+#define SNDRV_PCM_INFO_COMPLEX		0x00000400	/* complex frame organization (mmap only) */
+#define SNDRV_PCM_INFO_BLOCK_TRANSFER	0x00010000	/* hardware transfer block of samples */
+#define SNDRV_PCM_INFO_OVERRANGE	0x00020000	/* hardware supports ADC (capture) overrange detection */
+#define SNDRV_PCM_INFO_RESUME		0x00040000	/* hardware supports stream resume after suspend */
+#define SNDRV_PCM_INFO_PAUSE		0x00080000	/* pause ioctl is supported */
+#define SNDRV_PCM_INFO_HALF_DUPLEX	0x00100000	/* only half duplex */
+#define SNDRV_PCM_INFO_JOINT_DUPLEX	0x00200000	/* playback and capture stream are somewhat correlated */
+#define SNDRV_PCM_INFO_SYNC_START	0x00400000	/* pcm support some kind of sync go */
+#define SNDRV_PCM_INFO_NO_PERIOD_WAKEUP	0x00800000	/* period wakeup can be disabled */
+#define SNDRV_PCM_INFO_HAS_WALL_CLOCK   0x01000000      /* has audio wall clock for audio/system time sync */
+#define SNDRV_PCM_INFO_FIFO_IN_FRAMES	0x80000000	/* internal kernel flag - FIFO size is in frames */
+
+typedef int __bitwise snd_pcm_state_t;
+#define	SNDRV_PCM_STATE_OPEN		((__force snd_pcm_state_t) 0) /* stream is open */
+#define	SNDRV_PCM_STATE_SETUP		((__force snd_pcm_state_t) 1) /* stream has a setup */
+#define	SNDRV_PCM_STATE_PREPARED	((__force snd_pcm_state_t) 2) /* stream is ready to start */
+#define	SNDRV_PCM_STATE_RUNNING		((__force snd_pcm_state_t) 3) /* stream is running */
+#define	SNDRV_PCM_STATE_XRUN		((__force snd_pcm_state_t) 4) /* stream reached an xrun */
+#define	SNDRV_PCM_STATE_DRAINING	((__force snd_pcm_state_t) 5) /* stream is draining */
+#define	SNDRV_PCM_STATE_PAUSED		((__force snd_pcm_state_t) 6) /* stream is paused */
+#define	SNDRV_PCM_STATE_SUSPENDED	((__force snd_pcm_state_t) 7) /* hardware is suspended */
+#define	SNDRV_PCM_STATE_DISCONNECTED	((__force snd_pcm_state_t) 8) /* hardware is disconnected */
+#define	SNDRV_PCM_STATE_LAST		SNDRV_PCM_STATE_DISCONNECTED
+
+enum {
+	SNDRV_PCM_MMAP_OFFSET_DATA = 0x00000000,
+	SNDRV_PCM_MMAP_OFFSET_STATUS = 0x80000000,
+	SNDRV_PCM_MMAP_OFFSET_CONTROL = 0x81000000,
+};
+
+union snd_pcm_sync_id {
+	unsigned char id[16];
+	unsigned short id16[8];
+	unsigned int id32[4];
+};
+
+struct snd_pcm_info {
+	unsigned int device;		/* RO/WR (control): device number */
+	unsigned int subdevice;		/* RO/WR (control): subdevice number */
+	int stream;			/* RO/WR (control): stream direction */
+	int card;			/* R: card number */
+	unsigned char id[64];		/* ID (user selectable) */
+	unsigned char name[80];		/* name of this device */
+	unsigned char subname[32];	/* subdevice name */
+	int dev_class;			/* SNDRV_PCM_CLASS_* */
+	int dev_subclass;		/* SNDRV_PCM_SUBCLASS_* */
+	unsigned int subdevices_count;
+	unsigned int subdevices_avail;
+	union snd_pcm_sync_id sync;	/* hardware synchronization ID */
+	unsigned char reserved[64];	/* reserved for future... */
+};
+
+typedef int snd_pcm_hw_param_t;
+#define	SNDRV_PCM_HW_PARAM_ACCESS	0	/* Access type */
+#define	SNDRV_PCM_HW_PARAM_FORMAT	1	/* Format */
+#define	SNDRV_PCM_HW_PARAM_SUBFORMAT	2	/* Subformat */
+#define	SNDRV_PCM_HW_PARAM_FIRST_MASK	SNDRV_PCM_HW_PARAM_ACCESS
+#define	SNDRV_PCM_HW_PARAM_LAST_MASK	SNDRV_PCM_HW_PARAM_SUBFORMAT
+
+#define	SNDRV_PCM_HW_PARAM_SAMPLE_BITS	8	/* Bits per sample */
+#define	SNDRV_PCM_HW_PARAM_FRAME_BITS	9	/* Bits per frame */
+#define	SNDRV_PCM_HW_PARAM_CHANNELS	10	/* Channels */
+#define	SNDRV_PCM_HW_PARAM_RATE		11	/* Approx rate */
+#define	SNDRV_PCM_HW_PARAM_PERIOD_TIME	12	/* Approx distance between
+						 * interrupts in us
+						 */
+#define	SNDRV_PCM_HW_PARAM_PERIOD_SIZE	13	/* Approx frames between
+						 * interrupts
+						 */
+#define	SNDRV_PCM_HW_PARAM_PERIOD_BYTES	14	/* Approx bytes between
+						 * interrupts
+						 */
+#define	SNDRV_PCM_HW_PARAM_PERIODS	15	/* Approx interrupts per
+						 * buffer
+						 */
+#define	SNDRV_PCM_HW_PARAM_BUFFER_TIME	16	/* Approx duration of buffer
+						 * in us
+						 */
+#define	SNDRV_PCM_HW_PARAM_BUFFER_SIZE	17	/* Size of buffer in frames */
+#define	SNDRV_PCM_HW_PARAM_BUFFER_BYTES	18	/* Size of buffer in bytes */
+#define	SNDRV_PCM_HW_PARAM_TICK_TIME	19	/* Approx tick duration in us */
+#define	SNDRV_PCM_HW_PARAM_FIRST_INTERVAL	SNDRV_PCM_HW_PARAM_SAMPLE_BITS
+#define	SNDRV_PCM_HW_PARAM_LAST_INTERVAL	SNDRV_PCM_HW_PARAM_TICK_TIME
+
+#define SNDRV_PCM_HW_PARAMS_NORESAMPLE	(1<<0)	/* avoid rate resampling */
+#define SNDRV_PCM_HW_PARAMS_EXPORT_BUFFER	(1<<1)	/* export buffer */
+#define SNDRV_PCM_HW_PARAMS_NO_PERIOD_WAKEUP	(1<<2)	/* disable period wakeups */
+
+struct snd_interval {
+	unsigned int min, max;
+	unsigned int openmin:1,
+		     openmax:1,
+		     integer:1,
+		     empty:1;
+};
+
+#define SNDRV_MASK_MAX	256
+
+struct snd_mask {
+	__u32 bits[(SNDRV_MASK_MAX+31)/32];
+};
+
+struct snd_pcm_hw_params {
+	unsigned int flags;
+	struct snd_mask masks[SNDRV_PCM_HW_PARAM_LAST_MASK - 
+			       SNDRV_PCM_HW_PARAM_FIRST_MASK + 1];
+	struct snd_mask mres[5];	/* reserved masks */
+	struct snd_interval intervals[SNDRV_PCM_HW_PARAM_LAST_INTERVAL -
+				        SNDRV_PCM_HW_PARAM_FIRST_INTERVAL + 1];
+	struct snd_interval ires[9];	/* reserved intervals */
+	unsigned int rmask;		/* W: requested masks */
+	unsigned int cmask;		/* R: changed masks */
+	unsigned int info;		/* R: Info flags for returned setup */
+	unsigned int msbits;		/* R: used most significant bits */
+	unsigned int rate_num;		/* R: rate numerator */
+	unsigned int rate_den;		/* R: rate denominator */
+	snd_pcm_uframes_t fifo_size;	/* R: chip FIFO size in frames */
+	unsigned char reserved[64];	/* reserved for future */
+};
+
+enum {
+	SNDRV_PCM_TSTAMP_NONE = 0,
+	SNDRV_PCM_TSTAMP_ENABLE,
+	SNDRV_PCM_TSTAMP_LAST = SNDRV_PCM_TSTAMP_ENABLE,
+};
+
+struct snd_pcm_sw_params {
+	int tstamp_mode;			/* timestamp mode */
+	unsigned int period_step;
+	unsigned int sleep_min;			/* min ticks to sleep */
+	snd_pcm_uframes_t avail_min;		/* min avail frames for wakeup */
+	snd_pcm_uframes_t xfer_align;		/* obsolete: xfer size need to be a multiple */
+	snd_pcm_uframes_t start_threshold;	/* min hw_avail frames for automatic start */
+	snd_pcm_uframes_t stop_threshold;	/* min avail frames for automatic stop */
+	snd_pcm_uframes_t silence_threshold;	/* min distance from noise for silence filling */
+	snd_pcm_uframes_t silence_size;		/* silence block size */
+	snd_pcm_uframes_t boundary;		/* pointers wrap point */
+	unsigned char reserved[64];		/* reserved for future */
+};
+
+struct snd_pcm_channel_info {
+	unsigned int channel;
+	__kernel_off_t offset;		/* mmap offset */
+	unsigned int first;		/* offset to first sample in bits */
+	unsigned int step;		/* samples distance in bits */
+};
+
+struct snd_pcm_status {
+	snd_pcm_state_t state;		/* stream state */
+	struct timespec trigger_tstamp;	/* time when stream was started/stopped/paused */
+	struct timespec tstamp;		/* reference timestamp */
+	snd_pcm_uframes_t appl_ptr;	/* appl ptr */
+	snd_pcm_uframes_t hw_ptr;	/* hw ptr */
+	snd_pcm_sframes_t delay;	/* current delay in frames */
+	snd_pcm_uframes_t avail;	/* number of frames available */
+	snd_pcm_uframes_t avail_max;	/* max frames available on hw since last status */
+	snd_pcm_uframes_t overrange;	/* count of ADC (capture) overrange detections from last status */
+	snd_pcm_state_t suspended_state; /* suspended stream state */
+	__u32 reserved_alignment;	/* must be filled with zero */
+	struct timespec audio_tstamp;	/* from sample counter or wall clock */
+	unsigned char reserved[56-sizeof(struct timespec)]; /* must be filled with zero */
+};
+
+struct snd_pcm_mmap_status {
+	snd_pcm_state_t state;		/* RO: state - SNDRV_PCM_STATE_XXXX */
+	int pad1;			/* Needed for 64 bit alignment */
+	snd_pcm_uframes_t hw_ptr;	/* RO: hw ptr (0...boundary-1) */
+	struct timespec tstamp;		/* Timestamp */
+	snd_pcm_state_t suspended_state; /* RO: suspended stream state */
+	struct timespec audio_tstamp;	/* from sample counter or wall clock */
+};
+
+struct snd_pcm_mmap_control {
+	snd_pcm_uframes_t appl_ptr;	/* RW: appl ptr (0...boundary-1) */
+	snd_pcm_uframes_t avail_min;	/* RW: min available frames for wakeup */
+};
+
+#define SNDRV_PCM_SYNC_PTR_HWSYNC	(1<<0)	/* execute hwsync */
+#define SNDRV_PCM_SYNC_PTR_APPL		(1<<1)	/* get appl_ptr from driver (r/w op) */
+#define SNDRV_PCM_SYNC_PTR_AVAIL_MIN	(1<<2)	/* get avail_min from driver */
+
+struct snd_pcm_sync_ptr {
+	unsigned int flags;
+	union {
+		struct snd_pcm_mmap_status status;
+		unsigned char reserved[64];
+	} s;
+	union {
+		struct snd_pcm_mmap_control control;
+		unsigned char reserved[64];
+	} c;
+};
+
+struct snd_xferi {
+	snd_pcm_sframes_t result;
+	void __user *buf;
+	snd_pcm_uframes_t frames;
+};
+
+struct snd_xfern {
+	snd_pcm_sframes_t result;
+	void __user * __user *bufs;
+	snd_pcm_uframes_t frames;
+};
+
+enum {
+	SNDRV_PCM_TSTAMP_TYPE_GETTIMEOFDAY = 0,	/* gettimeofday equivalent */
+	SNDRV_PCM_TSTAMP_TYPE_MONOTONIC,	/* posix_clock_monotonic equivalent */
+	SNDRV_PCM_TSTAMP_TYPE_LAST = SNDRV_PCM_TSTAMP_TYPE_MONOTONIC,
+};
+
+/* channel positions */
+enum {
+	SNDRV_CHMAP_UNKNOWN = 0,
+	SNDRV_CHMAP_NA,		/* N/A, silent */
+	SNDRV_CHMAP_MONO,	/* mono stream */
+	/* this follows the alsa-lib mixer channel value + 3 */
+	SNDRV_CHMAP_FL,		/* front left */
+	SNDRV_CHMAP_FR,		/* front right */
+	SNDRV_CHMAP_RL,		/* rear left */
+	SNDRV_CHMAP_RR,		/* rear right */
+	SNDRV_CHMAP_FC,		/* front center */
+	SNDRV_CHMAP_LFE,	/* LFE */
+	SNDRV_CHMAP_SL,		/* side left */
+	SNDRV_CHMAP_SR,		/* side right */
+	SNDRV_CHMAP_RC,		/* rear center */
+	/* new definitions */
+	SNDRV_CHMAP_FLC,	/* front left center */
+	SNDRV_CHMAP_FRC,	/* front right center */
+	SNDRV_CHMAP_RLC,	/* rear left center */
+	SNDRV_CHMAP_RRC,	/* rear right center */
+	SNDRV_CHMAP_FLW,	/* front left wide */
+	SNDRV_CHMAP_FRW,	/* front right wide */
+	SNDRV_CHMAP_FLH,	/* front left high */
+	SNDRV_CHMAP_FCH,	/* front center high */
+	SNDRV_CHMAP_FRH,	/* front right high */
+	SNDRV_CHMAP_TC,		/* top center */
+	SNDRV_CHMAP_TFL,	/* top front left */
+	SNDRV_CHMAP_TFR,	/* top front right */
+	SNDRV_CHMAP_TFC,	/* top front center */
+	SNDRV_CHMAP_TRL,	/* top rear left */
+	SNDRV_CHMAP_TRR,	/* top rear right */
+	SNDRV_CHMAP_TRC,	/* top rear center */
+	/* new definitions for UAC2 */
+	SNDRV_CHMAP_TFLC,	/* top front left center */
+	SNDRV_CHMAP_TFRC,	/* top front right center */
+	SNDRV_CHMAP_TSL,	/* top side left */
+	SNDRV_CHMAP_TSR,	/* top side right */
+	SNDRV_CHMAP_LLFE,	/* left LFE */
+	SNDRV_CHMAP_RLFE,	/* right LFE */
+	SNDRV_CHMAP_BC,		/* bottom center */
+	SNDRV_CHMAP_BLC,	/* bottom left center */
+	SNDRV_CHMAP_BRC,	/* bottom right center */
+	SNDRV_CHMAP_LAST = SNDRV_CHMAP_BRC,
+};
+
+#define SNDRV_CHMAP_POSITION_MASK	0xffff
+#define SNDRV_CHMAP_PHASE_INVERSE	(0x01 << 16)
+#define SNDRV_CHMAP_DRIVER_SPEC		(0x02 << 16)
+
+#define SNDRV_PCM_IOCTL_PVERSION	_IOR('A', 0x00, int)
+#define SNDRV_PCM_IOCTL_INFO		_IOR('A', 0x01, struct snd_pcm_info)
+#define SNDRV_PCM_IOCTL_TSTAMP		_IOW('A', 0x02, int)
+#define SNDRV_PCM_IOCTL_TTSTAMP		_IOW('A', 0x03, int)
+#define SNDRV_PCM_IOCTL_HW_REFINE	_IOWR('A', 0x10, struct snd_pcm_hw_params)
+#define SNDRV_PCM_IOCTL_HW_PARAMS	_IOWR('A', 0x11, struct snd_pcm_hw_params)
+#define SNDRV_PCM_IOCTL_HW_FREE		_IO('A', 0x12)
+#define SNDRV_PCM_IOCTL_SW_PARAMS	_IOWR('A', 0x13, struct snd_pcm_sw_params)
+#define SNDRV_PCM_IOCTL_STATUS		_IOR('A', 0x20, struct snd_pcm_status)
+#define SNDRV_PCM_IOCTL_DELAY		_IOR('A', 0x21, snd_pcm_sframes_t)
+#define SNDRV_PCM_IOCTL_HWSYNC		_IO('A', 0x22)
+#define SNDRV_PCM_IOCTL_SYNC_PTR	_IOWR('A', 0x23, struct snd_pcm_sync_ptr)
+#define SNDRV_PCM_IOCTL_CHANNEL_INFO	_IOR('A', 0x32, struct snd_pcm_channel_info)
+#define SNDRV_PCM_IOCTL_PREPARE		_IO('A', 0x40)
+#define SNDRV_PCM_IOCTL_RESET		_IO('A', 0x41)
+#define SNDRV_PCM_IOCTL_START		_IO('A', 0x42)
+#define SNDRV_PCM_IOCTL_DROP		_IO('A', 0x43)
+#define SNDRV_PCM_IOCTL_DRAIN		_IO('A', 0x44)
+#define SNDRV_PCM_IOCTL_PAUSE		_IOW('A', 0x45, int)
+#define SNDRV_PCM_IOCTL_REWIND		_IOW('A', 0x46, snd_pcm_uframes_t)
+#define SNDRV_PCM_IOCTL_RESUME		_IO('A', 0x47)
+#define SNDRV_PCM_IOCTL_XRUN		_IO('A', 0x48)
+#define SNDRV_PCM_IOCTL_FORWARD		_IOW('A', 0x49, snd_pcm_uframes_t)
+#define SNDRV_PCM_IOCTL_WRITEI_FRAMES	_IOW('A', 0x50, struct snd_xferi)
+#define SNDRV_PCM_IOCTL_READI_FRAMES	_IOR('A', 0x51, struct snd_xferi)
+#define SNDRV_PCM_IOCTL_WRITEN_FRAMES	_IOW('A', 0x52, struct snd_xfern)
+#define SNDRV_PCM_IOCTL_READN_FRAMES	_IOR('A', 0x53, struct snd_xfern)
+#define SNDRV_PCM_IOCTL_LINK		_IOW('A', 0x60, int)
+#define SNDRV_PCM_IOCTL_UNLINK		_IO('A', 0x61)
+
+/*****************************************************************************
+ *                                                                           *
+ *                            MIDI v1.0 interface                            *
+ *                                                                           *
+ *****************************************************************************/
+
+/*
+ *  Raw MIDI section - /dev/snd/midi??
+ */
+
+#define SNDRV_RAWMIDI_VERSION		SNDRV_PROTOCOL_VERSION(2, 0, 0)
+
+enum {
+	SNDRV_RAWMIDI_STREAM_OUTPUT = 0,
+	SNDRV_RAWMIDI_STREAM_INPUT,
+	SNDRV_RAWMIDI_STREAM_LAST = SNDRV_RAWMIDI_STREAM_INPUT,
+};
+
+#define SNDRV_RAWMIDI_INFO_OUTPUT		0x00000001
+#define SNDRV_RAWMIDI_INFO_INPUT		0x00000002
+#define SNDRV_RAWMIDI_INFO_DUPLEX		0x00000004
+
+struct snd_rawmidi_info {
+	unsigned int device;		/* RO/WR (control): device number */
+	unsigned int subdevice;		/* RO/WR (control): subdevice number */
+	int stream;			/* WR: stream */
+	int card;			/* R: card number */
+	unsigned int flags;		/* SNDRV_RAWMIDI_INFO_XXXX */
+	unsigned char id[64];		/* ID (user selectable) */
+	unsigned char name[80];		/* name of device */
+	unsigned char subname[32];	/* name of active or selected subdevice */
+	unsigned int subdevices_count;
+	unsigned int subdevices_avail;
+	unsigned char reserved[64];	/* reserved for future use */
+};
+
+struct snd_rawmidi_params {
+	int stream;
+	size_t buffer_size;		/* queue size in bytes */
+	size_t avail_min;		/* minimum avail bytes for wakeup */
+	unsigned int no_active_sensing: 1; /* do not send active sensing byte in close() */
+	unsigned char reserved[16];	/* reserved for future use */
+};
+
+struct snd_rawmidi_status {
+	int stream;
+	struct timespec tstamp;		/* Timestamp */
+	size_t avail;			/* available bytes */
+	size_t xruns;			/* count of overruns since last status (in bytes) */
+	unsigned char reserved[16];	/* reserved for future use */
+};
+
+#define SNDRV_RAWMIDI_IOCTL_PVERSION	_IOR('W', 0x00, int)
+#define SNDRV_RAWMIDI_IOCTL_INFO	_IOR('W', 0x01, struct snd_rawmidi_info)
+#define SNDRV_RAWMIDI_IOCTL_PARAMS	_IOWR('W', 0x10, struct snd_rawmidi_params)
+#define SNDRV_RAWMIDI_IOCTL_STATUS	_IOWR('W', 0x20, struct snd_rawmidi_status)
+#define SNDRV_RAWMIDI_IOCTL_DROP	_IOW('W', 0x30, int)
+#define SNDRV_RAWMIDI_IOCTL_DRAIN	_IOW('W', 0x31, int)
+
+/*
+ *  Timer section - /dev/snd/timer
+ */
+
+#define SNDRV_TIMER_VERSION		SNDRV_PROTOCOL_VERSION(2, 0, 6)
+
+enum {
+	SNDRV_TIMER_CLASS_NONE = -1,
+	SNDRV_TIMER_CLASS_SLAVE = 0,
+	SNDRV_TIMER_CLASS_GLOBAL,
+	SNDRV_TIMER_CLASS_CARD,
+	SNDRV_TIMER_CLASS_PCM,
+	SNDRV_TIMER_CLASS_LAST = SNDRV_TIMER_CLASS_PCM,
+};
+
+/* slave timer classes */
+enum {
+	SNDRV_TIMER_SCLASS_NONE = 0,
+	SNDRV_TIMER_SCLASS_APPLICATION,
+	SNDRV_TIMER_SCLASS_SEQUENCER,		/* alias */
+	SNDRV_TIMER_SCLASS_OSS_SEQUENCER,	/* alias */
+	SNDRV_TIMER_SCLASS_LAST = SNDRV_TIMER_SCLASS_OSS_SEQUENCER,
+};
+
+/* global timers (device member) */
+#define SNDRV_TIMER_GLOBAL_SYSTEM	0
+#define SNDRV_TIMER_GLOBAL_RTC		1
+#define SNDRV_TIMER_GLOBAL_HPET		2
+#define SNDRV_TIMER_GLOBAL_HRTIMER	3
+
+/* info flags */
+#define SNDRV_TIMER_FLG_SLAVE		(1<<0)	/* cannot be controlled */
+
+struct snd_timer_id {
+	int dev_class;
+	int dev_sclass;
+	int card;
+	int device;
+	int subdevice;
+};
+
+struct snd_timer_ginfo {
+	struct snd_timer_id tid;	/* requested timer ID */
+	unsigned int flags;		/* timer flags - SNDRV_TIMER_FLG_* */
+	int card;			/* card number */
+	unsigned char id[64];		/* timer identification */
+	unsigned char name[80];		/* timer name */
+	unsigned long reserved0;	/* reserved for future use */
+	unsigned long resolution;	/* average period resolution in ns */
+	unsigned long resolution_min;	/* minimal period resolution in ns */
+	unsigned long resolution_max;	/* maximal period resolution in ns */
+	unsigned int clients;		/* active timer clients */
+	unsigned char reserved[32];
+};
+
+struct snd_timer_gparams {
+	struct snd_timer_id tid;	/* requested timer ID */
+	unsigned long period_num;	/* requested precise period duration (in seconds) - numerator */
+	unsigned long period_den;	/* requested precise period duration (in seconds) - denominator */
+	unsigned char reserved[32];
+};
+
+struct snd_timer_gstatus {
+	struct snd_timer_id tid;	/* requested timer ID */
+	unsigned long resolution;	/* current period resolution in ns */
+	unsigned long resolution_num;	/* precise current period resolution (in seconds) - numerator */
+	unsigned long resolution_den;	/* precise current period resolution (in seconds) - denominator */
+	unsigned char reserved[32];
+};
+
+struct snd_timer_select {
+	struct snd_timer_id id;	/* bind to timer ID */
+	unsigned char reserved[32];	/* reserved */
+};
+
+struct snd_timer_info {
+	unsigned int flags;		/* timer flags - SNDRV_TIMER_FLG_* */
+	int card;			/* card number */
+	unsigned char id[64];		/* timer identificator */
+	unsigned char name[80];		/* timer name */
+	unsigned long reserved0;	/* reserved for future use */
+	unsigned long resolution;	/* average period resolution in ns */
+	unsigned char reserved[64];	/* reserved */
+};
+
+#define SNDRV_TIMER_PSFLG_AUTO		(1<<0)	/* auto start, otherwise one-shot */
+#define SNDRV_TIMER_PSFLG_EXCLUSIVE	(1<<1)	/* exclusive use, precise start/stop/pause/continue */
+#define SNDRV_TIMER_PSFLG_EARLY_EVENT	(1<<2)	/* write early event to the poll queue */
+
+struct snd_timer_params {
+	unsigned int flags;		/* flags - SNDRV_MIXER_PSFLG_* */
+	unsigned int ticks;		/* requested resolution in ticks */
+	unsigned int queue_size;	/* total size of queue (32-1024) */
+	unsigned int reserved0;		/* reserved, was: failure locations */
+	unsigned int filter;		/* event filter (bitmask of SNDRV_TIMER_EVENT_*) */
+	unsigned char reserved[60];	/* reserved */
+};
+
+struct snd_timer_status {
+	struct timespec tstamp;		/* Timestamp - last update */
+	unsigned int resolution;	/* current period resolution in ns */
+	unsigned int lost;		/* counter of master tick lost */
+	unsigned int overrun;		/* count of read queue overruns */
+	unsigned int queue;		/* used queue size */
+	unsigned char reserved[64];	/* reserved */
+};
+
+#define SNDRV_TIMER_IOCTL_PVERSION	_IOR('T', 0x00, int)
+#define SNDRV_TIMER_IOCTL_NEXT_DEVICE	_IOWR('T', 0x01, struct snd_timer_id)
+#define SNDRV_TIMER_IOCTL_TREAD		_IOW('T', 0x02, int)
+#define SNDRV_TIMER_IOCTL_GINFO		_IOWR('T', 0x03, struct snd_timer_ginfo)
+#define SNDRV_TIMER_IOCTL_GPARAMS	_IOW('T', 0x04, struct snd_timer_gparams)
+#define SNDRV_TIMER_IOCTL_GSTATUS	_IOWR('T', 0x05, struct snd_timer_gstatus)
+#define SNDRV_TIMER_IOCTL_SELECT	_IOW('T', 0x10, struct snd_timer_select)
+#define SNDRV_TIMER_IOCTL_INFO		_IOR('T', 0x11, struct snd_timer_info)
+#define SNDRV_TIMER_IOCTL_PARAMS	_IOW('T', 0x12, struct snd_timer_params)
+#define SNDRV_TIMER_IOCTL_STATUS	_IOR('T', 0x14, struct snd_timer_status)
+/* The following four ioctls are changed since 1.0.9 due to confliction */
+#define SNDRV_TIMER_IOCTL_START		_IO('T', 0xa0)
+#define SNDRV_TIMER_IOCTL_STOP		_IO('T', 0xa1)
+#define SNDRV_TIMER_IOCTL_CONTINUE	_IO('T', 0xa2)
+#define SNDRV_TIMER_IOCTL_PAUSE		_IO('T', 0xa3)
+
+struct snd_timer_read {
+	unsigned int resolution;
+	unsigned int ticks;
+};
+
+enum {
+	SNDRV_TIMER_EVENT_RESOLUTION = 0,	/* val = resolution in ns */
+	SNDRV_TIMER_EVENT_TICK,			/* val = ticks */
+	SNDRV_TIMER_EVENT_START,		/* val = resolution in ns */
+	SNDRV_TIMER_EVENT_STOP,			/* val = 0 */
+	SNDRV_TIMER_EVENT_CONTINUE,		/* val = resolution in ns */
+	SNDRV_TIMER_EVENT_PAUSE,		/* val = 0 */
+	SNDRV_TIMER_EVENT_EARLY,		/* val = 0, early event */
+	SNDRV_TIMER_EVENT_SUSPEND,		/* val = 0 */
+	SNDRV_TIMER_EVENT_RESUME,		/* val = resolution in ns */
+	/* master timer events for slave timer instances */
+	SNDRV_TIMER_EVENT_MSTART = SNDRV_TIMER_EVENT_START + 10,
+	SNDRV_TIMER_EVENT_MSTOP = SNDRV_TIMER_EVENT_STOP + 10,
+	SNDRV_TIMER_EVENT_MCONTINUE = SNDRV_TIMER_EVENT_CONTINUE + 10,
+	SNDRV_TIMER_EVENT_MPAUSE = SNDRV_TIMER_EVENT_PAUSE + 10,
+	SNDRV_TIMER_EVENT_MSUSPEND = SNDRV_TIMER_EVENT_SUSPEND + 10,
+	SNDRV_TIMER_EVENT_MRESUME = SNDRV_TIMER_EVENT_RESUME + 10,
+};
+
+struct snd_timer_tread {
+	int event;
+	struct timespec tstamp;
+	unsigned int val;
+};
+
+/****************************************************************************
+ *                                                                          *
+ *        Section for driver control interface - /dev/snd/control?          *
+ *                                                                          *
+ ****************************************************************************/
+
+#define SNDRV_CTL_VERSION		SNDRV_PROTOCOL_VERSION(2, 0, 7)
+
+struct snd_ctl_card_info {
+	int card;			/* card number */
+	int pad;			/* reserved for future (was type) */
+	unsigned char id[16];		/* ID of card (user selectable) */
+	unsigned char driver[16];	/* Driver name */
+	unsigned char name[32];		/* Short name of soundcard */
+	unsigned char longname[80];	/* name + info text about soundcard */
+	unsigned char reserved_[16];	/* reserved for future (was ID of mixer) */
+	unsigned char mixername[80];	/* visual mixer identification */
+	unsigned char components[128];	/* card components / fine identification, delimited with one space (AC97 etc..) */
+};
+
+typedef int __bitwise snd_ctl_elem_type_t;
+#define	SNDRV_CTL_ELEM_TYPE_NONE	((__force snd_ctl_elem_type_t) 0) /* invalid */
+#define	SNDRV_CTL_ELEM_TYPE_BOOLEAN	((__force snd_ctl_elem_type_t) 1) /* boolean type */
+#define	SNDRV_CTL_ELEM_TYPE_INTEGER	((__force snd_ctl_elem_type_t) 2) /* integer type */
+#define	SNDRV_CTL_ELEM_TYPE_ENUMERATED	((__force snd_ctl_elem_type_t) 3) /* enumerated type */
+#define	SNDRV_CTL_ELEM_TYPE_BYTES	((__force snd_ctl_elem_type_t) 4) /* byte array */
+#define	SNDRV_CTL_ELEM_TYPE_IEC958	((__force snd_ctl_elem_type_t) 5) /* IEC958 (S/PDIF) setup */
+#define	SNDRV_CTL_ELEM_TYPE_INTEGER64	((__force snd_ctl_elem_type_t) 6) /* 64-bit integer type */
+#define	SNDRV_CTL_ELEM_TYPE_LAST	SNDRV_CTL_ELEM_TYPE_INTEGER64
+
+typedef int __bitwise snd_ctl_elem_iface_t;
+#define	SNDRV_CTL_ELEM_IFACE_CARD	((__force snd_ctl_elem_iface_t) 0) /* global control */
+#define	SNDRV_CTL_ELEM_IFACE_HWDEP	((__force snd_ctl_elem_iface_t) 1) /* hardware dependent device */
+#define	SNDRV_CTL_ELEM_IFACE_MIXER	((__force snd_ctl_elem_iface_t) 2) /* virtual mixer device */
+#define	SNDRV_CTL_ELEM_IFACE_PCM	((__force snd_ctl_elem_iface_t) 3) /* PCM device */
+#define	SNDRV_CTL_ELEM_IFACE_RAWMIDI	((__force snd_ctl_elem_iface_t) 4) /* RawMidi device */
+#define	SNDRV_CTL_ELEM_IFACE_TIMER	((__force snd_ctl_elem_iface_t) 5) /* timer device */
+#define	SNDRV_CTL_ELEM_IFACE_SEQUENCER	((__force snd_ctl_elem_iface_t) 6) /* sequencer client */
+#define	SNDRV_CTL_ELEM_IFACE_LAST	SNDRV_CTL_ELEM_IFACE_SEQUENCER
+
+#define SNDRV_CTL_ELEM_ACCESS_READ		(1<<0)
+#define SNDRV_CTL_ELEM_ACCESS_WRITE		(1<<1)
+#define SNDRV_CTL_ELEM_ACCESS_READWRITE		(SNDRV_CTL_ELEM_ACCESS_READ|SNDRV_CTL_ELEM_ACCESS_WRITE)
+#define SNDRV_CTL_ELEM_ACCESS_VOLATILE		(1<<2)	/* control value may be changed without a notification */
+#define SNDRV_CTL_ELEM_ACCESS_TIMESTAMP		(1<<3)	/* when was control changed */
+#define SNDRV_CTL_ELEM_ACCESS_TLV_READ		(1<<4)	/* TLV read is possible */
+#define SNDRV_CTL_ELEM_ACCESS_TLV_WRITE		(1<<5)	/* TLV write is possible */
+#define SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE	(SNDRV_CTL_ELEM_ACCESS_TLV_READ|SNDRV_CTL_ELEM_ACCESS_TLV_WRITE)
+#define SNDRV_CTL_ELEM_ACCESS_TLV_COMMAND	(1<<6)	/* TLV command is possible */
+#define SNDRV_CTL_ELEM_ACCESS_INACTIVE		(1<<8)	/* control does actually nothing, but may be updated */
+#define SNDRV_CTL_ELEM_ACCESS_LOCK		(1<<9)	/* write lock */
+#define SNDRV_CTL_ELEM_ACCESS_OWNER		(1<<10)	/* write lock owner */
+#define SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK	(1<<28)	/* kernel use a TLV callback */ 
+#define SNDRV_CTL_ELEM_ACCESS_USER		(1<<29) /* user space element */
+/* bits 30 and 31 are obsoleted (for indirect access) */
+
+/* for further details see the ACPI and PCI power management specification */
+#define SNDRV_CTL_POWER_D0		0x0000	/* full On */
+#define SNDRV_CTL_POWER_D1		0x0100	/* partial On */
+#define SNDRV_CTL_POWER_D2		0x0200	/* partial On */
+#define SNDRV_CTL_POWER_D3		0x0300	/* Off */
+#define SNDRV_CTL_POWER_D3hot		(SNDRV_CTL_POWER_D3|0x0000)	/* Off, with power */
+#define SNDRV_CTL_POWER_D3cold		(SNDRV_CTL_POWER_D3|0x0001)	/* Off, without power */
+
+struct snd_ctl_elem_id {
+	unsigned int numid;		/* numeric identifier, zero = invalid */
+	snd_ctl_elem_iface_t iface;	/* interface identifier */
+	unsigned int device;		/* device/client number */
+	unsigned int subdevice;		/* subdevice (substream) number */
+	unsigned char name[44];		/* ASCII name of item */
+	unsigned int index;		/* index of item */
+};
+
+struct snd_ctl_elem_list {
+	unsigned int offset;		/* W: first element ID to get */
+	unsigned int space;		/* W: count of element IDs to get */
+	unsigned int used;		/* R: count of element IDs set */
+	unsigned int count;		/* R: count of all elements */
+	struct snd_ctl_elem_id __user *pids; /* R: IDs */
+	unsigned char reserved[50];
+};
+
+struct snd_ctl_elem_info {
+	struct snd_ctl_elem_id id;	/* W: element ID */
+	snd_ctl_elem_type_t type;	/* R: value type - SNDRV_CTL_ELEM_TYPE_* */
+	unsigned int access;		/* R: value access (bitmask) - SNDRV_CTL_ELEM_ACCESS_* */
+	unsigned int count;		/* count of values */
+	__kernel_pid_t owner;		/* owner's PID of this control */
+	union {
+		struct {
+			long min;		/* R: minimum value */
+			long max;		/* R: maximum value */
+			long step;		/* R: step (0 variable) */
+		} integer;
+		struct {
+			long long min;		/* R: minimum value */
+			long long max;		/* R: maximum value */
+			long long step;		/* R: step (0 variable) */
+		} integer64;
+		struct {
+			unsigned int items;	/* R: number of items */
+			unsigned int item;	/* W: item number */
+			char name[64];		/* R: value name */
+			__u64 names_ptr;	/* W: names list (ELEM_ADD only) */
+			unsigned int names_length;
+		} enumerated;
+		unsigned char reserved[128];
+	} value;
+	union {
+		unsigned short d[4];		/* dimensions */
+		unsigned short *d_ptr;		/* indirect - obsoleted */
+	} dimen;
+	unsigned char reserved[64-4*sizeof(unsigned short)];
+};
+
+struct snd_ctl_elem_value {
+	struct snd_ctl_elem_id id;	/* W: element ID */
+	unsigned int indirect: 1;	/* W: indirect access - obsoleted */
+	union {
+		union {
+			long value[128];
+			long *value_ptr;	/* obsoleted */
+		} integer;
+		union {
+			long long value[64];
+			long long *value_ptr;	/* obsoleted */
+		} integer64;
+		union {
+			unsigned int item[128];
+			unsigned int *item_ptr;	/* obsoleted */
+		} enumerated;
+		union {
+			unsigned char data[512];
+			unsigned char *data_ptr;	/* obsoleted */
+		} bytes;
+		struct snd_aes_iec958 iec958;
+	} value;		/* RO */
+	struct timespec tstamp;
+	unsigned char reserved[128-sizeof(struct timespec)];
+};
+
+struct snd_ctl_tlv {
+	unsigned int numid;	/* control element numeric identification */
+	unsigned int length;	/* in bytes aligned to 4 */
+	unsigned int tlv[0];	/* first TLV */
+};
+
+#define SNDRV_CTL_IOCTL_PVERSION	_IOR('U', 0x00, int)
+#define SNDRV_CTL_IOCTL_CARD_INFO	_IOR('U', 0x01, struct snd_ctl_card_info)
+#define SNDRV_CTL_IOCTL_ELEM_LIST	_IOWR('U', 0x10, struct snd_ctl_elem_list)
+#define SNDRV_CTL_IOCTL_ELEM_INFO	_IOWR('U', 0x11, struct snd_ctl_elem_info)
+#define SNDRV_CTL_IOCTL_ELEM_READ	_IOWR('U', 0x12, struct snd_ctl_elem_value)
+#define SNDRV_CTL_IOCTL_ELEM_WRITE	_IOWR('U', 0x13, struct snd_ctl_elem_value)
+#define SNDRV_CTL_IOCTL_ELEM_LOCK	_IOW('U', 0x14, struct snd_ctl_elem_id)
+#define SNDRV_CTL_IOCTL_ELEM_UNLOCK	_IOW('U', 0x15, struct snd_ctl_elem_id)
+#define SNDRV_CTL_IOCTL_SUBSCRIBE_EVENTS _IOWR('U', 0x16, int)
+#define SNDRV_CTL_IOCTL_ELEM_ADD	_IOWR('U', 0x17, struct snd_ctl_elem_info)
+#define SNDRV_CTL_IOCTL_ELEM_REPLACE	_IOWR('U', 0x18, struct snd_ctl_elem_info)
+#define SNDRV_CTL_IOCTL_ELEM_REMOVE	_IOWR('U', 0x19, struct snd_ctl_elem_id)
+#define SNDRV_CTL_IOCTL_TLV_READ	_IOWR('U', 0x1a, struct snd_ctl_tlv)
+#define SNDRV_CTL_IOCTL_TLV_WRITE	_IOWR('U', 0x1b, struct snd_ctl_tlv)
+#define SNDRV_CTL_IOCTL_TLV_COMMAND	_IOWR('U', 0x1c, struct snd_ctl_tlv)
+#define SNDRV_CTL_IOCTL_HWDEP_NEXT_DEVICE _IOWR('U', 0x20, int)
+#define SNDRV_CTL_IOCTL_HWDEP_INFO	_IOR('U', 0x21, struct snd_hwdep_info)
+#define SNDRV_CTL_IOCTL_PCM_NEXT_DEVICE	_IOR('U', 0x30, int)
+#define SNDRV_CTL_IOCTL_PCM_INFO	_IOWR('U', 0x31, struct snd_pcm_info)
+#define SNDRV_CTL_IOCTL_PCM_PREFER_SUBDEVICE _IOW('U', 0x32, int)
+#define SNDRV_CTL_IOCTL_RAWMIDI_NEXT_DEVICE _IOWR('U', 0x40, int)
+#define SNDRV_CTL_IOCTL_RAWMIDI_INFO	_IOWR('U', 0x41, struct snd_rawmidi_info)
+#define SNDRV_CTL_IOCTL_RAWMIDI_PREFER_SUBDEVICE _IOW('U', 0x42, int)
+#define SNDRV_CTL_IOCTL_POWER		_IOWR('U', 0xd0, int)
+#define SNDRV_CTL_IOCTL_POWER_STATE	_IOR('U', 0xd1, int)
+
+/*
+ *  Read interface.
+ */
+
+enum sndrv_ctl_event_type {
+	SNDRV_CTL_EVENT_ELEM = 0,
+	SNDRV_CTL_EVENT_LAST = SNDRV_CTL_EVENT_ELEM,
+};
+
+#define SNDRV_CTL_EVENT_MASK_VALUE	(1<<0)	/* element value was changed */
+#define SNDRV_CTL_EVENT_MASK_INFO	(1<<1)	/* element info was changed */
+#define SNDRV_CTL_EVENT_MASK_ADD	(1<<2)	/* element was added */
+#define SNDRV_CTL_EVENT_MASK_TLV	(1<<3)	/* element TLV tree was changed */
+#define SNDRV_CTL_EVENT_MASK_REMOVE	(~0U)	/* element was removed */
+
+struct snd_ctl_event {
+	int type;	/* event type - SNDRV_CTL_EVENT_* */
+	union {
+		struct {
+			unsigned int mask;
+			struct snd_ctl_elem_id id;
+		} elem;
+		unsigned char data8[60];
+	} data;
+};
+
+/*
+ *  Control names
+ */
+
+#define SNDRV_CTL_NAME_NONE				""
+#define SNDRV_CTL_NAME_PLAYBACK				"Playback "
+#define SNDRV_CTL_NAME_CAPTURE				"Capture "
+
+#define SNDRV_CTL_NAME_IEC958_NONE			""
+#define SNDRV_CTL_NAME_IEC958_SWITCH			"Switch"
+#define SNDRV_CTL_NAME_IEC958_VOLUME			"Volume"
+#define SNDRV_CTL_NAME_IEC958_DEFAULT			"Default"
+#define SNDRV_CTL_NAME_IEC958_MASK			"Mask"
+#define SNDRV_CTL_NAME_IEC958_CON_MASK			"Con Mask"
+#define SNDRV_CTL_NAME_IEC958_PRO_MASK			"Pro Mask"
+#define SNDRV_CTL_NAME_IEC958_PCM_STREAM		"PCM Stream"
+#define SNDRV_CTL_NAME_IEC958(expl,direction,what)	"IEC958 " expl SNDRV_CTL_NAME_##direction SNDRV_CTL_NAME_IEC958_##what
+
+#endif /* _UAPI__SOUND_ASOUND_H */
diff --git a/include/sound/asound_fm.h b/include/uapi/sound/asound_fm.h
similarity index 100%
rename from include/sound/asound_fm.h
rename to include/uapi/sound/asound_fm.h
diff --git a/include/sound/compress_offload.h b/include/uapi/sound/compress_offload.h
similarity index 100%
rename from include/sound/compress_offload.h
rename to include/uapi/sound/compress_offload.h
diff --git a/include/sound/compress_params.h b/include/uapi/sound/compress_params.h
similarity index 100%
rename from include/sound/compress_params.h
rename to include/uapi/sound/compress_params.h
diff --git a/include/uapi/sound/emu10k1.h b/include/uapi/sound/emu10k1.h
new file mode 100644
index 0000000..d1bbaf7
--- /dev/null
+++ b/include/uapi/sound/emu10k1.h
@@ -0,0 +1,373 @@
+/*
+ *  Copyright (c) by Jaroslav Kysela <perex@perex.cz>,
+ *		     Creative Labs, Inc.
+ *  Definitions for EMU10K1 (SB Live!) chips
+ *
+ *
+ *   This program is free software; 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 _UAPI__SOUND_EMU10K1_H
+#define _UAPI__SOUND_EMU10K1_H
+
+#include <linux/types.h>
+
+
+
+/*
+ * ---- FX8010 ----
+ */
+
+#define EMU10K1_CARD_CREATIVE			0x00000000
+#define EMU10K1_CARD_EMUAPS			0x00000001
+
+#define EMU10K1_FX8010_PCM_COUNT		8
+
+/* instruction set */
+#define iMAC0	 0x00	/* R = A + (X * Y >> 31)   ; saturation */
+#define iMAC1	 0x01	/* R = A + (-X * Y >> 31)  ; saturation */
+#define iMAC2	 0x02	/* R = A + (X * Y >> 31)   ; wraparound */
+#define iMAC3	 0x03	/* R = A + (-X * Y >> 31)  ; wraparound */
+#define iMACINT0 0x04	/* R = A + X * Y	   ; saturation */
+#define iMACINT1 0x05	/* R = A + X * Y	   ; wraparound (31-bit) */
+#define iACC3	 0x06	/* R = A + X + Y	   ; saturation */
+#define iMACMV   0x07	/* R = A, acc += X * Y >> 31 */
+#define iANDXOR  0x08	/* R = (A & X) ^ Y */
+#define iTSTNEG  0x09	/* R = (A >= Y) ? X : ~X */
+#define iLIMITGE 0x0a	/* R = (A >= Y) ? X : Y */
+#define iLIMITLT 0x0b	/* R = (A < Y) ? X : Y */
+#define iLOG	 0x0c	/* R = linear_data, A (log_data), X (max_exp), Y (format_word) */
+#define iEXP	 0x0d	/* R = log_data, A (linear_data), X (max_exp), Y (format_word) */
+#define iINTERP  0x0e	/* R = A + (X * (Y - A) >> 31)  ; saturation */
+#define iSKIP    0x0f	/* R = A (cc_reg), X (count), Y (cc_test) */
+
+/* GPRs */
+#define FXBUS(x)	(0x00 + (x))	/* x = 0x00 - 0x0f */
+#define EXTIN(x)	(0x10 + (x))	/* x = 0x00 - 0x0f */
+#define EXTOUT(x)	(0x20 + (x))	/* x = 0x00 - 0x0f physical outs -> FXWC low 16 bits */
+#define FXBUS2(x)	(0x30 + (x))	/* x = 0x00 - 0x0f copies of fx buses for capture -> FXWC high 16 bits */
+					/* NB: 0x31 and 0x32 are shared with Center/LFE on SB live 5.1 */
+
+#define C_00000000	0x40
+#define C_00000001	0x41
+#define C_00000002	0x42
+#define C_00000003	0x43
+#define C_00000004	0x44
+#define C_00000008	0x45
+#define C_00000010	0x46
+#define C_00000020	0x47
+#define C_00000100	0x48
+#define C_00010000	0x49
+#define C_00080000	0x4a
+#define C_10000000	0x4b
+#define C_20000000	0x4c
+#define C_40000000	0x4d
+#define C_80000000	0x4e
+#define C_7fffffff	0x4f
+#define C_ffffffff	0x50
+#define C_fffffffe	0x51
+#define C_c0000000	0x52
+#define C_4f1bbcdc	0x53
+#define C_5a7ef9db	0x54
+#define C_00100000	0x55		/* ?? */
+#define GPR_ACCU	0x56		/* ACCUM, accumulator */
+#define GPR_COND	0x57		/* CCR, condition register */
+#define GPR_NOISE0	0x58		/* noise source */
+#define GPR_NOISE1	0x59		/* noise source */
+#define GPR_IRQ		0x5a		/* IRQ register */
+#define GPR_DBAC	0x5b		/* TRAM Delay Base Address Counter */
+#define GPR(x)		(FXGPREGBASE + (x)) /* free GPRs: x = 0x00 - 0xff */
+#define ITRAM_DATA(x)	(TANKMEMDATAREGBASE + 0x00 + (x)) /* x = 0x00 - 0x7f */
+#define ETRAM_DATA(x)	(TANKMEMDATAREGBASE + 0x80 + (x)) /* x = 0x00 - 0x1f */
+#define ITRAM_ADDR(x)	(TANKMEMADDRREGBASE + 0x00 + (x)) /* x = 0x00 - 0x7f */
+#define ETRAM_ADDR(x)	(TANKMEMADDRREGBASE + 0x80 + (x)) /* x = 0x00 - 0x1f */
+
+#define A_ITRAM_DATA(x)	(TANKMEMDATAREGBASE + 0x00 + (x)) /* x = 0x00 - 0xbf */
+#define A_ETRAM_DATA(x)	(TANKMEMDATAREGBASE + 0xc0 + (x)) /* x = 0x00 - 0x3f */
+#define A_ITRAM_ADDR(x)	(TANKMEMADDRREGBASE + 0x00 + (x)) /* x = 0x00 - 0xbf */
+#define A_ETRAM_ADDR(x)	(TANKMEMADDRREGBASE + 0xc0 + (x)) /* x = 0x00 - 0x3f */
+#define A_ITRAM_CTL(x)	(A_TANKMEMCTLREGBASE + 0x00 + (x)) /* x = 0x00 - 0xbf */
+#define A_ETRAM_CTL(x)	(A_TANKMEMCTLREGBASE + 0xc0 + (x)) /* x = 0x00 - 0x3f */
+
+#define A_FXBUS(x)	(0x00 + (x))	/* x = 0x00 - 0x3f FX buses */
+#define A_EXTIN(x)	(0x40 + (x))	/* x = 0x00 - 0x0f physical ins */
+#define A_P16VIN(x)	(0x50 + (x))	/* x = 0x00 - 0x0f p16v ins (A2 only) "EMU32 inputs" */
+#define A_EXTOUT(x)	(0x60 + (x))	/* x = 0x00 - 0x1f physical outs -> A_FXWC1 0x79-7f unknown   */
+#define A_FXBUS2(x)	(0x80 + (x))	/* x = 0x00 - 0x1f extra outs used for EFX capture -> A_FXWC2 */
+#define A_EMU32OUTH(x)	(0xa0 + (x))	/* x = 0x00 - 0x0f "EMU32_OUT_10 - _1F" - ??? */
+#define A_EMU32OUTL(x)	(0xb0 + (x))	/* x = 0x00 - 0x0f "EMU32_OUT_1 - _F" - ??? */
+#define A3_EMU32IN(x)	(0x160 + (x))	/* x = 0x00 - 0x3f "EMU32_IN_00 - _3F" - Only when .device = 0x0008 */
+#define A3_EMU32OUT(x)	(0x1E0 + (x))	/* x = 0x00 - 0x0f "EMU32_OUT_00 - _3F" - Only when .device = 0x0008 */
+#define A_GPR(x)	(A_FXGPREGBASE + (x))
+
+/* cc_reg constants */
+#define CC_REG_NORMALIZED C_00000001
+#define CC_REG_BORROW	C_00000002
+#define CC_REG_MINUS	C_00000004
+#define CC_REG_ZERO	C_00000008
+#define CC_REG_SATURATE	C_00000010
+#define CC_REG_NONZERO	C_00000100
+
+/* FX buses */
+#define FXBUS_PCM_LEFT		0x00
+#define FXBUS_PCM_RIGHT		0x01
+#define FXBUS_PCM_LEFT_REAR	0x02
+#define FXBUS_PCM_RIGHT_REAR	0x03
+#define FXBUS_MIDI_LEFT		0x04
+#define FXBUS_MIDI_RIGHT	0x05
+#define FXBUS_PCM_CENTER	0x06
+#define FXBUS_PCM_LFE		0x07
+#define FXBUS_PCM_LEFT_FRONT	0x08
+#define FXBUS_PCM_RIGHT_FRONT	0x09
+#define FXBUS_MIDI_REVERB	0x0c
+#define FXBUS_MIDI_CHORUS	0x0d
+#define FXBUS_PCM_LEFT_SIDE	0x0e
+#define FXBUS_PCM_RIGHT_SIDE	0x0f
+#define FXBUS_PT_LEFT		0x14
+#define FXBUS_PT_RIGHT		0x15
+
+/* Inputs */
+#define EXTIN_AC97_L	   0x00	/* AC'97 capture channel - left */
+#define EXTIN_AC97_R	   0x01	/* AC'97 capture channel - right */
+#define EXTIN_SPDIF_CD_L   0x02	/* internal S/PDIF CD - onboard - left */
+#define EXTIN_SPDIF_CD_R   0x03	/* internal S/PDIF CD - onboard - right */
+#define EXTIN_ZOOM_L	   0x04	/* Zoom Video I2S - left */
+#define EXTIN_ZOOM_R	   0x05	/* Zoom Video I2S - right */
+#define EXTIN_TOSLINK_L	   0x06	/* LiveDrive - TOSLink Optical - left */
+#define EXTIN_TOSLINK_R    0x07	/* LiveDrive - TOSLink Optical - right */
+#define EXTIN_LINE1_L	   0x08	/* LiveDrive - Line/Mic 1 - left */
+#define EXTIN_LINE1_R	   0x09	/* LiveDrive - Line/Mic 1 - right */
+#define EXTIN_COAX_SPDIF_L 0x0a	/* LiveDrive - Coaxial S/PDIF - left */
+#define EXTIN_COAX_SPDIF_R 0x0b /* LiveDrive - Coaxial S/PDIF - right */
+#define EXTIN_LINE2_L	   0x0c	/* LiveDrive - Line/Mic 2 - left */
+#define EXTIN_LINE2_R	   0x0d	/* LiveDrive - Line/Mic 2 - right */
+
+/* Outputs */
+#define EXTOUT_AC97_L	   0x00	/* AC'97 playback channel - left */
+#define EXTOUT_AC97_R	   0x01	/* AC'97 playback channel - right */
+#define EXTOUT_TOSLINK_L   0x02	/* LiveDrive - TOSLink Optical - left */
+#define EXTOUT_TOSLINK_R   0x03	/* LiveDrive - TOSLink Optical - right */
+#define EXTOUT_AC97_CENTER 0x04	/* SB Live 5.1 - center */
+#define EXTOUT_AC97_LFE	   0x05 /* SB Live 5.1 - LFE */
+#define EXTOUT_HEADPHONE_L 0x06	/* LiveDrive - Headphone - left */
+#define EXTOUT_HEADPHONE_R 0x07	/* LiveDrive - Headphone - right */
+#define EXTOUT_REAR_L	   0x08	/* Rear channel - left */
+#define EXTOUT_REAR_R	   0x09	/* Rear channel - right */
+#define EXTOUT_ADC_CAP_L   0x0a	/* ADC Capture buffer - left */
+#define EXTOUT_ADC_CAP_R   0x0b	/* ADC Capture buffer - right */
+#define EXTOUT_MIC_CAP	   0x0c	/* MIC Capture buffer */
+#define EXTOUT_AC97_REAR_L 0x0d	/* SB Live 5.1 (c) 2003 - Rear Left */
+#define EXTOUT_AC97_REAR_R 0x0e	/* SB Live 5.1 (c) 2003 - Rear Right */
+#define EXTOUT_ACENTER	   0x11 /* Analog Center */
+#define EXTOUT_ALFE	   0x12 /* Analog LFE */
+
+/* Audigy Inputs */
+#define A_EXTIN_AC97_L		0x00	/* AC'97 capture channel - left */
+#define A_EXTIN_AC97_R		0x01	/* AC'97 capture channel - right */
+#define A_EXTIN_SPDIF_CD_L	0x02	/* digital CD left */
+#define A_EXTIN_SPDIF_CD_R	0x03	/* digital CD left */
+#define A_EXTIN_OPT_SPDIF_L     0x04    /* audigy drive Optical SPDIF - left */
+#define A_EXTIN_OPT_SPDIF_R     0x05    /*                              right */ 
+#define A_EXTIN_LINE2_L		0x08	/* audigy drive line2/mic2 - left */
+#define A_EXTIN_LINE2_R		0x09	/*                           right */
+#define A_EXTIN_ADC_L		0x0a    /* Philips ADC - left */
+#define A_EXTIN_ADC_R		0x0b    /*               right */
+#define A_EXTIN_AUX2_L		0x0c	/* audigy drive aux2 - left */
+#define A_EXTIN_AUX2_R		0x0d	/*                   - right */
+
+/* Audigiy Outputs */
+#define A_EXTOUT_FRONT_L	0x00	/* digital front left */
+#define A_EXTOUT_FRONT_R	0x01	/*               right */
+#define A_EXTOUT_CENTER		0x02	/* digital front center */
+#define A_EXTOUT_LFE		0x03	/* digital front lfe */
+#define A_EXTOUT_HEADPHONE_L	0x04	/* headphone audigy drive left */
+#define A_EXTOUT_HEADPHONE_R	0x05	/*                        right */
+#define A_EXTOUT_REAR_L		0x06	/* digital rear left */
+#define A_EXTOUT_REAR_R		0x07	/*              right */
+#define A_EXTOUT_AFRONT_L	0x08	/* analog front left */
+#define A_EXTOUT_AFRONT_R	0x09	/*              right */
+#define A_EXTOUT_ACENTER	0x0a	/* analog center */
+#define A_EXTOUT_ALFE		0x0b	/* analog LFE */
+#define A_EXTOUT_ASIDE_L	0x0c	/* analog side left  - Audigy 2 ZS */
+#define A_EXTOUT_ASIDE_R	0x0d	/*             right - Audigy 2 ZS */
+#define A_EXTOUT_AREAR_L	0x0e	/* analog rear left */
+#define A_EXTOUT_AREAR_R	0x0f	/*             right */
+#define A_EXTOUT_AC97_L		0x10	/* AC97 left (front) */
+#define A_EXTOUT_AC97_R		0x11	/*      right */
+#define A_EXTOUT_ADC_CAP_L	0x16	/* ADC capture buffer left */
+#define A_EXTOUT_ADC_CAP_R	0x17	/*                    right */
+#define A_EXTOUT_MIC_CAP	0x18	/* Mic capture buffer */
+
+/* Audigy constants */
+#define A_C_00000000	0xc0
+#define A_C_00000001	0xc1
+#define A_C_00000002	0xc2
+#define A_C_00000003	0xc3
+#define A_C_00000004	0xc4
+#define A_C_00000008	0xc5
+#define A_C_00000010	0xc6
+#define A_C_00000020	0xc7
+#define A_C_00000100	0xc8
+#define A_C_00010000	0xc9
+#define A_C_00000800	0xca
+#define A_C_10000000	0xcb
+#define A_C_20000000	0xcc
+#define A_C_40000000	0xcd
+#define A_C_80000000	0xce
+#define A_C_7fffffff	0xcf
+#define A_C_ffffffff	0xd0
+#define A_C_fffffffe	0xd1
+#define A_C_c0000000	0xd2
+#define A_C_4f1bbcdc	0xd3
+#define A_C_5a7ef9db	0xd4
+#define A_C_00100000	0xd5
+#define A_GPR_ACCU	0xd6		/* ACCUM, accumulator */
+#define A_GPR_COND	0xd7		/* CCR, condition register */
+#define A_GPR_NOISE0	0xd8		/* noise source */
+#define A_GPR_NOISE1	0xd9		/* noise source */
+#define A_GPR_IRQ	0xda		/* IRQ register */
+#define A_GPR_DBAC	0xdb		/* TRAM Delay Base Address Counter - internal */
+#define A_GPR_DBACE	0xde		/* TRAM Delay Base Address Counter - external */
+
+/* definitions for debug register */
+#define EMU10K1_DBG_ZC			0x80000000	/* zero tram counter */
+#define EMU10K1_DBG_SATURATION_OCCURED	0x02000000	/* saturation control */
+#define EMU10K1_DBG_SATURATION_ADDR	0x01ff0000	/* saturation address */
+#define EMU10K1_DBG_SINGLE_STEP		0x00008000	/* single step mode */
+#define EMU10K1_DBG_STEP		0x00004000	/* start single step */
+#define EMU10K1_DBG_CONDITION_CODE	0x00003e00	/* condition code */
+#define EMU10K1_DBG_SINGLE_STEP_ADDR	0x000001ff	/* single step address */
+
+/* tank memory address line */
+#ifndef __KERNEL__
+#define TANKMEMADDRREG_ADDR_MASK 0x000fffff	/* 20 bit tank address field			*/
+#define TANKMEMADDRREG_CLEAR	 0x00800000	/* Clear tank memory				*/
+#define TANKMEMADDRREG_ALIGN	 0x00400000	/* Align read or write relative to tank access	*/
+#define TANKMEMADDRREG_WRITE	 0x00200000	/* Write to tank memory				*/
+#define TANKMEMADDRREG_READ	 0x00100000	/* Read from tank memory			*/
+#endif
+
+struct snd_emu10k1_fx8010_info {
+	unsigned int internal_tram_size;	/* in samples */
+	unsigned int external_tram_size;	/* in samples */
+	char fxbus_names[16][32];		/* names of FXBUSes */
+	char extin_names[16][32];		/* names of external inputs */
+	char extout_names[32][32];		/* names of external outputs */
+	unsigned int gpr_controls;		/* count of GPR controls */
+};
+
+#define EMU10K1_GPR_TRANSLATION_NONE		0
+#define EMU10K1_GPR_TRANSLATION_TABLE100	1
+#define EMU10K1_GPR_TRANSLATION_BASS		2
+#define EMU10K1_GPR_TRANSLATION_TREBLE		3
+#define EMU10K1_GPR_TRANSLATION_ONOFF		4
+
+struct snd_emu10k1_fx8010_control_gpr {
+	struct snd_ctl_elem_id id;		/* full control ID definition */
+	unsigned int vcount;		/* visible count */
+	unsigned int count;		/* count of GPR (1..16) */
+	unsigned short gpr[32];		/* GPR number(s) */
+	unsigned int value[32];		/* initial values */
+	unsigned int min;		/* minimum range */
+	unsigned int max;		/* maximum range */
+	unsigned int translation;	/* translation type (EMU10K1_GPR_TRANSLATION*) */
+	const unsigned int *tlv;
+};
+
+/* old ABI without TLV support */
+struct snd_emu10k1_fx8010_control_old_gpr {
+	struct snd_ctl_elem_id id;
+	unsigned int vcount;
+	unsigned int count;
+	unsigned short gpr[32];
+	unsigned int value[32];
+	unsigned int min;
+	unsigned int max;
+	unsigned int translation;
+};
+
+struct snd_emu10k1_fx8010_code {
+	char name[128];
+
+	DECLARE_BITMAP(gpr_valid, 0x200); /* bitmask of valid initializers */
+	__u32 __user *gpr_map;		/* initializers */
+
+	unsigned int gpr_add_control_count; /* count of GPR controls to add/replace */
+	struct snd_emu10k1_fx8010_control_gpr __user *gpr_add_controls; /* GPR controls to add/replace */
+
+	unsigned int gpr_del_control_count; /* count of GPR controls to remove */
+	struct snd_ctl_elem_id __user *gpr_del_controls; /* IDs of GPR controls to remove */
+
+	unsigned int gpr_list_control_count; /* count of GPR controls to list */
+	unsigned int gpr_list_control_total; /* total count of GPR controls */
+	struct snd_emu10k1_fx8010_control_gpr __user *gpr_list_controls; /* listed GPR controls */
+
+	DECLARE_BITMAP(tram_valid, 0x100); /* bitmask of valid initializers */
+	__u32 __user *tram_data_map;	  /* data initializers */
+	__u32 __user *tram_addr_map;	  /* map initializers */
+
+	DECLARE_BITMAP(code_valid, 1024); /* bitmask of valid instructions */
+	__u32 __user *code;		  /* one instruction - 64 bits */
+};
+
+struct snd_emu10k1_fx8010_tram {
+	unsigned int address;		/* 31.bit == 1 -> external TRAM */
+	unsigned int size;		/* size in samples (4 bytes) */
+	unsigned int *samples;		/* pointer to samples (20-bit) */
+					/* NULL->clear memory */
+};
+
+struct snd_emu10k1_fx8010_pcm_rec {
+	unsigned int substream;		/* substream number */
+	unsigned int res1;		/* reserved */
+	unsigned int channels;		/* 16-bit channels count, zero = remove this substream */
+	unsigned int tram_start;	/* ring buffer position in TRAM (in samples) */
+	unsigned int buffer_size;	/* count of buffered samples */
+	unsigned short gpr_size;		/* GPR containing size of ringbuffer in samples (host) */
+	unsigned short gpr_ptr;		/* GPR containing current pointer in the ring buffer (host = reset, FX8010) */
+	unsigned short gpr_count;	/* GPR containing count of samples between two interrupts (host) */
+	unsigned short gpr_tmpcount;	/* GPR containing current count of samples to interrupt (host = set, FX8010) */
+	unsigned short gpr_trigger;	/* GPR containing trigger (activate) information (host) */
+	unsigned short gpr_running;	/* GPR containing info if PCM is running (FX8010) */
+	unsigned char pad;		/* reserved */
+	unsigned char etram[32];	/* external TRAM address & data (one per channel) */
+	unsigned int res2;		/* reserved */
+};
+
+#define SNDRV_EMU10K1_VERSION		SNDRV_PROTOCOL_VERSION(1, 0, 1)
+
+#define SNDRV_EMU10K1_IOCTL_INFO	_IOR ('H', 0x10, struct snd_emu10k1_fx8010_info)
+#define SNDRV_EMU10K1_IOCTL_CODE_POKE	_IOW ('H', 0x11, struct snd_emu10k1_fx8010_code)
+#define SNDRV_EMU10K1_IOCTL_CODE_PEEK	_IOWR('H', 0x12, struct snd_emu10k1_fx8010_code)
+#define SNDRV_EMU10K1_IOCTL_TRAM_SETUP	_IOW ('H', 0x20, int)
+#define SNDRV_EMU10K1_IOCTL_TRAM_POKE	_IOW ('H', 0x21, struct snd_emu10k1_fx8010_tram)
+#define SNDRV_EMU10K1_IOCTL_TRAM_PEEK	_IOWR('H', 0x22, struct snd_emu10k1_fx8010_tram)
+#define SNDRV_EMU10K1_IOCTL_PCM_POKE	_IOW ('H', 0x30, struct snd_emu10k1_fx8010_pcm_rec)
+#define SNDRV_EMU10K1_IOCTL_PCM_PEEK	_IOWR('H', 0x31, struct snd_emu10k1_fx8010_pcm_rec)
+#define SNDRV_EMU10K1_IOCTL_PVERSION	_IOR ('H', 0x40, int)
+#define SNDRV_EMU10K1_IOCTL_STOP	_IO  ('H', 0x80)
+#define SNDRV_EMU10K1_IOCTL_CONTINUE	_IO  ('H', 0x81)
+#define SNDRV_EMU10K1_IOCTL_ZERO_TRAM_COUNTER _IO ('H', 0x82)
+#define SNDRV_EMU10K1_IOCTL_SINGLE_STEP	_IOW ('H', 0x83, int)
+#define SNDRV_EMU10K1_IOCTL_DBG_READ	_IOR ('H', 0x84, int)
+
+/* typedefs for compatibility to user-space */
+typedef struct snd_emu10k1_fx8010_info emu10k1_fx8010_info_t;
+typedef struct snd_emu10k1_fx8010_control_gpr emu10k1_fx8010_control_gpr_t;
+typedef struct snd_emu10k1_fx8010_code emu10k1_fx8010_code_t;
+typedef struct snd_emu10k1_fx8010_tram emu10k1_fx8010_tram_t;
+typedef struct snd_emu10k1_fx8010_pcm_rec emu10k1_fx8010_pcm_t;
+
+#endif /* _UAPI__SOUND_EMU10K1_H */
diff --git a/include/sound/hdsp.h b/include/uapi/sound/hdsp.h
similarity index 100%
rename from include/sound/hdsp.h
rename to include/uapi/sound/hdsp.h
diff --git a/include/sound/hdspm.h b/include/uapi/sound/hdspm.h
similarity index 100%
rename from include/sound/hdspm.h
rename to include/uapi/sound/hdspm.h
diff --git a/include/uapi/sound/sb16_csp.h b/include/uapi/sound/sb16_csp.h
new file mode 100644
index 0000000..3b96907
--- /dev/null
+++ b/include/uapi/sound/sb16_csp.h
@@ -0,0 +1,122 @@
+/*
+ *  Copyright (c) 1999 by Uros Bizjak <uros@kss-loka.si>
+ *                        Takashi Iwai <tiwai@suse.de>
+ *
+ *  SB16ASP/AWE32 CSP control
+ *
+ *   This program is free software; you can redistribute it and/or modify 
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ *
+ */
+#ifndef _UAPI__SOUND_SB16_CSP_H
+#define _UAPI__SOUND_SB16_CSP_H
+
+
+/* CSP modes */
+#define SNDRV_SB_CSP_MODE_NONE		0x00
+#define SNDRV_SB_CSP_MODE_DSP_READ	0x01	/* Record from DSP */
+#define SNDRV_SB_CSP_MODE_DSP_WRITE	0x02	/* Play to DSP */
+#define SNDRV_SB_CSP_MODE_QSOUND		0x04	/* QSound */
+
+/* CSP load flags */
+#define SNDRV_SB_CSP_LOAD_FROMUSER	0x01
+#define SNDRV_SB_CSP_LOAD_INITBLOCK	0x02
+
+/* CSP sample width */
+#define SNDRV_SB_CSP_SAMPLE_8BIT		0x01
+#define SNDRV_SB_CSP_SAMPLE_16BIT		0x02
+
+/* CSP channels */
+#define SNDRV_SB_CSP_MONO			0x01
+#define SNDRV_SB_CSP_STEREO		0x02
+
+/* CSP rates */
+#define SNDRV_SB_CSP_RATE_8000		0x01
+#define SNDRV_SB_CSP_RATE_11025		0x02
+#define SNDRV_SB_CSP_RATE_22050		0x04
+#define SNDRV_SB_CSP_RATE_44100		0x08
+#define SNDRV_SB_CSP_RATE_ALL		0x0f
+
+/* CSP running state */
+#define SNDRV_SB_CSP_ST_IDLE		0x00
+#define SNDRV_SB_CSP_ST_LOADED		0x01
+#define SNDRV_SB_CSP_ST_RUNNING		0x02
+#define SNDRV_SB_CSP_ST_PAUSED		0x04
+#define SNDRV_SB_CSP_ST_AUTO		0x08
+#define SNDRV_SB_CSP_ST_QSOUND		0x10
+
+/* maximum QSound value (180 degrees right) */
+#define SNDRV_SB_CSP_QSOUND_MAX_RIGHT	0x20
+
+/* maximum microcode RIFF file size */
+#define SNDRV_SB_CSP_MAX_MICROCODE_FILE_SIZE	0x3000
+
+/* microcode header */
+struct snd_sb_csp_mc_header {
+	char codec_name[16];		/* id name of codec */
+	unsigned short func_req;	/* requested function */
+};
+
+/* microcode to be loaded */
+struct snd_sb_csp_microcode {
+	struct snd_sb_csp_mc_header info;
+	unsigned char data[SNDRV_SB_CSP_MAX_MICROCODE_FILE_SIZE];
+};
+
+/* start CSP with sample_width in mono/stereo */
+struct snd_sb_csp_start {
+	int sample_width;	/* sample width, look above */
+	int channels;		/* channels, look above */
+};
+
+/* CSP information */
+struct snd_sb_csp_info {
+	char codec_name[16];		/* id name of codec */
+	unsigned short func_nr;		/* function number */
+	unsigned int acc_format;	/* accepted PCM formats */
+	unsigned short acc_channels;	/* accepted channels */
+	unsigned short acc_width;	/* accepted sample width */
+	unsigned short acc_rates;	/* accepted sample rates */
+	unsigned short csp_mode;	/* CSP mode, see above */
+	unsigned short run_channels;	/* current channels  */
+	unsigned short run_width;	/* current sample width */
+	unsigned short version;		/* version id: 0x10 - 0x1f */
+	unsigned short state;		/* state bits */
+};
+
+/* HWDEP controls */
+/* get CSP information */
+#define SNDRV_SB_CSP_IOCTL_INFO		_IOR('H', 0x10, struct snd_sb_csp_info)
+/* load microcode to CSP */
+/* NOTE: struct snd_sb_csp_microcode overflows the max size (13 bits)
+ * defined for some architectures like MIPS, and it leads to build errors.
+ * (x86 and co have 14-bit size, thus it's valid, though.)
+ * As a workaround for skipping the size-limit check, here we don't use the
+ * normal _IOW() macro but _IOC() with the manual argument.
+ */
+#define SNDRV_SB_CSP_IOCTL_LOAD_CODE	\
+	_IOC(_IOC_WRITE, 'H', 0x11, sizeof(struct snd_sb_csp_microcode))
+/* unload microcode from CSP */
+#define SNDRV_SB_CSP_IOCTL_UNLOAD_CODE	_IO('H', 0x12)
+/* start CSP */
+#define SNDRV_SB_CSP_IOCTL_START		_IOW('H', 0x13, struct snd_sb_csp_start)
+/* stop CSP */
+#define SNDRV_SB_CSP_IOCTL_STOP		_IO('H', 0x14)
+/* pause CSP and DMA transfer */
+#define SNDRV_SB_CSP_IOCTL_PAUSE		_IO('H', 0x15)
+/* restart CSP and DMA transfer */
+#define SNDRV_SB_CSP_IOCTL_RESTART	_IO('H', 0x16)
+
+
+#endif /* _UAPI__SOUND_SB16_CSP_H */
diff --git a/include/sound/sfnt_info.h b/include/uapi/sound/sfnt_info.h
similarity index 100%
rename from include/sound/sfnt_info.h
rename to include/uapi/sound/sfnt_info.h
diff --git a/init/main.c b/init/main.c
index e33e09d..63ae904 100644
--- a/init/main.c
+++ b/init/main.c
@@ -857,7 +857,7 @@
 	/*
 	 * init can allocate pages on any node
 	 */
-	set_mems_allowed(node_states[N_HIGH_MEMORY]);
+	set_mems_allowed(node_states[N_MEMORY]);
 	/*
 	 * init can run on any cpu.
 	 */
diff --git a/kernel/cpuset.c b/kernel/cpuset.c
index b017887..7bb63ee 100644
--- a/kernel/cpuset.c
+++ b/kernel/cpuset.c
@@ -302,10 +302,10 @@
  * are online, with memory.  If none are online with memory, walk
  * up the cpuset hierarchy until we find one that does have some
  * online mems.  If we get all the way to the top and still haven't
- * found any online mems, return node_states[N_HIGH_MEMORY].
+ * found any online mems, return node_states[N_MEMORY].
  *
  * One way or another, we guarantee to return some non-empty subset
- * of node_states[N_HIGH_MEMORY].
+ * of node_states[N_MEMORY].
  *
  * Call with callback_mutex held.
  */
@@ -313,14 +313,14 @@
 static void guarantee_online_mems(const struct cpuset *cs, nodemask_t *pmask)
 {
 	while (cs && !nodes_intersects(cs->mems_allowed,
-					node_states[N_HIGH_MEMORY]))
+					node_states[N_MEMORY]))
 		cs = cs->parent;
 	if (cs)
 		nodes_and(*pmask, cs->mems_allowed,
-					node_states[N_HIGH_MEMORY]);
+					node_states[N_MEMORY]);
 	else
-		*pmask = node_states[N_HIGH_MEMORY];
-	BUG_ON(!nodes_intersects(*pmask, node_states[N_HIGH_MEMORY]));
+		*pmask = node_states[N_MEMORY];
+	BUG_ON(!nodes_intersects(*pmask, node_states[N_MEMORY]));
 }
 
 /*
@@ -1100,7 +1100,7 @@
 		return -ENOMEM;
 
 	/*
-	 * top_cpuset.mems_allowed tracks node_stats[N_HIGH_MEMORY];
+	 * top_cpuset.mems_allowed tracks node_stats[N_MEMORY];
 	 * it's read-only
 	 */
 	if (cs == &top_cpuset) {
@@ -1122,7 +1122,7 @@
 			goto done;
 
 		if (!nodes_subset(trialcs->mems_allowed,
-				node_states[N_HIGH_MEMORY])) {
+				node_states[N_MEMORY])) {
 			retval =  -EINVAL;
 			goto done;
 		}
@@ -2026,7 +2026,7 @@
  * before dropping down to the next.  It always processes a node before
  * any of its children.
  *
- * In the case of memory hot-unplug, it will remove nodes from N_HIGH_MEMORY
+ * In the case of memory hot-unplug, it will remove nodes from N_MEMORY
  * if all present pages from a node are offlined.
  */
 static void
@@ -2065,7 +2065,7 @@
 
 			/* Continue past cpusets with all mems online */
 			if (nodes_subset(cp->mems_allowed,
-					node_states[N_HIGH_MEMORY]))
+					node_states[N_MEMORY]))
 				continue;
 
 			oldmems = cp->mems_allowed;
@@ -2073,7 +2073,7 @@
 			/* Remove offline mems from this cpuset. */
 			mutex_lock(&callback_mutex);
 			nodes_and(cp->mems_allowed, cp->mems_allowed,
-						node_states[N_HIGH_MEMORY]);
+						node_states[N_MEMORY]);
 			mutex_unlock(&callback_mutex);
 
 			/* Move tasks from the empty cpuset to a parent */
@@ -2126,8 +2126,8 @@
 
 #ifdef CONFIG_MEMORY_HOTPLUG
 /*
- * Keep top_cpuset.mems_allowed tracking node_states[N_HIGH_MEMORY].
- * Call this routine anytime after node_states[N_HIGH_MEMORY] changes.
+ * Keep top_cpuset.mems_allowed tracking node_states[N_MEMORY].
+ * Call this routine anytime after node_states[N_MEMORY] changes.
  * See cpuset_update_active_cpus() for CPU hotplug handling.
  */
 static int cpuset_track_online_nodes(struct notifier_block *self,
@@ -2140,7 +2140,7 @@
 	case MEM_ONLINE:
 		oldmems = top_cpuset.mems_allowed;
 		mutex_lock(&callback_mutex);
-		top_cpuset.mems_allowed = node_states[N_HIGH_MEMORY];
+		top_cpuset.mems_allowed = node_states[N_MEMORY];
 		mutex_unlock(&callback_mutex);
 		update_tasks_nodemask(&top_cpuset, &oldmems, NULL);
 		break;
@@ -2169,7 +2169,7 @@
 void __init cpuset_init_smp(void)
 {
 	cpumask_copy(top_cpuset.cpus_allowed, cpu_active_mask);
-	top_cpuset.mems_allowed = node_states[N_HIGH_MEMORY];
+	top_cpuset.mems_allowed = node_states[N_MEMORY];
 
 	hotplug_memory_notifier(cpuset_track_online_nodes, 10);
 
@@ -2237,7 +2237,7 @@
  *
  * Description: Returns the nodemask_t mems_allowed of the cpuset
  * attached to the specified @tsk.  Guaranteed to return some non-empty
- * subset of node_states[N_HIGH_MEMORY], even if this means going outside the
+ * subset of node_states[N_MEMORY], even if this means going outside the
  * tasks cpuset.
  **/
 
diff --git a/kernel/kthread.c b/kernel/kthread.c
index 29fb60c..691dc2e 100644
--- a/kernel/kthread.c
+++ b/kernel/kthread.c
@@ -428,7 +428,7 @@
 	set_task_comm(tsk, "kthreadd");
 	ignore_signals(tsk);
 	set_cpus_allowed_ptr(tsk, cpu_all_mask);
-	set_mems_allowed(node_states[N_HIGH_MEMORY]);
+	set_mems_allowed(node_states[N_MEMORY]);
 
 	current->flags |= PF_NOFREEZE;
 
diff --git a/kernel/pid.c b/kernel/pid.c
index aebd4f5..fd996c1 100644
--- a/kernel/pid.c
+++ b/kernel/pid.c
@@ -1,8 +1,8 @@
 /*
  * Generic pidhash and scalable, time-bounded PID allocator
  *
- * (C) 2002-2003 William Irwin, IBM
- * (C) 2004 William Irwin, Oracle
+ * (C) 2002-2003 Nadia Yvette Chambers, IBM
+ * (C) 2004 Nadia Yvette Chambers, Oracle
  * (C) 2002-2004 Ingo Molnar, Red Hat
  *
  * pid-structures are backing objects for tasks sharing a given ID to chain
diff --git a/kernel/profile.c b/kernel/profile.c
index 76b8e77..1f39181 100644
--- a/kernel/profile.c
+++ b/kernel/profile.c
@@ -8,9 +8,10 @@
  *  Scheduler profiling support, Arjan van de Ven and Ingo Molnar,
  *	Red Hat, July 2004
  *  Consolidation of architecture support code for profiling,
- *	William Irwin, Oracle, July 2004
+ *	Nadia Yvette Chambers, Oracle, July 2004
  *  Amortized hit count accounting via per-cpu open-addressed hashtables
- *	to resolve timer interrupt livelocks, William Irwin, Oracle, 2004
+ *	to resolve timer interrupt livelocks, Nadia Yvette Chambers,
+ *	Oracle, 2004
  */
 
 #include <linux/export.h>
@@ -256,7 +257,7 @@
  * pagetable hash functions, but uses a full hashtable full of finite
  * collision chains, not just pairs of them.
  *
- * -- wli
+ * -- nyc
  */
 static void __profile_flip_buffers(void *unused)
 {
diff --git a/kernel/res_counter.c b/kernel/res_counter.c
index ad581aa..3920d59 100644
--- a/kernel/res_counter.c
+++ b/kernel/res_counter.c
@@ -192,25 +192,3 @@
 	*res = PAGE_ALIGN(*res);
 	return 0;
 }
-
-int res_counter_write(struct res_counter *counter, int member,
-		      const char *buf, write_strategy_fn write_strategy)
-{
-	char *end;
-	unsigned long flags;
-	unsigned long long tmp, *val;
-
-	if (write_strategy) {
-		if (write_strategy(buf, &tmp))
-			return -EINVAL;
-	} else {
-		tmp = simple_strtoull(buf, &end, 10);
-		if (*end != '\0')
-			return -EINVAL;
-	}
-	spin_lock_irqsave(&counter->lock, flags);
-	val = res_counter_member(counter, member);
-	*val = tmp;
-	spin_unlock_irqrestore(&counter->lock, flags);
-	return 0;
-}
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
index 7693aaf..afd092d 100644
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -10,7 +10,7 @@
  * Based on code in the latency_tracer, that is:
  *
  *  Copyright (C) 2004-2006 Ingo Molnar
- *  Copyright (C) 2004 William Lee Irwin III
+ *  Copyright (C) 2004 Nadia Yvette Chambers
  */
 
 #include <linux/stop_machine.h>
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index b69cc38..61e081b 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -9,7 +9,7 @@
  *
  * Based on code from the latency_tracer, that is:
  *  Copyright (C) 2004-2006 Ingo Molnar
- *  Copyright (C) 2004 William Lee Irwin III
+ *  Copyright (C) 2004 Nadia Yvette Chambers
  */
 #include <linux/ring_buffer.h>
 #include <generated/utsrelease.h>
diff --git a/kernel/trace/trace_functions.c b/kernel/trace/trace_functions.c
index bb227e3..8e3ad80 100644
--- a/kernel/trace/trace_functions.c
+++ b/kernel/trace/trace_functions.c
@@ -7,7 +7,7 @@
  * Based on code from the latency_tracer, that is:
  *
  *  Copyright (C) 2004-2006 Ingo Molnar
- *  Copyright (C) 2004 William Lee Irwin III
+ *  Copyright (C) 2004 Nadia Yvette Chambers
  */
 #include <linux/ring_buffer.h>
 #include <linux/debugfs.h>
diff --git a/kernel/trace/trace_irqsoff.c b/kernel/trace/trace_irqsoff.c
index 5ffce7b..713a2ca 100644
--- a/kernel/trace/trace_irqsoff.c
+++ b/kernel/trace/trace_irqsoff.c
@@ -7,7 +7,7 @@
  * From code in the latency_tracer, that is:
  *
  *  Copyright (C) 2004-2006 Ingo Molnar
- *  Copyright (C) 2004 William Lee Irwin III
+ *  Copyright (C) 2004 Nadia Yvette Chambers
  */
 #include <linux/kallsyms.h>
 #include <linux/debugfs.h>
diff --git a/kernel/trace/trace_sched_wakeup.c b/kernel/trace/trace_sched_wakeup.c
index bc64fc1..9fe45fc 100644
--- a/kernel/trace/trace_sched_wakeup.c
+++ b/kernel/trace/trace_sched_wakeup.c
@@ -7,7 +7,7 @@
  * Based on code from the latency_tracer, that is:
  *
  *  Copyright (C) 2004-2006 Ingo Molnar
- *  Copyright (C) 2004 William Lee Irwin III
+ *  Copyright (C) 2004 Nadia Yvette Chambers
  */
 #include <linux/module.h>
 #include <linux/fs.h>
diff --git a/kernel/wait.c b/kernel/wait.c
index 7fdd9ea..6698e0c 100644
--- a/kernel/wait.c
+++ b/kernel/wait.c
@@ -1,7 +1,7 @@
 /*
  * Generic waiting primitives.
  *
- * (C) 2004 William Irwin, Oracle
+ * (C) 2004 Nadia Yvette Chambers, Oracle
  */
 #include <linux/init.h>
 #include <linux/export.h>
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 41faf0b..e458782 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -1115,7 +1115,7 @@
 	depends on DEBUG_KERNEL
 	select DEBUG_FS
 	help
-	  This option provides the ability to inject artifical errors to
+	  This option provides the ability to inject artificial errors to
 	  specified notifier chain callbacks. It is useful to test the error
 	  handling of notifier call chain failures.
 
@@ -1126,7 +1126,7 @@
 	depends on HOTPLUG_CPU && NOTIFIER_ERROR_INJECTION
 	help
 	  This option provides a kernel module that can be used to test
-	  the error handling of the cpu notifiers by injecting artifical
+	  the error handling of the cpu notifiers by injecting artificial
 	  errors to CPU notifier chain callbacks.  It is controlled through
 	  debugfs interface under /sys/kernel/debug/notifier-error-inject/cpu
 
@@ -1150,7 +1150,7 @@
 	depends on PM && NOTIFIER_ERROR_INJECTION
 	default m if PM_DEBUG
 	help
-	  This option provides the ability to inject artifical errors to
+	  This option provides the ability to inject artificial errors to
 	  PM notifier chain callbacks.  It is controlled through debugfs
 	  interface /sys/kernel/debug/notifier-error-inject/pm
 
@@ -1173,7 +1173,7 @@
 	tristate "Memory hotplug notifier error injection module"
 	depends on MEMORY_HOTPLUG_SPARSE && NOTIFIER_ERROR_INJECTION
 	help
-	  This option provides the ability to inject artifical errors to
+	  This option provides the ability to inject artificial errors to
 	  memory hotplug notifier chain callbacks.  It is controlled through
 	  debugfs interface under /sys/kernel/debug/notifier-error-inject/memory
 
@@ -1196,7 +1196,7 @@
 	tristate "pSeries reconfig notifier error injection module"
 	depends on PPC_PSERIES && NOTIFIER_ERROR_INJECTION
 	help
-	  This option provides the ability to inject artifical errors to
+	  This option provides the ability to inject artificial errors to
 	  pSeries reconfig notifier chain callbacks.  It is controlled
 	  through debugfs interface under
 	  /sys/kernel/debug/notifier-error-inject/pSeries-reconfig/
diff --git a/lib/bitmap.c b/lib/bitmap.c
index 06fdfa1..06f7e4f 100644
--- a/lib/bitmap.c
+++ b/lib/bitmap.c
@@ -353,7 +353,7 @@
 EXPORT_SYMBOL(bitmap_find_next_zero_area);
 
 /*
- * Bitmap printing & parsing functions: first version by Bill Irwin,
+ * Bitmap printing & parsing functions: first version by Nadia Yvette Chambers,
  * second version by Paul Jackson, third by Joe Korty.
  */
 
diff --git a/mm/Kconfig b/mm/Kconfig
index e6651c5..71259e0 100644
--- a/mm/Kconfig
+++ b/mm/Kconfig
@@ -143,6 +143,14 @@
 config MEMORY_ISOLATION
 	boolean
 
+config MOVABLE_NODE
+	boolean "Enable to assign a node which has only movable memory"
+	depends on HAVE_MEMBLOCK
+	depends on NO_BOOTMEM
+	depends on X86_64
+	depends on NUMA
+	depends on BROKEN
+
 # eventually, we can have this option just 'select SPARSEMEM'
 config MEMORY_HOTPLUG
 	bool "Allow for memory hot-add"
diff --git a/mm/bootmem.c b/mm/bootmem.c
index ecc4595..1324cd7 100644
--- a/mm/bootmem.c
+++ b/mm/bootmem.c
@@ -229,6 +229,22 @@
 	return count;
 }
 
+static void reset_node_lowmem_managed_pages(pg_data_t *pgdat)
+{
+	struct zone *z;
+
+	/*
+	 * In free_area_init_core(), highmem zone's managed_pages is set to
+	 * present_pages, and bootmem allocator doesn't allocate from highmem
+	 * zones. So there's no need to recalculate managed_pages because all
+	 * highmem pages will be managed by the buddy system. Here highmem
+	 * zone also includes highmem movable zone.
+	 */
+	for (z = pgdat->node_zones; z < pgdat->node_zones + MAX_NR_ZONES; z++)
+		if (!is_highmem(z))
+			z->managed_pages = 0;
+}
+
 /**
  * free_all_bootmem_node - release a node's free pages to the buddy allocator
  * @pgdat: node to be released
@@ -238,6 +254,7 @@
 unsigned long __init free_all_bootmem_node(pg_data_t *pgdat)
 {
 	register_page_bootmem_info_node(pgdat);
+	reset_node_lowmem_managed_pages(pgdat);
 	return free_all_bootmem_core(pgdat->bdata);
 }
 
@@ -250,6 +267,10 @@
 {
 	unsigned long total_pages = 0;
 	bootmem_data_t *bdata;
+	struct pglist_data *pgdat;
+
+	for_each_online_pgdat(pgdat)
+		reset_node_lowmem_managed_pages(pgdat);
 
 	list_for_each_entry(bdata, &bdata_list, list)
 		total_pages += free_all_bootmem_core(bdata);
@@ -439,12 +460,6 @@
 	return mark_bootmem(start, end, 1, flags);
 }
 
-int __weak __init reserve_bootmem_generic(unsigned long phys, unsigned long len,
-				   int flags)
-{
-	return reserve_bootmem(phys, len, flags);
-}
-
 static unsigned long __init align_idx(struct bootmem_data *bdata,
 				      unsigned long idx, unsigned long step)
 {
@@ -575,27 +590,6 @@
 	return NULL;
 }
 
-static void * __init alloc_arch_preferred_bootmem(bootmem_data_t *bdata,
-					unsigned long size, unsigned long align,
-					unsigned long goal, unsigned long limit)
-{
-	if (WARN_ON_ONCE(slab_is_available()))
-		return kzalloc(size, GFP_NOWAIT);
-
-#ifdef CONFIG_HAVE_ARCH_BOOTMEM
-	{
-		bootmem_data_t *p_bdata;
-
-		p_bdata = bootmem_arch_preferred_node(bdata, size, align,
-							goal, limit);
-		if (p_bdata)
-			return alloc_bootmem_bdata(p_bdata, size, align,
-							goal, limit);
-	}
-#endif
-	return NULL;
-}
-
 static void * __init alloc_bootmem_core(unsigned long size,
 					unsigned long align,
 					unsigned long goal,
@@ -604,9 +598,8 @@
 	bootmem_data_t *bdata;
 	void *region;
 
-	region = alloc_arch_preferred_bootmem(NULL, size, align, goal, limit);
-	if (region)
-		return region;
+	if (WARN_ON_ONCE(slab_is_available()))
+		return kzalloc(size, GFP_NOWAIT);
 
 	list_for_each_entry(bdata, &bdata_list, list) {
 		if (goal && bdata->node_low_pfn <= PFN_DOWN(goal))
@@ -704,11 +697,9 @@
 {
 	void *ptr;
 
+	if (WARN_ON_ONCE(slab_is_available()))
+		return kzalloc(size, GFP_NOWAIT);
 again:
-	ptr = alloc_arch_preferred_bootmem(pgdat->bdata, size,
-					   align, goal, limit);
-	if (ptr)
-		return ptr;
 
 	/* do not panic in alloc_bootmem_bdata() */
 	if (limit && goal + size > limit)
diff --git a/mm/compaction.c b/mm/compaction.c
index d24dd2d..1297912 100644
--- a/mm/compaction.c
+++ b/mm/compaction.c
@@ -215,60 +215,6 @@
 	return false;
 }
 
-static void compact_capture_page(struct compact_control *cc)
-{
-	unsigned long flags;
-	int mtype, mtype_low, mtype_high;
-
-	if (!cc->page || *cc->page)
-		return;
-
-	/*
-	 * For MIGRATE_MOVABLE allocations we capture a suitable page ASAP
-	 * regardless of the migratetype of the freelist is is captured from.
-	 * This is fine because the order for a high-order MIGRATE_MOVABLE
-	 * allocation is typically at least a pageblock size and overall
-	 * fragmentation is not impaired. Other allocation types must
-	 * capture pages from their own migratelist because otherwise they
-	 * could pollute other pageblocks like MIGRATE_MOVABLE with
-	 * difficult to move pages and making fragmentation worse overall.
-	 */
-	if (cc->migratetype == MIGRATE_MOVABLE) {
-		mtype_low = 0;
-		mtype_high = MIGRATE_PCPTYPES;
-	} else {
-		mtype_low = cc->migratetype;
-		mtype_high = cc->migratetype + 1;
-	}
-
-	/* Speculatively examine the free lists without zone lock */
-	for (mtype = mtype_low; mtype < mtype_high; mtype++) {
-		int order;
-		for (order = cc->order; order < MAX_ORDER; order++) {
-			struct page *page;
-			struct free_area *area;
-			area = &(cc->zone->free_area[order]);
-			if (list_empty(&area->free_list[mtype]))
-				continue;
-
-			/* Take the lock and attempt capture of the page */
-			if (!compact_trylock_irqsave(&cc->zone->lock, &flags, cc))
-				return;
-			if (!list_empty(&area->free_list[mtype])) {
-				page = list_entry(area->free_list[mtype].next,
-							struct page, lru);
-				if (capture_free_page(page, cc->order, mtype)) {
-					spin_unlock_irqrestore(&cc->zone->lock,
-									flags);
-					*cc->page = page;
-					return;
-				}
-			}
-			spin_unlock_irqrestore(&cc->zone->lock, flags);
-		}
-	}
-}
-
 /*
  * Isolate free pages onto a private freelist. Caller must hold zone->lock.
  * If @strict is true, will abort returning 0 on any invalid PFNs or non-free
@@ -953,6 +899,60 @@
 	return COMPACT_CONTINUE;
 }
 
+static void compact_capture_page(struct compact_control *cc)
+{
+	unsigned long flags;
+	int mtype, mtype_low, mtype_high;
+
+	if (!cc->page || *cc->page)
+		return;
+
+	/*
+	 * For MIGRATE_MOVABLE allocations we capture a suitable page ASAP
+	 * regardless of the migratetype of the freelist is is captured from.
+	 * This is fine because the order for a high-order MIGRATE_MOVABLE
+	 * allocation is typically at least a pageblock size and overall
+	 * fragmentation is not impaired. Other allocation types must
+	 * capture pages from their own migratelist because otherwise they
+	 * could pollute other pageblocks like MIGRATE_MOVABLE with
+	 * difficult to move pages and making fragmentation worse overall.
+	 */
+	if (cc->migratetype == MIGRATE_MOVABLE) {
+		mtype_low = 0;
+		mtype_high = MIGRATE_PCPTYPES;
+	} else {
+		mtype_low = cc->migratetype;
+		mtype_high = cc->migratetype + 1;
+	}
+
+	/* Speculatively examine the free lists without zone lock */
+	for (mtype = mtype_low; mtype < mtype_high; mtype++) {
+		int order;
+		for (order = cc->order; order < MAX_ORDER; order++) {
+			struct page *page;
+			struct free_area *area;
+			area = &(cc->zone->free_area[order]);
+			if (list_empty(&area->free_list[mtype]))
+				continue;
+
+			/* Take the lock and attempt capture of the page */
+			if (!compact_trylock_irqsave(&cc->zone->lock, &flags, cc))
+				return;
+			if (!list_empty(&area->free_list[mtype])) {
+				page = list_entry(area->free_list[mtype].next,
+							struct page, lru);
+				if (capture_free_page(page, cc->order, mtype)) {
+					spin_unlock_irqrestore(&cc->zone->lock,
+									flags);
+					*cc->page = page;
+					return;
+				}
+			}
+			spin_unlock_irqrestore(&cc->zone->lock, flags);
+		}
+	}
+}
+
 static int compact_zone(struct zone *zone, struct compact_control *cc)
 {
 	int ret;
diff --git a/mm/huge_memory.c b/mm/huge_memory.c
index 5f902e2..827d9c8 100644
--- a/mm/huge_memory.c
+++ b/mm/huge_memory.c
@@ -12,12 +12,14 @@
 #include <linux/mmu_notifier.h>
 #include <linux/rmap.h>
 #include <linux/swap.h>
+#include <linux/shrinker.h>
 #include <linux/mm_inline.h>
 #include <linux/kthread.h>
 #include <linux/khugepaged.h>
 #include <linux/freezer.h>
 #include <linux/mman.h>
 #include <linux/pagemap.h>
+
 #include <asm/tlb.h>
 #include <asm/pgalloc.h>
 #include "internal.h"
@@ -37,7 +39,8 @@
 	(1<<TRANSPARENT_HUGEPAGE_REQ_MADV_FLAG)|
 #endif
 	(1<<TRANSPARENT_HUGEPAGE_DEFRAG_FLAG)|
-	(1<<TRANSPARENT_HUGEPAGE_DEFRAG_KHUGEPAGED_FLAG);
+	(1<<TRANSPARENT_HUGEPAGE_DEFRAG_KHUGEPAGED_FLAG)|
+	(1<<TRANSPARENT_HUGEPAGE_USE_ZERO_PAGE_FLAG);
 
 /* default scan 8*512 pte (or vmas) every 30 second */
 static unsigned int khugepaged_pages_to_scan __read_mostly = HPAGE_PMD_NR*8;
@@ -159,6 +162,77 @@
 	return err;
 }
 
+static atomic_t huge_zero_refcount;
+static unsigned long huge_zero_pfn __read_mostly;
+
+static inline bool is_huge_zero_pfn(unsigned long pfn)
+{
+	unsigned long zero_pfn = ACCESS_ONCE(huge_zero_pfn);
+	return zero_pfn && pfn == zero_pfn;
+}
+
+static inline bool is_huge_zero_pmd(pmd_t pmd)
+{
+	return is_huge_zero_pfn(pmd_pfn(pmd));
+}
+
+static unsigned long get_huge_zero_page(void)
+{
+	struct page *zero_page;
+retry:
+	if (likely(atomic_inc_not_zero(&huge_zero_refcount)))
+		return ACCESS_ONCE(huge_zero_pfn);
+
+	zero_page = alloc_pages((GFP_TRANSHUGE | __GFP_ZERO) & ~__GFP_MOVABLE,
+			HPAGE_PMD_ORDER);
+	if (!zero_page) {
+		count_vm_event(THP_ZERO_PAGE_ALLOC_FAILED);
+		return 0;
+	}
+	count_vm_event(THP_ZERO_PAGE_ALLOC);
+	preempt_disable();
+	if (cmpxchg(&huge_zero_pfn, 0, page_to_pfn(zero_page))) {
+		preempt_enable();
+		__free_page(zero_page);
+		goto retry;
+	}
+
+	/* We take additional reference here. It will be put back by shrinker */
+	atomic_set(&huge_zero_refcount, 2);
+	preempt_enable();
+	return ACCESS_ONCE(huge_zero_pfn);
+}
+
+static void put_huge_zero_page(void)
+{
+	/*
+	 * Counter should never go to zero here. Only shrinker can put
+	 * last reference.
+	 */
+	BUG_ON(atomic_dec_and_test(&huge_zero_refcount));
+}
+
+static int shrink_huge_zero_page(struct shrinker *shrink,
+		struct shrink_control *sc)
+{
+	if (!sc->nr_to_scan)
+		/* we can free zero page only if last reference remains */
+		return atomic_read(&huge_zero_refcount) == 1 ? HPAGE_PMD_NR : 0;
+
+	if (atomic_cmpxchg(&huge_zero_refcount, 1, 0) == 1) {
+		unsigned long zero_pfn = xchg(&huge_zero_pfn, 0);
+		BUG_ON(zero_pfn == 0);
+		__free_page(__pfn_to_page(zero_pfn));
+	}
+
+	return 0;
+}
+
+static struct shrinker huge_zero_page_shrinker = {
+	.shrink = shrink_huge_zero_page,
+	.seeks = DEFAULT_SEEKS,
+};
+
 #ifdef CONFIG_SYSFS
 
 static ssize_t double_flag_show(struct kobject *kobj,
@@ -284,6 +358,20 @@
 static struct kobj_attribute defrag_attr =
 	__ATTR(defrag, 0644, defrag_show, defrag_store);
 
+static ssize_t use_zero_page_show(struct kobject *kobj,
+		struct kobj_attribute *attr, char *buf)
+{
+	return single_flag_show(kobj, attr, buf,
+				TRANSPARENT_HUGEPAGE_USE_ZERO_PAGE_FLAG);
+}
+static ssize_t use_zero_page_store(struct kobject *kobj,
+		struct kobj_attribute *attr, const char *buf, size_t count)
+{
+	return single_flag_store(kobj, attr, buf, count,
+				 TRANSPARENT_HUGEPAGE_USE_ZERO_PAGE_FLAG);
+}
+static struct kobj_attribute use_zero_page_attr =
+	__ATTR(use_zero_page, 0644, use_zero_page_show, use_zero_page_store);
 #ifdef CONFIG_DEBUG_VM
 static ssize_t debug_cow_show(struct kobject *kobj,
 				struct kobj_attribute *attr, char *buf)
@@ -305,6 +393,7 @@
 static struct attribute *hugepage_attr[] = {
 	&enabled_attr.attr,
 	&defrag_attr.attr,
+	&use_zero_page_attr.attr,
 #ifdef CONFIG_DEBUG_VM
 	&debug_cow_attr.attr,
 #endif
@@ -550,6 +639,8 @@
 		goto out;
 	}
 
+	register_shrinker(&huge_zero_page_shrinker);
+
 	/*
 	 * By default disable transparent hugepages on smaller systems,
 	 * where the extra memory used could hurt more than TLB overhead
@@ -678,6 +769,22 @@
 }
 #endif
 
+static bool set_huge_zero_page(pgtable_t pgtable, struct mm_struct *mm,
+		struct vm_area_struct *vma, unsigned long haddr, pmd_t *pmd,
+		unsigned long zero_pfn)
+{
+	pmd_t entry;
+	if (!pmd_none(*pmd))
+		return false;
+	entry = pfn_pmd(zero_pfn, vma->vm_page_prot);
+	entry = pmd_wrprotect(entry);
+	entry = pmd_mkhuge(entry);
+	set_pmd_at(mm, haddr, pmd, entry);
+	pgtable_trans_huge_deposit(mm, pgtable);
+	mm->nr_ptes++;
+	return true;
+}
+
 int do_huge_pmd_anonymous_page(struct mm_struct *mm, struct vm_area_struct *vma,
 			       unsigned long address, pmd_t *pmd,
 			       unsigned int flags)
@@ -691,6 +798,30 @@
 			return VM_FAULT_OOM;
 		if (unlikely(khugepaged_enter(vma)))
 			return VM_FAULT_OOM;
+		if (!(flags & FAULT_FLAG_WRITE) &&
+				transparent_hugepage_use_zero_page()) {
+			pgtable_t pgtable;
+			unsigned long zero_pfn;
+			bool set;
+			pgtable = pte_alloc_one(mm, haddr);
+			if (unlikely(!pgtable))
+				return VM_FAULT_OOM;
+			zero_pfn = get_huge_zero_page();
+			if (unlikely(!zero_pfn)) {
+				pte_free(mm, pgtable);
+				count_vm_event(THP_FAULT_FALLBACK);
+				goto out;
+			}
+			spin_lock(&mm->page_table_lock);
+			set = set_huge_zero_page(pgtable, mm, vma, haddr, pmd,
+					zero_pfn);
+			spin_unlock(&mm->page_table_lock);
+			if (!set) {
+				pte_free(mm, pgtable);
+				put_huge_zero_page();
+			}
+			return 0;
+		}
 		page = alloc_hugepage_vma(transparent_hugepage_defrag(vma),
 					  vma, haddr, numa_node_id(), 0);
 		if (unlikely(!page)) {
@@ -755,6 +886,26 @@
 		pte_free(dst_mm, pgtable);
 		goto out_unlock;
 	}
+	/*
+	 * mm->page_table_lock is enough to be sure that huge zero pmd is not
+	 * under splitting since we don't split the page itself, only pmd to
+	 * a page table.
+	 */
+	if (is_huge_zero_pmd(pmd)) {
+		unsigned long zero_pfn;
+		bool set;
+		/*
+		 * get_huge_zero_page() will never allocate a new page here,
+		 * since we already have a zero page to copy. It just takes a
+		 * reference.
+		 */
+		zero_pfn = get_huge_zero_page();
+		set = set_huge_zero_page(pgtable, dst_mm, vma, addr, dst_pmd,
+				zero_pfn);
+		BUG_ON(!set); /* unexpected !pmd_none(dst_pmd) */
+		ret = 0;
+		goto out_unlock;
+	}
 	if (unlikely(pmd_trans_splitting(pmd))) {
 		/* split huge page running from under us */
 		spin_unlock(&src_mm->page_table_lock);
@@ -806,6 +957,80 @@
 	spin_unlock(&mm->page_table_lock);
 }
 
+static int do_huge_pmd_wp_zero_page_fallback(struct mm_struct *mm,
+		struct vm_area_struct *vma, unsigned long address,
+		pmd_t *pmd, pmd_t orig_pmd, unsigned long haddr)
+{
+	pgtable_t pgtable;
+	pmd_t _pmd;
+	struct page *page;
+	int i, ret = 0;
+	unsigned long mmun_start;	/* For mmu_notifiers */
+	unsigned long mmun_end;		/* For mmu_notifiers */
+
+	page = alloc_page_vma(GFP_HIGHUSER_MOVABLE, vma, address);
+	if (!page) {
+		ret |= VM_FAULT_OOM;
+		goto out;
+	}
+
+	if (mem_cgroup_newpage_charge(page, mm, GFP_KERNEL)) {
+		put_page(page);
+		ret |= VM_FAULT_OOM;
+		goto out;
+	}
+
+	clear_user_highpage(page, address);
+	__SetPageUptodate(page);
+
+	mmun_start = haddr;
+	mmun_end   = haddr + HPAGE_PMD_SIZE;
+	mmu_notifier_invalidate_range_start(mm, mmun_start, mmun_end);
+
+	spin_lock(&mm->page_table_lock);
+	if (unlikely(!pmd_same(*pmd, orig_pmd)))
+		goto out_free_page;
+
+	pmdp_clear_flush(vma, haddr, pmd);
+	/* leave pmd empty until pte is filled */
+
+	pgtable = pgtable_trans_huge_withdraw(mm);
+	pmd_populate(mm, &_pmd, pgtable);
+
+	for (i = 0; i < HPAGE_PMD_NR; i++, haddr += PAGE_SIZE) {
+		pte_t *pte, entry;
+		if (haddr == (address & PAGE_MASK)) {
+			entry = mk_pte(page, vma->vm_page_prot);
+			entry = maybe_mkwrite(pte_mkdirty(entry), vma);
+			page_add_new_anon_rmap(page, vma, haddr);
+		} else {
+			entry = pfn_pte(my_zero_pfn(haddr), vma->vm_page_prot);
+			entry = pte_mkspecial(entry);
+		}
+		pte = pte_offset_map(&_pmd, haddr);
+		VM_BUG_ON(!pte_none(*pte));
+		set_pte_at(mm, haddr, pte, entry);
+		pte_unmap(pte);
+	}
+	smp_wmb(); /* make pte visible before pmd */
+	pmd_populate(mm, pmd, pgtable);
+	spin_unlock(&mm->page_table_lock);
+	put_huge_zero_page();
+	inc_mm_counter(mm, MM_ANONPAGES);
+
+	mmu_notifier_invalidate_range_end(mm, mmun_start, mmun_end);
+
+	ret |= VM_FAULT_WRITE;
+out:
+	return ret;
+out_free_page:
+	spin_unlock(&mm->page_table_lock);
+	mmu_notifier_invalidate_range_end(mm, mmun_start, mmun_end);
+	mem_cgroup_uncharge_page(page);
+	put_page(page);
+	goto out;
+}
+
 static int do_huge_pmd_wp_page_fallback(struct mm_struct *mm,
 					struct vm_area_struct *vma,
 					unsigned long address,
@@ -912,19 +1137,21 @@
 			unsigned long address, pmd_t *pmd, pmd_t orig_pmd)
 {
 	int ret = 0;
-	struct page *page, *new_page;
+	struct page *page = NULL, *new_page;
 	unsigned long haddr;
 	unsigned long mmun_start;	/* For mmu_notifiers */
 	unsigned long mmun_end;		/* For mmu_notifiers */
 
 	VM_BUG_ON(!vma->anon_vma);
+	haddr = address & HPAGE_PMD_MASK;
+	if (is_huge_zero_pmd(orig_pmd))
+		goto alloc;
 	spin_lock(&mm->page_table_lock);
 	if (unlikely(!pmd_same(*pmd, orig_pmd)))
 		goto out_unlock;
 
 	page = pmd_page(orig_pmd);
 	VM_BUG_ON(!PageCompound(page) || !PageHead(page));
-	haddr = address & HPAGE_PMD_MASK;
 	if (page_mapcount(page) == 1) {
 		pmd_t entry;
 		entry = pmd_mkyoung(orig_pmd);
@@ -936,7 +1163,7 @@
 	}
 	get_page(page);
 	spin_unlock(&mm->page_table_lock);
-
+alloc:
 	if (transparent_hugepage_enabled(vma) &&
 	    !transparent_hugepage_debug_cow())
 		new_page = alloc_hugepage_vma(transparent_hugepage_defrag(vma),
@@ -946,24 +1173,34 @@
 
 	if (unlikely(!new_page)) {
 		count_vm_event(THP_FAULT_FALLBACK);
-		ret = do_huge_pmd_wp_page_fallback(mm, vma, address,
-						   pmd, orig_pmd, page, haddr);
-		if (ret & VM_FAULT_OOM)
-			split_huge_page(page);
-		put_page(page);
+		if (is_huge_zero_pmd(orig_pmd)) {
+			ret = do_huge_pmd_wp_zero_page_fallback(mm, vma,
+					address, pmd, orig_pmd, haddr);
+		} else {
+			ret = do_huge_pmd_wp_page_fallback(mm, vma, address,
+					pmd, orig_pmd, page, haddr);
+			if (ret & VM_FAULT_OOM)
+				split_huge_page(page);
+			put_page(page);
+		}
 		goto out;
 	}
 	count_vm_event(THP_FAULT_ALLOC);
 
 	if (unlikely(mem_cgroup_newpage_charge(new_page, mm, GFP_KERNEL))) {
 		put_page(new_page);
-		split_huge_page(page);
-		put_page(page);
+		if (page) {
+			split_huge_page(page);
+			put_page(page);
+		}
 		ret |= VM_FAULT_OOM;
 		goto out;
 	}
 
-	copy_user_huge_page(new_page, page, haddr, vma, HPAGE_PMD_NR);
+	if (is_huge_zero_pmd(orig_pmd))
+		clear_huge_page(new_page, haddr, HPAGE_PMD_NR);
+	else
+		copy_user_huge_page(new_page, page, haddr, vma, HPAGE_PMD_NR);
 	__SetPageUptodate(new_page);
 
 	mmun_start = haddr;
@@ -971,7 +1208,8 @@
 	mmu_notifier_invalidate_range_start(mm, mmun_start, mmun_end);
 
 	spin_lock(&mm->page_table_lock);
-	put_page(page);
+	if (page)
+		put_page(page);
 	if (unlikely(!pmd_same(*pmd, orig_pmd))) {
 		spin_unlock(&mm->page_table_lock);
 		mem_cgroup_uncharge_page(new_page);
@@ -979,14 +1217,19 @@
 		goto out_mn;
 	} else {
 		pmd_t entry;
-		VM_BUG_ON(!PageHead(page));
 		entry = mk_huge_pmd(new_page, vma);
 		pmdp_clear_flush(vma, haddr, pmd);
 		page_add_new_anon_rmap(new_page, vma, haddr);
 		set_pmd_at(mm, haddr, pmd, entry);
 		update_mmu_cache_pmd(vma, address, pmd);
-		page_remove_rmap(page);
-		put_page(page);
+		if (is_huge_zero_pmd(orig_pmd)) {
+			add_mm_counter(mm, MM_ANONPAGES, HPAGE_PMD_NR);
+			put_huge_zero_page();
+		} else {
+			VM_BUG_ON(!PageHead(page));
+			page_remove_rmap(page);
+			put_page(page);
+		}
 		ret |= VM_FAULT_WRITE;
 	}
 	spin_unlock(&mm->page_table_lock);
@@ -1055,15 +1298,21 @@
 		pmd_t orig_pmd;
 		pgtable = pgtable_trans_huge_withdraw(tlb->mm);
 		orig_pmd = pmdp_get_and_clear(tlb->mm, addr, pmd);
-		page = pmd_page(orig_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));
-		tlb->mm->nr_ptes--;
-		spin_unlock(&tlb->mm->page_table_lock);
-		tlb_remove_page(tlb, page);
+		if (is_huge_zero_pmd(orig_pmd)) {
+			tlb->mm->nr_ptes--;
+			spin_unlock(&tlb->mm->page_table_lock);
+			put_huge_zero_page();
+		} else {
+			page = pmd_page(orig_pmd);
+			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));
+			tlb->mm->nr_ptes--;
+			spin_unlock(&tlb->mm->page_table_lock);
+			tlb_remove_page(tlb, page);
+		}
 		pte_free(tlb->mm, pgtable);
 		ret = 1;
 	}
@@ -1135,6 +1384,7 @@
 		pmd_t entry;
 		entry = pmdp_get_and_clear(mm, addr, pmd);
 		entry = pmd_modify(entry, newprot);
+		BUG_ON(pmd_write(entry));
 		set_pmd_at(mm, addr, pmd, entry);
 		spin_unlock(&vma->vm_mm->page_table_lock);
 		ret = 1;
@@ -1477,6 +1727,7 @@
 	struct anon_vma *anon_vma;
 	int ret = 1;
 
+	BUG_ON(is_huge_zero_pfn(page_to_pfn(page)));
 	BUG_ON(!PageAnon(page));
 	anon_vma = page_lock_anon_vma(page);
 	if (!anon_vma)
@@ -2336,19 +2587,65 @@
 	return 0;
 }
 
-void __split_huge_page_pmd(struct mm_struct *mm, pmd_t *pmd)
+static void __split_huge_zero_page_pmd(struct vm_area_struct *vma,
+		unsigned long haddr, pmd_t *pmd)
+{
+	struct mm_struct *mm = vma->vm_mm;
+	pgtable_t pgtable;
+	pmd_t _pmd;
+	int i;
+
+	pmdp_clear_flush(vma, haddr, pmd);
+	/* leave pmd empty until pte is filled */
+
+	pgtable = pgtable_trans_huge_withdraw(mm);
+	pmd_populate(mm, &_pmd, pgtable);
+
+	for (i = 0; i < HPAGE_PMD_NR; i++, haddr += PAGE_SIZE) {
+		pte_t *pte, entry;
+		entry = pfn_pte(my_zero_pfn(haddr), vma->vm_page_prot);
+		entry = pte_mkspecial(entry);
+		pte = pte_offset_map(&_pmd, haddr);
+		VM_BUG_ON(!pte_none(*pte));
+		set_pte_at(mm, haddr, pte, entry);
+		pte_unmap(pte);
+	}
+	smp_wmb(); /* make pte visible before pmd */
+	pmd_populate(mm, pmd, pgtable);
+	put_huge_zero_page();
+}
+
+void __split_huge_page_pmd(struct vm_area_struct *vma, unsigned long address,
+		pmd_t *pmd)
 {
 	struct page *page;
+	struct mm_struct *mm = vma->vm_mm;
+	unsigned long haddr = address & HPAGE_PMD_MASK;
+	unsigned long mmun_start;	/* For mmu_notifiers */
+	unsigned long mmun_end;		/* For mmu_notifiers */
 
+	BUG_ON(vma->vm_start > haddr || vma->vm_end < haddr + HPAGE_PMD_SIZE);
+
+	mmun_start = haddr;
+	mmun_end   = haddr + HPAGE_PMD_SIZE;
+	mmu_notifier_invalidate_range_start(mm, mmun_start, mmun_end);
 	spin_lock(&mm->page_table_lock);
 	if (unlikely(!pmd_trans_huge(*pmd))) {
 		spin_unlock(&mm->page_table_lock);
+		mmu_notifier_invalidate_range_end(mm, mmun_start, mmun_end);
+		return;
+	}
+	if (is_huge_zero_pmd(*pmd)) {
+		__split_huge_zero_page_pmd(vma, haddr, pmd);
+		spin_unlock(&mm->page_table_lock);
+		mmu_notifier_invalidate_range_end(mm, mmun_start, mmun_end);
 		return;
 	}
 	page = pmd_page(*pmd);
 	VM_BUG_ON(!page_count(page));
 	get_page(page);
 	spin_unlock(&mm->page_table_lock);
+	mmu_notifier_invalidate_range_end(mm, mmun_start, mmun_end);
 
 	split_huge_page(page);
 
@@ -2356,6 +2653,16 @@
 	BUG_ON(pmd_trans_huge(*pmd));
 }
 
+void split_huge_page_pmd_mm(struct mm_struct *mm, unsigned long address,
+		pmd_t *pmd)
+{
+	struct vm_area_struct *vma;
+
+	vma = find_vma(mm, address);
+	BUG_ON(vma == NULL);
+	split_huge_page_pmd(vma, address, pmd);
+}
+
 static void split_huge_page_address(struct mm_struct *mm,
 				    unsigned long address)
 {
@@ -2370,7 +2677,7 @@
 	 * Caller holds the mmap_sem write mode, so a huge pmd cannot
 	 * materialize from under us.
 	 */
-	split_huge_page_pmd(mm, pmd);
+	split_huge_page_pmd_mm(mm, address, pmd);
 }
 
 void __vma_adjust_trans_huge(struct vm_area_struct *vma,
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index 1ef2cd4..88e7293 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -1,6 +1,6 @@
 /*
  * Generic hugetlb support.
- * (C) William Irwin, April 2004
+ * (C) Nadia Yvette Chambers, April 2004
  */
 #include <linux/list.h>
 #include <linux/init.h>
@@ -1057,7 +1057,7 @@
 	 * on-line nodes with memory and will handle the hstate accounting.
 	 */
 	while (nr_pages--) {
-		if (!free_pool_huge_page(h, &node_states[N_HIGH_MEMORY], 1))
+		if (!free_pool_huge_page(h, &node_states[N_MEMORY], 1))
 			break;
 	}
 }
@@ -1180,14 +1180,14 @@
 int __weak alloc_bootmem_huge_page(struct hstate *h)
 {
 	struct huge_bootmem_page *m;
-	int nr_nodes = nodes_weight(node_states[N_HIGH_MEMORY]);
+	int nr_nodes = nodes_weight(node_states[N_MEMORY]);
 
 	while (nr_nodes) {
 		void *addr;
 
 		addr = __alloc_bootmem_node_nopanic(
 				NODE_DATA(hstate_next_node_to_alloc(h,
-						&node_states[N_HIGH_MEMORY])),
+						&node_states[N_MEMORY])),
 				huge_page_size(h), huge_page_size(h), 0);
 
 		if (addr) {
@@ -1259,7 +1259,7 @@
 			if (!alloc_bootmem_huge_page(h))
 				break;
 		} else if (!alloc_fresh_huge_page(h,
-					 &node_states[N_HIGH_MEMORY]))
+					 &node_states[N_MEMORY]))
 			break;
 	}
 	h->max_huge_pages = i;
@@ -1527,7 +1527,7 @@
 		if (!(obey_mempolicy &&
 				init_nodemask_of_mempolicy(nodes_allowed))) {
 			NODEMASK_FREE(nodes_allowed);
-			nodes_allowed = &node_states[N_HIGH_MEMORY];
+			nodes_allowed = &node_states[N_MEMORY];
 		}
 	} else if (nodes_allowed) {
 		/*
@@ -1537,11 +1537,11 @@
 		count += h->nr_huge_pages - h->nr_huge_pages_node[nid];
 		init_nodemask_of_node(nodes_allowed, nid);
 	} else
-		nodes_allowed = &node_states[N_HIGH_MEMORY];
+		nodes_allowed = &node_states[N_MEMORY];
 
 	h->max_huge_pages = set_max_huge_pages(h, count, nodes_allowed);
 
-	if (nodes_allowed != &node_states[N_HIGH_MEMORY])
+	if (nodes_allowed != &node_states[N_MEMORY])
 		NODEMASK_FREE(nodes_allowed);
 
 	return len;
@@ -1844,7 +1844,7 @@
 {
 	int nid;
 
-	for_each_node_state(nid, N_HIGH_MEMORY) {
+	for_each_node_state(nid, N_MEMORY) {
 		struct node *node = node_devices[nid];
 		if (node->dev.id == nid)
 			hugetlb_register_node(node);
@@ -1939,8 +1939,8 @@
 	for (i = 0; i < MAX_NUMNODES; ++i)
 		INIT_LIST_HEAD(&h->hugepage_freelists[i]);
 	INIT_LIST_HEAD(&h->hugepage_activelist);
-	h->next_nid_to_alloc = first_node(node_states[N_HIGH_MEMORY]);
-	h->next_nid_to_free = first_node(node_states[N_HIGH_MEMORY]);
+	h->next_nid_to_alloc = first_node(node_states[N_MEMORY]);
+	h->next_nid_to_free = first_node(node_states[N_MEMORY]);
 	snprintf(h->name, HSTATE_NAME_LEN, "hugepages-%lukB",
 					huge_page_size(h)/1024);
 	/*
@@ -2035,11 +2035,11 @@
 		if (!(obey_mempolicy &&
 			       init_nodemask_of_mempolicy(nodes_allowed))) {
 			NODEMASK_FREE(nodes_allowed);
-			nodes_allowed = &node_states[N_HIGH_MEMORY];
+			nodes_allowed = &node_states[N_MEMORY];
 		}
 		h->max_huge_pages = set_max_huge_pages(h, tmp, nodes_allowed);
 
-		if (nodes_allowed != &node_states[N_HIGH_MEMORY])
+		if (nodes_allowed != &node_states[N_MEMORY])
 			NODEMASK_FREE(nodes_allowed);
 	}
 out:
@@ -2386,8 +2386,10 @@
 		/*
 		 * HWPoisoned hugepage is already unmapped and dropped reference
 		 */
-		if (unlikely(is_hugetlb_entry_hwpoisoned(pte)))
+		if (unlikely(is_hugetlb_entry_hwpoisoned(pte))) {
+			pte_clear(mm, address, ptep);
 			continue;
+		}
 
 		page = pte_page(pte);
 		/*
@@ -3170,7 +3172,13 @@
 
 	spin_lock(&hugetlb_lock);
 	if (is_hugepage_on_freelist(hpage)) {
-		list_del(&hpage->lru);
+		/*
+		 * Hwpoisoned hugepage isn't linked to activelist or freelist,
+		 * but dangling hpage->lru can trigger list-debug warnings
+		 * (this happens when we call unpoison_memory() on it),
+		 * so let it point to itself with list_del_init().
+		 */
+		list_del_init(&hpage->lru);
 		set_page_refcounted(hpage);
 		h->free_huge_pages--;
 		h->free_huge_pages_node[nid]--;
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 12307b3..6c05592 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -59,6 +59,8 @@
 #include <trace/events/vmscan.h>
 
 struct cgroup_subsys mem_cgroup_subsys __read_mostly;
+EXPORT_SYMBOL(mem_cgroup_subsys);
+
 #define MEM_CGROUP_RECLAIM_RETRIES	5
 static struct mem_cgroup *root_mem_cgroup __read_mostly;
 
@@ -800,7 +802,7 @@
 	int nid;
 	u64 total = 0;
 
-	for_each_node_state(nid, N_HIGH_MEMORY)
+	for_each_node_state(nid, N_MEMORY)
 		total += mem_cgroup_node_nr_lru_pages(memcg, nid, lru_mask);
 	return total;
 }
@@ -1015,13 +1017,10 @@
 	     iter != NULL;				\
 	     iter = mem_cgroup_iter(NULL, iter, NULL))
 
-void mem_cgroup_count_vm_event(struct mm_struct *mm, enum vm_event_item idx)
+void __mem_cgroup_count_vm_event(struct mm_struct *mm, enum vm_event_item idx)
 {
 	struct mem_cgroup *memcg;
 
-	if (!mm)
-		return;
-
 	rcu_read_lock();
 	memcg = mem_cgroup_from_task(rcu_dereference(mm->owner));
 	if (unlikely(!memcg))
@@ -1040,7 +1039,7 @@
 out:
 	rcu_read_unlock();
 }
-EXPORT_SYMBOL(mem_cgroup_count_vm_event);
+EXPORT_SYMBOL(__mem_cgroup_count_vm_event);
 
 /**
  * mem_cgroup_zone_lruvec - get the lru list vector for a zone and memcg
@@ -1644,9 +1643,9 @@
 		return;
 
 	/* make a nodemask where this memcg uses memory from */
-	memcg->scan_nodes = node_states[N_HIGH_MEMORY];
+	memcg->scan_nodes = node_states[N_MEMORY];
 
-	for_each_node_mask(nid, node_states[N_HIGH_MEMORY]) {
+	for_each_node_mask(nid, node_states[N_MEMORY]) {
 
 		if (!test_mem_cgroup_node_reclaimable(memcg, nid, false))
 			node_clear(nid, memcg->scan_nodes);
@@ -1717,7 +1716,7 @@
 	/*
 	 * Check rest of nodes.
 	 */
-	for_each_node_state(nid, N_HIGH_MEMORY) {
+	for_each_node_state(nid, N_MEMORY) {
 		if (node_isset(nid, memcg->scan_nodes))
 			continue;
 		if (test_mem_cgroup_node_reclaimable(memcg, nid, noswap))
@@ -3776,7 +3775,7 @@
 		lru_add_drain_all();
 		drain_all_stock_sync(memcg);
 		mem_cgroup_start_move(memcg);
-		for_each_node_state(node, N_HIGH_MEMORY) {
+		for_each_node_state(node, N_MEMORY) {
 			for (zid = 0; zid < MAX_NR_ZONES; zid++) {
 				enum lru_list lru;
 				for_each_lru(lru) {
@@ -4122,7 +4121,7 @@
 
 	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) {
+	for_each_node_state(nid, N_MEMORY) {
 		node_nr = mem_cgroup_node_nr_lru_pages(memcg, nid, LRU_ALL);
 		seq_printf(m, " N%d=%lu", nid, node_nr);
 	}
@@ -4130,7 +4129,7 @@
 
 	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) {
+	for_each_node_state(nid, N_MEMORY) {
 		node_nr = mem_cgroup_node_nr_lru_pages(memcg, nid,
 				LRU_ALL_FILE);
 		seq_printf(m, " N%d=%lu", nid, node_nr);
@@ -4139,7 +4138,7 @@
 
 	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) {
+	for_each_node_state(nid, N_MEMORY) {
 		node_nr = mem_cgroup_node_nr_lru_pages(memcg, nid,
 				LRU_ALL_ANON);
 		seq_printf(m, " N%d=%lu", nid, node_nr);
@@ -4148,7 +4147,7 @@
 
 	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) {
+	for_each_node_state(nid, N_MEMORY) {
 		node_nr = mem_cgroup_node_nr_lru_pages(memcg, nid,
 				BIT(LRU_UNEVICTABLE));
 		seq_printf(m, " N%d=%lu", nid, node_nr);
diff --git a/mm/memory.c b/mm/memory.c
index 7653773..db2e9e7 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -717,20 +717,6 @@
 	return (flags & (VM_SHARED | VM_MAYWRITE)) == VM_MAYWRITE;
 }
 
-#ifndef is_zero_pfn
-static inline int is_zero_pfn(unsigned long pfn)
-{
-	return pfn == zero_pfn;
-}
-#endif
-
-#ifndef my_zero_pfn
-static inline unsigned long my_zero_pfn(unsigned long addr)
-{
-	return zero_pfn;
-}
-#endif
-
 /*
  * vm_normal_page -- This function gets the "struct page" associated with a pte.
  *
@@ -1250,7 +1236,7 @@
 					BUG();
 				}
 #endif
-				split_huge_page_pmd(vma->vm_mm, pmd);
+				split_huge_page_pmd(vma, addr, pmd);
 			} else if (zap_huge_pmd(tlb, vma, pmd, addr))
 				goto next;
 			/* fall through */
@@ -1519,7 +1505,7 @@
 	}
 	if (pmd_trans_huge(*pmd)) {
 		if (flags & FOLL_SPLIT) {
-			split_huge_page_pmd(mm, pmd);
+			split_huge_page_pmd(vma, address, pmd);
 			goto split_fallthrough;
 		}
 		spin_lock(&mm->page_table_lock);
@@ -2794,13 +2780,8 @@
 oom_free_new:
 	page_cache_release(new_page);
 oom:
-	if (old_page) {
-		if (page_mkwrite) {
-			unlock_page(old_page);
-			page_cache_release(old_page);
-		}
+	if (old_page)
 		page_cache_release(old_page);
-	}
 	return VM_FAULT_OOM;
 
 unwritable_page:
diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
index de9cb14..518baa8 100644
--- a/mm/memory_hotplug.c
+++ b/mm/memory_hotplug.c
@@ -106,6 +106,7 @@
 void __ref put_page_bootmem(struct page *page)
 {
 	unsigned long type;
+	static DEFINE_MUTEX(ppb_lock);
 
 	type = (unsigned long) page->lru.next;
 	BUG_ON(type < MEMORY_HOTPLUG_MIN_BOOTMEM_TYPE ||
@@ -115,7 +116,14 @@
 		ClearPagePrivate(page);
 		set_page_private(page, 0);
 		INIT_LIST_HEAD(&page->lru);
+
+		/*
+		 * Please refer to comment for __free_pages_bootmem()
+		 * for why we serialize here.
+		 */
+		mutex_lock(&ppb_lock);
 		__free_pages_bootmem(page, 0);
+		mutex_unlock(&ppb_lock);
 	}
 
 }
@@ -581,11 +589,19 @@
 	return 0;
 }
 
+#ifdef CONFIG_MOVABLE_NODE
+/* when CONFIG_MOVABLE_NODE, we allow online node don't have normal memory */
+static bool can_online_high_movable(struct zone *zone)
+{
+	return true;
+}
+#else /* #ifdef CONFIG_MOVABLE_NODE */
 /* ensure every online node has NORMAL memory */
 static bool can_online_high_movable(struct zone *zone)
 {
 	return node_state(zone_to_nid(zone), N_NORMAL_MEMORY);
 }
+#endif /* #ifdef CONFIG_MOVABLE_NODE */
 
 /* check which state of node_states will be changed when online memory */
 static void node_states_check_changes_online(unsigned long nr_pages,
@@ -595,13 +611,15 @@
 	enum zone_type zone_last = ZONE_NORMAL;
 
 	/*
-	 * If we have HIGHMEM, node_states[N_NORMAL_MEMORY] contains nodes
-	 * which have 0...ZONE_NORMAL, set zone_last to ZONE_NORMAL.
+	 * If we have HIGHMEM or movable node, node_states[N_NORMAL_MEMORY]
+	 * contains nodes which have zones of 0...ZONE_NORMAL,
+	 * set zone_last to ZONE_NORMAL.
 	 *
-	 * If we don't have HIGHMEM, node_states[N_NORMAL_MEMORY] contains nodes
-	 * which have 0...ZONE_MOVABLE, set zone_last to ZONE_MOVABLE.
+	 * If we don't have HIGHMEM nor movable node,
+	 * node_states[N_NORMAL_MEMORY] contains nodes which have zones of
+	 * 0...ZONE_MOVABLE, set zone_last to ZONE_MOVABLE.
 	 */
-	if (N_HIGH_MEMORY == N_NORMAL_MEMORY)
+	if (N_MEMORY == N_NORMAL_MEMORY)
 		zone_last = ZONE_MOVABLE;
 
 	/*
@@ -615,12 +633,34 @@
 	else
 		arg->status_change_nid_normal = -1;
 
+#ifdef CONFIG_HIGHMEM
+	/*
+	 * If we have movable node, node_states[N_HIGH_MEMORY]
+	 * contains nodes which have zones of 0...ZONE_HIGHMEM,
+	 * set zone_last to ZONE_HIGHMEM.
+	 *
+	 * If we don't have movable node, node_states[N_NORMAL_MEMORY]
+	 * contains nodes which have zones of 0...ZONE_MOVABLE,
+	 * set zone_last to ZONE_MOVABLE.
+	 */
+	zone_last = ZONE_HIGHMEM;
+	if (N_MEMORY == N_HIGH_MEMORY)
+		zone_last = ZONE_MOVABLE;
+
+	if (zone_idx(zone) <= zone_last && !node_state(nid, N_HIGH_MEMORY))
+		arg->status_change_nid_high = nid;
+	else
+		arg->status_change_nid_high = -1;
+#else
+	arg->status_change_nid_high = arg->status_change_nid_normal;
+#endif
+
 	/*
 	 * if the node don't have memory befor online, we will need to
-	 * set the node to node_states[N_HIGH_MEMORY] after the memory
+	 * set the node to node_states[N_MEMORY] after the memory
 	 * is online.
 	 */
-	if (!node_state(nid, N_HIGH_MEMORY))
+	if (!node_state(nid, N_MEMORY))
 		arg->status_change_nid = nid;
 	else
 		arg->status_change_nid = -1;
@@ -631,7 +671,10 @@
 	if (arg->status_change_nid_normal >= 0)
 		node_set_state(node, N_NORMAL_MEMORY);
 
-	node_set_state(node, N_HIGH_MEMORY);
+	if (arg->status_change_nid_high >= 0)
+		node_set_state(node, N_HIGH_MEMORY);
+
+	node_set_state(node, N_MEMORY);
 }
 
 
@@ -713,6 +756,7 @@
 		return ret;
 	}
 
+	zone->managed_pages += onlined_pages;
 	zone->present_pages += onlined_pages;
 	zone->zone_pgdat->node_present_pages += onlined_pages;
 	if (onlined_pages) {
@@ -1066,6 +1110,13 @@
 	return offlined;
 }
 
+#ifdef CONFIG_MOVABLE_NODE
+/* when CONFIG_MOVABLE_NODE, we allow online node don't have normal memory */
+static bool can_offline_normal(struct zone *zone, unsigned long nr_pages)
+{
+	return true;
+}
+#else /* #ifdef CONFIG_MOVABLE_NODE */
 /* ensure the node has NORMAL memory if it is still online */
 static bool can_offline_normal(struct zone *zone, unsigned long nr_pages)
 {
@@ -1089,6 +1140,7 @@
 	 */
 	return present_pages == 0;
 }
+#endif /* #ifdef CONFIG_MOVABLE_NODE */
 
 /* check which state of node_states will be changed when offline memory */
 static void node_states_check_changes_offline(unsigned long nr_pages,
@@ -1099,13 +1151,15 @@
 	enum zone_type zt, zone_last = ZONE_NORMAL;
 
 	/*
-	 * If we have HIGHMEM, node_states[N_NORMAL_MEMORY] contains nodes
-	 * which have 0...ZONE_NORMAL, set zone_last to ZONE_NORMAL.
+	 * If we have HIGHMEM or movable node, node_states[N_NORMAL_MEMORY]
+	 * contains nodes which have zones of 0...ZONE_NORMAL,
+	 * set zone_last to ZONE_NORMAL.
 	 *
-	 * If we don't have HIGHMEM, node_states[N_NORMAL_MEMORY] contains nodes
-	 * which have 0...ZONE_MOVABLE, set zone_last to ZONE_MOVABLE.
+	 * If we don't have HIGHMEM nor movable node,
+	 * node_states[N_NORMAL_MEMORY] contains nodes which have zones of
+	 * 0...ZONE_MOVABLE, set zone_last to ZONE_MOVABLE.
 	 */
-	if (N_HIGH_MEMORY == N_NORMAL_MEMORY)
+	if (N_MEMORY == N_NORMAL_MEMORY)
 		zone_last = ZONE_MOVABLE;
 
 	/*
@@ -1122,6 +1176,30 @@
 	else
 		arg->status_change_nid_normal = -1;
 
+#ifdef CONFIG_HIGHMEM
+	/*
+	 * If we have movable node, node_states[N_HIGH_MEMORY]
+	 * contains nodes which have zones of 0...ZONE_HIGHMEM,
+	 * set zone_last to ZONE_HIGHMEM.
+	 *
+	 * If we don't have movable node, node_states[N_NORMAL_MEMORY]
+	 * contains nodes which have zones of 0...ZONE_MOVABLE,
+	 * set zone_last to ZONE_MOVABLE.
+	 */
+	zone_last = ZONE_HIGHMEM;
+	if (N_MEMORY == N_HIGH_MEMORY)
+		zone_last = ZONE_MOVABLE;
+
+	for (; zt <= zone_last; zt++)
+		present_pages += pgdat->node_zones[zt].present_pages;
+	if (zone_idx(zone) <= zone_last && nr_pages >= present_pages)
+		arg->status_change_nid_high = zone_to_nid(zone);
+	else
+		arg->status_change_nid_high = -1;
+#else
+	arg->status_change_nid_high = arg->status_change_nid_normal;
+#endif
+
 	/*
 	 * node_states[N_HIGH_MEMORY] contains nodes which have 0...ZONE_MOVABLE
 	 */
@@ -1146,9 +1224,13 @@
 	if (arg->status_change_nid_normal >= 0)
 		node_clear_state(node, N_NORMAL_MEMORY);
 
-	if ((N_HIGH_MEMORY != N_NORMAL_MEMORY) &&
-	    (arg->status_change_nid >= 0))
+	if ((N_MEMORY != N_NORMAL_MEMORY) &&
+	    (arg->status_change_nid_high >= 0))
 		node_clear_state(node, N_HIGH_MEMORY);
+
+	if ((N_MEMORY != N_HIGH_MEMORY) &&
+	    (arg->status_change_nid >= 0))
+		node_clear_state(node, N_MEMORY);
 }
 
 static int __ref __offline_pages(unsigned long start_pfn,
@@ -1230,10 +1312,10 @@
 			goto repeat;
 		}
 	}
-	/* drain all zone's lru pagevec, this is asyncronous... */
+	/* drain all zone's lru pagevec, this is asynchronous... */
 	lru_add_drain_all();
 	yield();
-	/* drain pcp pages , this is synchrouns. */
+	/* drain pcp pages, this is synchronous. */
 	drain_all_pages();
 	/* check again */
 	offlined_pages = check_pages_isolated(start_pfn, end_pfn);
@@ -1242,12 +1324,13 @@
 		goto failed_removal;
 	}
 	printk(KERN_INFO "Offlined Pages %ld\n", offlined_pages);
-	/* Ok, all of our target is islaoted.
+	/* Ok, all of our target is isolated.
 	   We cannot do rollback at this point. */
 	offline_isolated_pages(start_pfn, end_pfn);
 	/* reset pagetype flags and makes migrate type to be MOVABLE */
 	undo_isolate_page_range(start_pfn, end_pfn, MIGRATE_MOVABLE);
 	/* removal success */
+	zone->managed_pages -= offlined_pages;
 	zone->present_pages -= offlined_pages;
 	zone->zone_pgdat->node_present_pages -= offlined_pages;
 	totalram_pages -= offlined_pages;
diff --git a/mm/mempolicy.c b/mm/mempolicy.c
index 05b2836..aaf5456 100644
--- a/mm/mempolicy.c
+++ b/mm/mempolicy.c
@@ -212,9 +212,9 @@
 	/* if mode is MPOL_DEFAULT, pol is NULL. This is right. */
 	if (pol == NULL)
 		return 0;
-	/* Check N_HIGH_MEMORY */
+	/* Check N_MEMORY */
 	nodes_and(nsc->mask1,
-		  cpuset_current_mems_allowed, node_states[N_HIGH_MEMORY]);
+		  cpuset_current_mems_allowed, node_states[N_MEMORY]);
 
 	VM_BUG_ON(!nodes);
 	if (pol->mode == MPOL_PREFERRED && nodes_empty(*nodes))
@@ -511,7 +511,7 @@
 	pmd = pmd_offset(pud, addr);
 	do {
 		next = pmd_addr_end(addr, end);
-		split_huge_page_pmd(vma->vm_mm, pmd);
+		split_huge_page_pmd(vma, addr, pmd);
 		if (pmd_none_or_trans_huge_or_clear_bad(pmd))
 			continue;
 		if (check_pte_range(vma, pmd, addr, next, nodes,
@@ -1388,7 +1388,7 @@
 		goto out_put;
 	}
 
-	if (!nodes_subset(*new, node_states[N_HIGH_MEMORY])) {
+	if (!nodes_subset(*new, node_states[N_MEMORY])) {
 		err = -EINVAL;
 		goto out_put;
 	}
@@ -2326,7 +2326,7 @@
 	 * fall back to the largest node if they're all smaller.
 	 */
 	nodes_clear(interleave_nodes);
-	for_each_node_state(nid, N_HIGH_MEMORY) {
+	for_each_node_state(nid, N_MEMORY) {
 		unsigned long total_pages = node_present_pages(nid);
 
 		/* Preserve the largest node */
@@ -2407,7 +2407,7 @@
 		*nodelist++ = '\0';
 		if (nodelist_parse(nodelist, nodes))
 			goto out;
-		if (!nodes_subset(nodes, node_states[N_HIGH_MEMORY]))
+		if (!nodes_subset(nodes, node_states[N_MEMORY]))
 			goto out;
 	} else
 		nodes_clear(nodes);
@@ -2441,7 +2441,7 @@
 		 * Default to online nodes with memory if no nodelist
 		 */
 		if (!nodelist)
-			nodes = node_states[N_HIGH_MEMORY];
+			nodes = node_states[N_MEMORY];
 		break;
 	case MPOL_LOCAL:
 		/*
diff --git a/mm/migrate.c b/mm/migrate.c
index 3f675ca..cae0271 100644
--- a/mm/migrate.c
+++ b/mm/migrate.c
@@ -1238,7 +1238,7 @@
 			if (node < 0 || node >= MAX_NUMNODES)
 				goto out_pm;
 
-			if (!node_state(node, N_HIGH_MEMORY))
+			if (!node_state(node, N_MEMORY))
 				goto out_pm;
 
 			err = -EACCES;
diff --git a/mm/mmap.c b/mm/mmap.c
index f940062..2b7d9e7 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -1488,7 +1488,11 @@
 		 *
 		 * Answer: Yes, several device drivers can do it in their
 		 *         f_op->mmap method. -DaveM
+		 * Bug: If addr is changed, prev, rb_link, rb_parent should
+		 *      be updated for vma_link()
 		 */
+		WARN_ON_ONCE(addr != vma->vm_start);
+
 		addr = vma->vm_start;
 		pgoff = vma->vm_pgoff;
 		vm_flags = vma->vm_flags;
@@ -2065,6 +2069,18 @@
 		if (vma->vm_pgoff + (size >> PAGE_SHIFT) >= vma->vm_pgoff) {
 			error = acct_stack_growth(vma, size, grow);
 			if (!error) {
+				/*
+				 * vma_gap_update() doesn't support concurrent
+				 * updates, but we only hold a shared mmap_sem
+				 * lock here, so we need to protect against
+				 * concurrent vma expansions.
+				 * vma_lock_anon_vma() doesn't help here, as
+				 * we don't guarantee that all growable vmas
+				 * in a mm share the same root anon vma.
+				 * So, we reuse mm->page_table_lock to guard
+				 * against concurrent vma expansions.
+				 */
+				spin_lock(&vma->vm_mm->page_table_lock);
 				anon_vma_interval_tree_pre_update_vma(vma);
 				vma->vm_end = address;
 				anon_vma_interval_tree_post_update_vma(vma);
@@ -2072,6 +2088,8 @@
 					vma_gap_update(vma->vm_next);
 				else
 					vma->vm_mm->highest_vm_end = address;
+				spin_unlock(&vma->vm_mm->page_table_lock);
+
 				perf_event_mmap(vma);
 			}
 		}
@@ -2122,11 +2140,25 @@
 		if (grow <= vma->vm_pgoff) {
 			error = acct_stack_growth(vma, size, grow);
 			if (!error) {
+				/*
+				 * vma_gap_update() doesn't support concurrent
+				 * updates, but we only hold a shared mmap_sem
+				 * lock here, so we need to protect against
+				 * concurrent vma expansions.
+				 * vma_lock_anon_vma() doesn't help here, as
+				 * we don't guarantee that all growable vmas
+				 * in a mm share the same root anon vma.
+				 * So, we reuse mm->page_table_lock to guard
+				 * against concurrent vma expansions.
+				 */
+				spin_lock(&vma->vm_mm->page_table_lock);
 				anon_vma_interval_tree_pre_update_vma(vma);
 				vma->vm_start = address;
 				vma->vm_pgoff -= grow;
 				anon_vma_interval_tree_post_update_vma(vma);
 				vma_gap_update(vma);
+				spin_unlock(&vma->vm_mm->page_table_lock);
+
 				perf_event_mmap(vma);
 			}
 		}
diff --git a/mm/mprotect.c b/mm/mprotect.c
index a409926..e8c3938 100644
--- a/mm/mprotect.c
+++ b/mm/mprotect.c
@@ -90,7 +90,7 @@
 		next = pmd_addr_end(addr, end);
 		if (pmd_trans_huge(*pmd)) {
 			if (next - addr != HPAGE_PMD_SIZE)
-				split_huge_page_pmd(vma->vm_mm, pmd);
+				split_huge_page_pmd(vma, addr, pmd);
 			else if (change_huge_pmd(vma, pmd, addr, newprot))
 				continue;
 			/* fall through */
diff --git a/mm/mremap.c b/mm/mremap.c
index 1b61c2d..eabb24d 100644
--- a/mm/mremap.c
+++ b/mm/mremap.c
@@ -182,7 +182,7 @@
 				need_flush = true;
 				continue;
 			} else if (!err) {
-				split_huge_page_pmd(vma->vm_mm, old_pmd);
+				split_huge_page_pmd(vma, old_addr, old_pmd);
 			}
 			VM_BUG_ON(pmd_trans_huge(*old_pmd));
 		}
diff --git a/mm/nobootmem.c b/mm/nobootmem.c
index bd82f6b..b8294fc 100644
--- a/mm/nobootmem.c
+++ b/mm/nobootmem.c
@@ -137,6 +137,22 @@
 	return count;
 }
 
+static void reset_node_lowmem_managed_pages(pg_data_t *pgdat)
+{
+	struct zone *z;
+
+	/*
+	 * In free_area_init_core(), highmem zone's managed_pages is set to
+	 * present_pages, and bootmem allocator doesn't allocate from highmem
+	 * zones. So there's no need to recalculate managed_pages because all
+	 * highmem pages will be managed by the buddy system. Here highmem
+	 * zone also includes highmem movable zone.
+	 */
+	for (z = pgdat->node_zones; z < pgdat->node_zones + MAX_NR_ZONES; z++)
+		if (!is_highmem(z))
+			z->managed_pages = 0;
+}
+
 /**
  * free_all_bootmem_node - release a node's free pages to the buddy allocator
  * @pgdat: node to be released
@@ -146,6 +162,7 @@
 unsigned long __init free_all_bootmem_node(pg_data_t *pgdat)
 {
 	register_page_bootmem_info_node(pgdat);
+	reset_node_lowmem_managed_pages(pgdat);
 
 	/* free_low_memory_core_early(MAX_NUMNODES) will be called later */
 	return 0;
@@ -158,6 +175,11 @@
  */
 unsigned long __init free_all_bootmem(void)
 {
+	struct pglist_data *pgdat;
+
+	for_each_online_pgdat(pgdat)
+		reset_node_lowmem_managed_pages(pgdat);
+
 	/*
 	 * We need to use MAX_NUMNODES instead of NODE_DATA(0)->node_id
 	 *  because in some case like Node0 doesn't have RAM installed
diff --git a/mm/oom_kill.c b/mm/oom_kill.c
index 18f1ae2..0399f14 100644
--- a/mm/oom_kill.c
+++ b/mm/oom_kill.c
@@ -215,7 +215,7 @@
 	 * the page allocator means a mempolicy is in effect.  Cpuset policy
 	 * is enforced in get_page_from_freelist().
 	 */
-	if (nodemask && !nodes_subset(node_states[N_HIGH_MEMORY], *nodemask)) {
+	if (nodemask && !nodes_subset(node_states[N_MEMORY], *nodemask)) {
 		*totalpages = total_swap_pages;
 		for_each_node_mask(nid, *nodemask)
 			*totalpages += node_spanned_pages(nid);
@@ -591,43 +591,6 @@
 	spin_unlock(&zone_scan_lock);
 }
 
-/*
- * Try to acquire the oom killer lock for all system zones.  Returns zero if a
- * parallel oom killing is taking place, otherwise locks all zones and returns
- * non-zero.
- */
-static int try_set_system_oom(void)
-{
-	struct zone *zone;
-	int ret = 1;
-
-	spin_lock(&zone_scan_lock);
-	for_each_populated_zone(zone)
-		if (zone_is_oom_locked(zone)) {
-			ret = 0;
-			goto out;
-		}
-	for_each_populated_zone(zone)
-		zone_set_flag(zone, ZONE_OOM_LOCKED);
-out:
-	spin_unlock(&zone_scan_lock);
-	return ret;
-}
-
-/*
- * Clears ZONE_OOM_LOCKED for all system zones so that failed allocation
- * attempts or page faults may now recall the oom killer, if necessary.
- */
-static void clear_system_oom(void)
-{
-	struct zone *zone;
-
-	spin_lock(&zone_scan_lock);
-	for_each_populated_zone(zone)
-		zone_clear_flag(zone, ZONE_OOM_LOCKED);
-	spin_unlock(&zone_scan_lock);
-}
-
 /**
  * out_of_memory - kill the "best" process when we run out of memory
  * @zonelist: zonelist pointer
@@ -708,15 +671,16 @@
 
 /*
  * The pagefault handler calls here because it is out of memory, so kill a
- * memory-hogging task.  If a populated zone has ZONE_OOM_LOCKED set, a parallel
- * oom killing is already in progress so do nothing.  If a task is found with
- * TIF_MEMDIE set, it has been killed so do nothing and allow it to exit.
+ * memory-hogging task.  If any populated zone has ZONE_OOM_LOCKED set, a
+ * parallel oom killing is already in progress so do nothing.
  */
 void pagefault_out_of_memory(void)
 {
-	if (try_set_system_oom()) {
+	struct zonelist *zonelist = node_zonelist(first_online_node,
+						  GFP_KERNEL);
+
+	if (try_set_zonelist_oom(zonelist, GFP_KERNEL)) {
 		out_of_memory(NULL, 0, 0, NULL, false);
-		clear_system_oom();
+		clear_zonelist_oom(zonelist, GFP_KERNEL);
 	}
-	schedule_timeout_killable(1);
 }
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 5a8d339..83637df 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -90,6 +90,9 @@
 #ifdef CONFIG_HIGHMEM
 	[N_HIGH_MEMORY] = { { [0] = 1UL } },
 #endif
+#ifdef CONFIG_MOVABLE_NODE
+	[N_MEMORY] = { { [0] = 1UL } },
+#endif
 	[N_CPU] = { { [0] = 1UL } },
 #endif	/* NUMA */
 };
@@ -523,7 +526,7 @@
  * If a block is freed, and its buddy is also free, then this
  * triggers coalescing into a block of larger size.
  *
- * -- wli
+ * -- nyc
  */
 
 static inline void __free_one_page(struct page *page,
@@ -732,6 +735,13 @@
 	local_irq_restore(flags);
 }
 
+/*
+ * Read access to zone->managed_pages is safe because it's unsigned long,
+ * but we still need to serialize writers. Currently all callers of
+ * __free_pages_bootmem() except put_page_bootmem() should only be used
+ * at boot time. So for shorter boot time, we shift the burden to
+ * put_page_bootmem() to serialize writers.
+ */
 void __meminit __free_pages_bootmem(struct page *page, unsigned int order)
 {
 	unsigned int nr_pages = 1 << order;
@@ -747,6 +757,7 @@
 		set_page_count(p, 0);
 	}
 
+	page_zone(page)->managed_pages += 1 << order;
 	set_page_refcounted(page);
 	__free_pages(page, order);
 }
@@ -782,7 +793,7 @@
  * large block of memory acted on by a series of small allocations.
  * This behavior is a critical factor in sglist merging's success.
  *
- * -- wli
+ * -- nyc
  */
 static inline void expand(struct zone *zone, struct page *page,
 	int low, int high, struct free_area *area,
@@ -1695,7 +1706,7 @@
  *
  * If the zonelist cache is present in the passed in zonelist, then
  * returns a pointer to the allowed node mask (either the current
- * tasks mems_allowed, or node_states[N_HIGH_MEMORY].)
+ * tasks mems_allowed, or node_states[N_MEMORY].)
  *
  * If the zonelist cache is not available for this zonelist, does
  * nothing and returns NULL.
@@ -1724,7 +1735,7 @@
 
 	allowednodes = !in_interrupt() && (alloc_flags & ALLOC_CPUSET) ?
 					&cpuset_current_mems_allowed :
-					&node_states[N_HIGH_MEMORY];
+					&node_states[N_MEMORY];
 	return allowednodes;
 }
 
@@ -2981,6 +2992,7 @@
 			" isolated(anon):%lukB"
 			" isolated(file):%lukB"
 			" present:%lukB"
+			" managed:%lukB"
 			" mlocked:%lukB"
 			" dirty:%lukB"
 			" writeback:%lukB"
@@ -3010,6 +3022,7 @@
 			K(zone_page_state(zone, NR_ISOLATED_ANON)),
 			K(zone_page_state(zone, NR_ISOLATED_FILE)),
 			K(zone->present_pages),
+			K(zone->managed_pages),
 			K(zone_page_state(zone, NR_MLOCK)),
 			K(zone_page_state(zone, NR_FILE_DIRTY)),
 			K(zone_page_state(zone, NR_WRITEBACK)),
@@ -3238,7 +3251,7 @@
 		return node;
 	}
 
-	for_each_node_state(n, N_HIGH_MEMORY) {
+	for_each_node_state(n, N_MEMORY) {
 
 		/* Don't want a node to appear more than once */
 		if (node_isset(n, *used_node_mask))
@@ -3380,7 +3393,7 @@
  	 * local memory, NODE_ORDER may be suitable.
          */
 	average_size = total_size /
-				(nodes_weight(node_states[N_HIGH_MEMORY]) + 1);
+				(nodes_weight(node_states[N_MEMORY]) + 1);
 	for_each_online_node(nid) {
 		low_kmem_size = 0;
 		total_size = 0;
@@ -4476,6 +4489,26 @@
 
 #endif /* CONFIG_HUGETLB_PAGE_SIZE_VARIABLE */
 
+static unsigned long __paginginit calc_memmap_size(unsigned long spanned_pages,
+						   unsigned long present_pages)
+{
+	unsigned long pages = spanned_pages;
+
+	/*
+	 * Provide a more accurate estimation if there are holes within
+	 * the zone and SPARSEMEM is in use. If there are holes within the
+	 * zone, each populated memory region may cost us one or two extra
+	 * memmap pages due to alignment because memmap pages for each
+	 * populated regions may not naturally algined on page boundary.
+	 * So the (present_pages >> 4) heuristic is a tradeoff for that.
+	 */
+	if (spanned_pages > present_pages + (present_pages >> 4) &&
+	    IS_ENABLED(CONFIG_SPARSEMEM))
+		pages = present_pages;
+
+	return PAGE_ALIGN(pages * sizeof(struct page)) >> PAGE_SHIFT;
+}
+
 /*
  * Set up the zone data structures:
  *   - mark all pages reserved
@@ -4499,48 +4532,56 @@
 
 	for (j = 0; j < MAX_NR_ZONES; j++) {
 		struct zone *zone = pgdat->node_zones + j;
-		unsigned long size, realsize, memmap_pages;
+		unsigned long size, realsize, freesize, memmap_pages;
 
 		size = zone_spanned_pages_in_node(nid, j, zones_size);
-		realsize = size - zone_absent_pages_in_node(nid, j,
+		realsize = freesize = size - zone_absent_pages_in_node(nid, j,
 								zholes_size);
 
 		/*
-		 * Adjust realsize so that it accounts for how much memory
+		 * Adjust freesize so that it accounts for how much memory
 		 * is used by this zone for memmap. This affects the watermark
 		 * and per-cpu initialisations
 		 */
-		memmap_pages =
-			PAGE_ALIGN(size * sizeof(struct page)) >> PAGE_SHIFT;
-		if (realsize >= memmap_pages) {
-			realsize -= memmap_pages;
+		memmap_pages = calc_memmap_size(size, realsize);
+		if (freesize >= memmap_pages) {
+			freesize -= memmap_pages;
 			if (memmap_pages)
 				printk(KERN_DEBUG
 				       "  %s zone: %lu pages used for memmap\n",
 				       zone_names[j], memmap_pages);
 		} else
 			printk(KERN_WARNING
-				"  %s zone: %lu pages exceeds realsize %lu\n",
-				zone_names[j], memmap_pages, realsize);
+				"  %s zone: %lu pages exceeds freesize %lu\n",
+				zone_names[j], memmap_pages, freesize);
 
 		/* Account for reserved pages */
-		if (j == 0 && realsize > dma_reserve) {
-			realsize -= dma_reserve;
+		if (j == 0 && freesize > dma_reserve) {
+			freesize -= dma_reserve;
 			printk(KERN_DEBUG "  %s zone: %lu pages reserved\n",
 					zone_names[0], dma_reserve);
 		}
 
 		if (!is_highmem_idx(j))
-			nr_kernel_pages += realsize;
-		nr_all_pages += realsize;
+			nr_kernel_pages += freesize;
+		/* Charge for highmem memmap if there are enough kernel pages */
+		else if (nr_kernel_pages > memmap_pages * 2)
+			nr_kernel_pages -= memmap_pages;
+		nr_all_pages += freesize;
 
 		zone->spanned_pages = size;
-		zone->present_pages = realsize;
+		zone->present_pages = freesize;
+		/*
+		 * Set an approximate value for lowmem here, it will be adjusted
+		 * when the bootmem allocator frees pages into the buddy system.
+		 * And all highmem pages will be managed by the buddy system.
+		 */
+		zone->managed_pages = is_highmem_idx(j) ? realsize : freesize;
 #ifdef CONFIG_NUMA
 		zone->node = nid;
-		zone->min_unmapped_pages = (realsize*sysctl_min_unmapped_ratio)
+		zone->min_unmapped_pages = (freesize*sysctl_min_unmapped_ratio)
 						/ 100;
-		zone->min_slab_pages = (realsize * sysctl_min_slab_ratio) / 100;
+		zone->min_slab_pages = (freesize * sysctl_min_slab_ratio) / 100;
 #endif
 		zone->name = zone_names[j];
 		spin_lock_init(&zone->lock);
@@ -4731,7 +4772,7 @@
 /*
  * early_calculate_totalpages()
  * Sum pages in active regions for movable zone.
- * Populate N_HIGH_MEMORY for calculating usable_nodes.
+ * Populate N_MEMORY for calculating usable_nodes.
  */
 static unsigned long __init early_calculate_totalpages(void)
 {
@@ -4744,7 +4785,7 @@
 
 		totalpages += pages;
 		if (pages)
-			node_set_state(nid, N_HIGH_MEMORY);
+			node_set_state(nid, N_MEMORY);
 	}
   	return totalpages;
 }
@@ -4761,9 +4802,9 @@
 	unsigned long usable_startpfn;
 	unsigned long kernelcore_node, kernelcore_remaining;
 	/* save the state before borrow the nodemask */
-	nodemask_t saved_node_state = node_states[N_HIGH_MEMORY];
+	nodemask_t saved_node_state = node_states[N_MEMORY];
 	unsigned long totalpages = early_calculate_totalpages();
-	int usable_nodes = nodes_weight(node_states[N_HIGH_MEMORY]);
+	int usable_nodes = nodes_weight(node_states[N_MEMORY]);
 
 	/*
 	 * If movablecore was specified, calculate what size of
@@ -4798,7 +4839,7 @@
 restart:
 	/* Spread kernelcore memory as evenly as possible throughout nodes */
 	kernelcore_node = required_kernelcore / usable_nodes;
-	for_each_node_state(nid, N_HIGH_MEMORY) {
+	for_each_node_state(nid, N_MEMORY) {
 		unsigned long start_pfn, end_pfn;
 
 		/*
@@ -4890,23 +4931,27 @@
 
 out:
 	/* restore the node_state */
-	node_states[N_HIGH_MEMORY] = saved_node_state;
+	node_states[N_MEMORY] = saved_node_state;
 }
 
-/* Any regular memory on that node ? */
-static void __init check_for_regular_memory(pg_data_t *pgdat)
+/* Any regular or high memory on that node ? */
+static void check_for_memory(pg_data_t *pgdat, int nid)
 {
-#ifdef CONFIG_HIGHMEM
 	enum zone_type zone_type;
 
-	for (zone_type = 0; zone_type <= ZONE_NORMAL; zone_type++) {
+	if (N_MEMORY == N_NORMAL_MEMORY)
+		return;
+
+	for (zone_type = 0; zone_type <= ZONE_MOVABLE - 1; zone_type++) {
 		struct zone *zone = &pgdat->node_zones[zone_type];
 		if (zone->present_pages) {
-			node_set_state(zone_to_nid(zone), N_NORMAL_MEMORY);
+			node_set_state(nid, N_HIGH_MEMORY);
+			if (N_NORMAL_MEMORY != N_HIGH_MEMORY &&
+			    zone_type <= ZONE_NORMAL)
+				node_set_state(nid, N_NORMAL_MEMORY);
 			break;
 		}
 	}
-#endif
 }
 
 /**
@@ -4989,8 +5034,8 @@
 
 		/* Any memory on that node */
 		if (pgdat->node_present_pages)
-			node_set_state(nid, N_HIGH_MEMORY);
-		check_for_regular_memory(pgdat);
+			node_set_state(nid, N_MEMORY);
+		check_for_memory(pgdat, nid);
 	}
 }
 
@@ -5727,7 +5772,7 @@
 	unsigned int tries = 0;
 	int ret = 0;
 
-	migrate_prep_local();
+	migrate_prep();
 
 	while (pfn < end || !list_empty(&cc->migratepages)) {
 		if (fatal_signal_pending(current)) {
diff --git a/mm/page_cgroup.c b/mm/page_cgroup.c
index 44db00e..6d757e3a 100644
--- a/mm/page_cgroup.c
+++ b/mm/page_cgroup.c
@@ -274,7 +274,7 @@
 	if (mem_cgroup_disabled())
 		return;
 
-	for_each_node_state(nid, N_HIGH_MEMORY) {
+	for_each_node_state(nid, N_MEMORY) {
 		unsigned long start_pfn, end_pfn;
 
 		start_pfn = node_start_pfn(nid);
diff --git a/mm/pagewalk.c b/mm/pagewalk.c
index 6c118d0..35aa294 100644
--- a/mm/pagewalk.c
+++ b/mm/pagewalk.c
@@ -58,7 +58,7 @@
 		if (!walk->pte_entry)
 			continue;
 
-		split_huge_page_pmd(walk->mm, pmd);
+		split_huge_page_pmd_mm(walk->mm, addr, pmd);
 		if (pmd_none_or_trans_huge_or_clear_bad(pmd))
 			goto again;
 		err = walk_pte_range(pmd, addr, next, walk);
diff --git a/mm/rmap.c b/mm/rmap.c
index cf7e99a..face808 100644
--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -1249,12 +1249,14 @@
 	update_hiwater_rss(mm);
 
 	if (PageHWPoison(page) && !(flags & TTU_IGNORE_HWPOISON)) {
-		if (PageAnon(page))
-			dec_mm_counter(mm, MM_ANONPAGES);
-		else
-			dec_mm_counter(mm, MM_FILEPAGES);
+		if (!PageHuge(page)) {
+			if (PageAnon(page))
+				dec_mm_counter(mm, MM_ANONPAGES);
+			else
+				dec_mm_counter(mm, MM_FILEPAGES);
+		}
 		set_pte_at(mm, address, pte,
-				swp_entry_to_pte(make_hwpoison_entry(page)));
+			   swp_entry_to_pte(make_hwpoison_entry(page)));
 	} else if (PageAnon(page)) {
 		swp_entry_t entry = { .val = page_private(page) };
 
diff --git a/mm/shmem.c b/mm/shmem.c
index 50c5b8f..03f9ba8 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -1715,6 +1715,96 @@
 	return error;
 }
 
+/*
+ * llseek SEEK_DATA or SEEK_HOLE through the radix_tree.
+ */
+static pgoff_t shmem_seek_hole_data(struct address_space *mapping,
+				    pgoff_t index, pgoff_t end, int origin)
+{
+	struct page *page;
+	struct pagevec pvec;
+	pgoff_t indices[PAGEVEC_SIZE];
+	bool done = false;
+	int i;
+
+	pagevec_init(&pvec, 0);
+	pvec.nr = 1;		/* start small: we may be there already */
+	while (!done) {
+		pvec.nr = shmem_find_get_pages_and_swap(mapping, index,
+					pvec.nr, pvec.pages, indices);
+		if (!pvec.nr) {
+			if (origin == SEEK_DATA)
+				index = end;
+			break;
+		}
+		for (i = 0; i < pvec.nr; i++, index++) {
+			if (index < indices[i]) {
+				if (origin == SEEK_HOLE) {
+					done = true;
+					break;
+				}
+				index = indices[i];
+			}
+			page = pvec.pages[i];
+			if (page && !radix_tree_exceptional_entry(page)) {
+				if (!PageUptodate(page))
+					page = NULL;
+			}
+			if (index >= end ||
+			    (page && origin == SEEK_DATA) ||
+			    (!page && origin == SEEK_HOLE)) {
+				done = true;
+				break;
+			}
+		}
+		shmem_deswap_pagevec(&pvec);
+		pagevec_release(&pvec);
+		pvec.nr = PAGEVEC_SIZE;
+		cond_resched();
+	}
+	return index;
+}
+
+static loff_t shmem_file_llseek(struct file *file, loff_t offset, int origin)
+{
+	struct address_space *mapping = file->f_mapping;
+	struct inode *inode = mapping->host;
+	pgoff_t start, end;
+	loff_t new_offset;
+
+	if (origin != SEEK_DATA && origin != SEEK_HOLE)
+		return generic_file_llseek_size(file, offset, origin,
+					MAX_LFS_FILESIZE, i_size_read(inode));
+	mutex_lock(&inode->i_mutex);
+	/* We're holding i_mutex so we can access i_size directly */
+
+	if (offset < 0)
+		offset = -EINVAL;
+	else if (offset >= inode->i_size)
+		offset = -ENXIO;
+	else {
+		start = offset >> PAGE_CACHE_SHIFT;
+		end = (inode->i_size + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
+		new_offset = shmem_seek_hole_data(mapping, start, end, origin);
+		new_offset <<= PAGE_CACHE_SHIFT;
+		if (new_offset > offset) {
+			if (new_offset < inode->i_size)
+				offset = new_offset;
+			else if (origin == SEEK_DATA)
+				offset = -ENXIO;
+			else
+				offset = inode->i_size;
+		}
+	}
+
+	if (offset >= 0 && offset != file->f_pos) {
+		file->f_pos = offset;
+		file->f_version = 0;
+	}
+	mutex_unlock(&inode->i_mutex);
+	return offset;
+}
+
 static long shmem_fallocate(struct file *file, int mode, loff_t offset,
 							 loff_t len)
 {
@@ -2586,7 +2676,7 @@
 static const struct file_operations shmem_file_operations = {
 	.mmap		= shmem_mmap,
 #ifdef CONFIG_TMPFS
-	.llseek		= generic_file_llseek,
+	.llseek		= shmem_file_llseek,
 	.read		= do_sync_read,
 	.write		= do_sync_write,
 	.aio_read	= shmem_file_aio_read,
diff --git a/mm/util.c b/mm/util.c
index dc3036c..c55e26b 100644
--- a/mm/util.c
+++ b/mm/util.c
@@ -152,7 +152,7 @@
  *
  * The contents of the object pointed to are preserved up to the
  * lesser of the new and old sizes.  If @p is %NULL, krealloc()
- * behaves exactly like kmalloc().  If @size is 0 and @p is not a
+ * behaves exactly like kmalloc().  If @new_size is 0 and @p is not a
  * %NULL pointer, the object pointed to is freed.
  */
 void *krealloc(const void *p, size_t new_size, gfp_t flags)
diff --git a/mm/vmscan.c b/mm/vmscan.c
index 157bb11..7f30961 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -3131,7 +3131,7 @@
 	int nid;
 
 	if (action == CPU_ONLINE || action == CPU_ONLINE_FROZEN) {
-		for_each_node_state(nid, N_HIGH_MEMORY) {
+		for_each_node_state(nid, N_MEMORY) {
 			pg_data_t *pgdat = NODE_DATA(nid);
 			const struct cpumask *mask;
 
@@ -3187,7 +3187,7 @@
 	int nid;
 
 	swap_setup();
-	for_each_node_state(nid, N_HIGH_MEMORY)
+	for_each_node_state(nid, N_MEMORY)
  		kswapd_run(nid);
 	hotcpu_notifier(cpu_callback, 0);
 	return 0;
diff --git a/mm/vmstat.c b/mm/vmstat.c
index c737057..df14808 100644
--- a/mm/vmstat.c
+++ b/mm/vmstat.c
@@ -801,6 +801,8 @@
 	"thp_collapse_alloc",
 	"thp_collapse_alloc_failed",
 	"thp_split",
+	"thp_zero_page_alloc",
+	"thp_zero_page_alloc_failed",
 #endif
 
 #endif /* CONFIG_VM_EVENTS_COUNTERS */
@@ -930,7 +932,7 @@
 	pg_data_t *pgdat = (pg_data_t *)arg;
 
 	/* check memoryless node */
-	if (!node_state(pgdat->node_id, N_HIGH_MEMORY))
+	if (!node_state(pgdat->node_id, N_MEMORY))
 		return 0;
 
 	seq_printf(m, "Page block order: %d\n", pageblock_order);
@@ -992,14 +994,16 @@
 		   "\n        high     %lu"
 		   "\n        scanned  %lu"
 		   "\n        spanned  %lu"
-		   "\n        present  %lu",
+		   "\n        present  %lu"
+		   "\n        managed  %lu",
 		   zone_page_state(zone, NR_FREE_PAGES),
 		   min_wmark_pages(zone),
 		   low_wmark_pages(zone),
 		   high_wmark_pages(zone),
 		   zone->pages_scanned,
 		   zone->spanned_pages,
-		   zone->present_pages);
+		   zone->present_pages,
+		   zone->managed_pages);
 
 	for (i = 0; i < NR_VM_ZONE_STAT_ITEMS; i++)
 		seq_printf(m, "\n    %-12s %lu", vmstat_text[i],
@@ -1292,7 +1296,7 @@
 	pg_data_t *pgdat = (pg_data_t *)arg;
 
 	/* check memoryless node */
-	if (!node_state(pgdat->node_id, N_HIGH_MEMORY))
+	if (!node_state(pgdat->node_id, N_MEMORY))
 		return 0;
 
 	walk_zones_in_node(m, pgdat, unusable_show_print);
diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c
index 0c00284..b2bcbe2 100644
--- a/net/bluetooth/hidp/core.c
+++ b/net/bluetooth/hidp/core.c
@@ -945,6 +945,13 @@
 	hid->hid_get_raw_report = hidp_get_raw_report;
 	hid->hid_output_raw_report = hidp_output_raw_report;
 
+	/* True if device is blacklisted in drivers/hid/hid-core.c */
+	if (hid_ignore(hid)) {
+		hid_destroy_device(session->hid);
+		session->hid = NULL;
+		return -ENODEV;
+	}
+
 	return 0;
 
 fault:
@@ -1017,7 +1024,7 @@
 
 	if (req->rd_size > 0) {
 		err = hidp_setup_hid(session, req);
-		if (err)
+		if (err && err != -ENODEV)
 			goto purge;
 	}
 
diff --git a/net/can/proc.c b/net/can/proc.c
index 3b6dd31..ae56690 100644
--- a/net/can/proc.c
+++ b/net/can/proc.c
@@ -397,7 +397,7 @@
 	int i;
 	int all_empty = 1;
 
-	/* check wether at least one list is non-empty */
+	/* check whether at least one list is non-empty */
 	for (i = 0; i < 0x800; i++)
 		if (!hlist_empty(&d->rx_sff[i])) {
 			all_empty = 0;
diff --git a/net/ipv4/tcp_cong.c b/net/ipv4/tcp_cong.c
index baf2861..291f2ed 100644
--- a/net/ipv4/tcp_cong.c
+++ b/net/ipv4/tcp_cong.c
@@ -1,7 +1,7 @@
 /*
  * Plugable TCP congestion control support and newReno
  * congestion control.
- * Based on ideas from I/O scheduler suport and Web100.
+ * Based on ideas from I/O scheduler support and Web100.
  *
  * Copyright (C) 2005 Stephen Hemminger <shemminger@osdl.org>
  */
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h
index c6560cc..698dc7e 100644
--- a/net/mac80211/driver-ops.h
+++ b/net/mac80211/driver-ops.h
@@ -634,7 +634,7 @@
 
 static inline int drv_tx_last_beacon(struct ieee80211_local *local)
 {
-	int ret = 0; /* default unsuported op for less congestion */
+	int ret = 0; /* default unsupported op for less congestion */
 
 	might_sleep();
 
diff --git a/net/netfilter/nf_log.c b/net/netfilter/nf_log.c
index 703fb26..9e31269 100644
--- a/net/netfilter/nf_log.c
+++ b/net/netfilter/nf_log.c
@@ -32,7 +32,7 @@
 	return NULL;
 }
 
-/* return EEXIST if the same logger is registred, 0 on success. */
+/* return EEXIST if the same logger is registered, 0 on success. */
 int nf_log_register(u_int8_t pf, struct nf_logger *logger)
 {
 	const struct nf_logger *llog;
diff --git a/net/rfkill/core.c b/net/rfkill/core.c
index a5c9527..9b9be52 100644
--- a/net/rfkill/core.c
+++ b/net/rfkill/core.c
@@ -676,7 +676,7 @@
 	rfkill_set_block(rfkill, state);
 	mutex_unlock(&rfkill_global_mutex);
 
-	return err ?: count;
+	return count;
 }
 
 static u8 user_state_from_blocked(unsigned long state)
@@ -721,7 +721,7 @@
 	rfkill_set_block(rfkill, state == RFKILL_USER_STATE_SOFT_BLOCKED);
 	mutex_unlock(&rfkill_global_mutex);
 
-	return err ?: count;
+	return count;
 }
 
 static ssize_t rfkill_claim_show(struct device *dev,
diff --git a/net/sctp/endpointola.c b/net/sctp/endpointola.c
index 32ab55b..17a001b 100644
--- a/net/sctp/endpointola.c
+++ b/net/sctp/endpointola.c
@@ -163,7 +163,7 @@
 
 	list_add(&null_key->key_list, &ep->endpoint_shared_keys);
 
-	/* Allocate and initialize transorms arrays for suported HMACs. */
+	/* Allocate and initialize transorms arrays for supported HMACs. */
 	err = sctp_auth_init_hmacs(ep, gfp);
 	if (err)
 		goto nomem_hmacs;
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
index ebcd1ee..618ec7e 100644
--- a/net/sctp/sm_statefuns.c
+++ b/net/sctp/sm_statefuns.c
@@ -4000,7 +4000,7 @@
 	chunk->subh.auth_hdr = auth_hdr;
 	skb_pull(chunk->skb, sizeof(struct sctp_authhdr));
 
-	/* Make sure that we suport the HMAC algorithm from the auth
+	/* Make sure that we support the HMAC algorithm from the auth
 	 * chunk.
 	 */
 	if (!sctp_auth_asoc_verify_hmac_id(asoc, auth_hdr->hmac_id))
diff --git a/scripts/kernel-doc b/scripts/kernel-doc
index 46e7aff..28b7615 100755
--- a/scripts/kernel-doc
+++ b/scripts/kernel-doc
@@ -137,6 +137,8 @@
 # should document the "Context:" of the function, e.g. whether the functions
 # can be called form interrupts. Unlike other sections you can end it with an
 # empty line.
+# A non-void function should have a "Return:" section describing the return
+# value(s).
 # Example-sections should contain the string EXAMPLE so that they are marked
 # appropriately in DocBook.
 #
@@ -315,6 +317,7 @@
 my $section_intro = "Introduction";
 my $section = $section_default;
 my $section_context = "Context";
+my $section_return = "Return";
 
 my $undescribed = "-- undescribed --";
 
@@ -2039,6 +2042,28 @@
 }
 
 ##
+# Checks the section describing the return value of a function.
+sub check_return_section {
+        my $file = shift;
+        my $declaration_name = shift;
+        my $return_type = shift;
+
+        # Ignore an empty return type (It's a macro)
+        # Ignore functions with a "void" return type. (But don't ignore "void *")
+        if (($return_type eq "") || ($return_type =~ /void\s*\w*\s*$/)) {
+                return;
+        }
+
+        if (!defined($sections{$section_return}) ||
+            $sections{$section_return} eq "") {
+                print STDERR "Warning(${file}:$.): " .
+                        "No description found for return value of " .
+                        "'$declaration_name'\n";
+                ++$warnings;
+        }
+}
+
+##
 # takes a function prototype and the name of the current file being
 # processed and spits out all the details stored in the global
 # arrays/hashes.
@@ -2109,6 +2134,15 @@
 	my $prms = join " ", @parameterlist;
 	check_sections($file, $declaration_name, "function", $sectcheck, $prms, "");
 
+        # This check emits a lot of warnings at the moment, because many
+        # functions don't have a 'Return' doc section. So until the number
+        # of warnings goes sufficiently down, the check is only performed in
+        # verbose mode.
+        # TODO: always perform the check.
+        if ($verbose) {
+                check_return_section($file, $declaration_name, $return_type);
+        }
+
     output_declaration($declaration_name,
 		       'function',
 		       {'function' => $declaration_name,
diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c
index a58f712..86468f3 100644
--- a/security/keys/process_keys.c
+++ b/security/keys/process_keys.c
@@ -358,8 +358,6 @@
 
 		switch (PTR_ERR(key_ref)) {
 		case -EAGAIN: /* no key */
-			if (ret)
-				break;
 		case -ENOKEY: /* negative key */
 			ret = key_ref;
 			break;
diff --git a/sound/arm/aaci.c b/sound/arm/aaci.c
index 5119fda..aa5d803 100644
--- a/sound/arm/aaci.c
+++ b/sound/arm/aaci.c
@@ -786,7 +786,7 @@
 #endif
 
 
-static struct ac97_pcm ac97_defs[] __devinitdata = {
+static struct ac97_pcm ac97_defs[] = {
 	[0] = {	/* Front PCM */
 		.exclusive = 1,
 		.r = {
@@ -832,7 +832,7 @@
 	.read	= aaci_ac97_read,
 };
 
-static int __devinit aaci_probe_ac97(struct aaci *aaci)
+static int aaci_probe_ac97(struct aaci *aaci)
 {
 	struct snd_ac97_template ac97_template;
 	struct snd_ac97_bus *ac97_bus;
@@ -893,7 +893,7 @@
 		iounmap(aaci->base);
 }
 
-static struct aaci * __devinit aaci_init_card(struct amba_device *dev)
+static struct aaci *aaci_init_card(struct amba_device *dev)
 {
 	struct aaci *aaci;
 	struct snd_card *card;
@@ -926,7 +926,7 @@
 	return aaci;
 }
 
-static int __devinit aaci_init_pcm(struct aaci *aaci)
+static int aaci_init_pcm(struct aaci *aaci)
 {
 	struct snd_pcm *pcm;
 	int ret;
@@ -948,7 +948,7 @@
 	return ret;
 }
 
-static unsigned int __devinit aaci_size_fifo(struct aaci *aaci)
+static unsigned int aaci_size_fifo(struct aaci *aaci)
 {
 	struct aaci_runtime *aacirun = &aaci->playback;
 	int i;
@@ -984,8 +984,8 @@
 	return i;
 }
 
-static int __devinit aaci_probe(struct amba_device *dev,
-	const struct amba_id *id)
+static int aaci_probe(struct amba_device *dev,
+		      const struct amba_id *id)
 {
 	struct aaci *aaci;
 	int ret, i;
@@ -1072,7 +1072,7 @@
 	return ret;
 }
 
-static int __devexit aaci_remove(struct amba_device *dev)
+static int aaci_remove(struct amba_device *dev)
 {
 	struct snd_card *card = amba_get_drvdata(dev);
 
@@ -1104,7 +1104,7 @@
 		.name	= DRIVER_NAME,
 	},
 	.probe		= aaci_probe,
-	.remove		= __devexit_p(aaci_remove),
+	.remove		= aaci_remove,
 	.suspend	= aaci_suspend,
 	.resume		= aaci_resume,
 	.id_table	= aaci_ids,
diff --git a/sound/arm/pxa2xx-ac97-lib.c b/sound/arm/pxa2xx-ac97-lib.c
index 48d7c0a..6fc0ae9 100644
--- a/sound/arm/pxa2xx-ac97-lib.c
+++ b/sound/arm/pxa2xx-ac97-lib.c
@@ -314,7 +314,7 @@
 EXPORT_SYMBOL_GPL(pxa2xx_ac97_hw_resume);
 #endif
 
-int __devinit pxa2xx_ac97_hw_probe(struct platform_device *dev)
+int pxa2xx_ac97_hw_probe(struct platform_device *dev)
 {
 	int ret;
 	pxa2xx_audio_ops_t *pdata = dev->dev.platform_data;
diff --git a/sound/arm/pxa2xx-ac97.c b/sound/arm/pxa2xx-ac97.c
index 4e1fda7..ec54be4 100644
--- a/sound/arm/pxa2xx-ac97.c
+++ b/sound/arm/pxa2xx-ac97.c
@@ -163,7 +163,7 @@
 static SIMPLE_DEV_PM_OPS(pxa2xx_ac97_pm_ops, pxa2xx_ac97_suspend, pxa2xx_ac97_resume);
 #endif
 
-static int __devinit pxa2xx_ac97_probe(struct platform_device *dev)
+static int pxa2xx_ac97_probe(struct platform_device *dev)
 {
 	struct snd_card *card;
 	struct snd_ac97_bus *ac97_bus;
@@ -224,7 +224,7 @@
 	return ret;
 }
 
-static int __devexit pxa2xx_ac97_remove(struct platform_device *dev)
+static int pxa2xx_ac97_remove(struct platform_device *dev)
 {
 	struct snd_card *card = platform_get_drvdata(dev);
 
@@ -239,7 +239,7 @@
 
 static struct platform_driver pxa2xx_ac97_driver = {
 	.probe		= pxa2xx_ac97_probe,
-	.remove		= __devexit_p(pxa2xx_ac97_remove),
+	.remove		= pxa2xx_ac97_remove,
 	.driver		= {
 		.name	= "pxa2xx-ac97",
 		.owner	= THIS_MODULE,
diff --git a/sound/atmel/abdac.c b/sound/atmel/abdac.c
index 277ebce..071ce1b 100644
--- a/sound/atmel/abdac.c
+++ b/sound/atmel/abdac.c
@@ -309,7 +309,7 @@
 	.pointer	= atmel_abdac_pointer,
 };
 
-static int __devinit atmel_abdac_pcm_new(struct atmel_abdac *dac)
+static int atmel_abdac_pcm_new(struct atmel_abdac *dac)
 {
 	struct snd_pcm_hardware hw = atmel_abdac_hw;
 	struct snd_pcm *pcm;
@@ -386,7 +386,7 @@
 	return retval;
 }
 
-static int __devinit atmel_abdac_probe(struct platform_device *pdev)
+static int atmel_abdac_probe(struct platform_device *pdev)
 {
 	struct snd_card		*card;
 	struct atmel_abdac	*dac;
@@ -567,7 +567,7 @@
 #define ATMEL_ABDAC_PM_OPS	NULL
 #endif
 
-static int __devexit atmel_abdac_remove(struct platform_device *pdev)
+static int atmel_abdac_remove(struct platform_device *pdev)
 {
 	struct snd_card *card = platform_get_drvdata(pdev);
 	struct atmel_abdac *dac = get_dac(card);
@@ -589,7 +589,7 @@
 }
 
 static struct platform_driver atmel_abdac_driver = {
-	.remove		= __devexit_p(atmel_abdac_remove),
+	.remove		= atmel_abdac_remove,
 	.driver		= {
 		.name	= "atmel_abdac",
 		.owner	= THIS_MODULE,
diff --git a/sound/atmel/ac97c.c b/sound/atmel/ac97c.c
index 9052aff..79d6bda 100644
--- a/sound/atmel/ac97c.c
+++ b/sound/atmel/ac97c.c
@@ -728,7 +728,7 @@
 	return retval;
 }
 
-static struct ac97_pcm at91_ac97_pcm_defs[] __devinitdata = {
+static struct ac97_pcm at91_ac97_pcm_defs[] = {
 	/* Playback */
 	{
 		.exclusive = 1,
@@ -756,7 +756,7 @@
 	},
 };
 
-static int __devinit atmel_ac97c_pcm_new(struct atmel_ac97c *chip)
+static int atmel_ac97c_pcm_new(struct atmel_ac97c *chip)
 {
 	struct snd_pcm		*pcm;
 	struct snd_pcm_hardware	hw = atmel_ac97c_hw;
@@ -902,7 +902,7 @@
 	}
 }
 
-static int __devinit atmel_ac97c_probe(struct platform_device *pdev)
+static int atmel_ac97c_probe(struct platform_device *pdev)
 {
 	struct snd_card			*card;
 	struct atmel_ac97c		*chip;
@@ -1168,7 +1168,7 @@
 #define ATMEL_AC97C_PM_OPS	NULL
 #endif
 
-static int __devexit atmel_ac97c_remove(struct platform_device *pdev)
+static int atmel_ac97c_remove(struct platform_device *pdev)
 {
 	struct snd_card *card = platform_get_drvdata(pdev);
 	struct atmel_ac97c *chip = get_chip(card);
@@ -1205,7 +1205,7 @@
 }
 
 static struct platform_driver atmel_ac97c_driver = {
-	.remove		= __devexit_p(atmel_ac97c_remove),
+	.remove		= atmel_ac97c_remove,
 	.driver		= {
 		.name	= "atmel_ac97c",
 		.owner	= THIS_MODULE,
diff --git a/sound/core/oss/pcm_plugin.c b/sound/core/oss/pcm_plugin.c
index 71cc3dd..727ac44 100644
--- a/sound/core/oss/pcm_plugin.c
+++ b/sound/core/oss/pcm_plugin.c
@@ -199,12 +199,13 @@
 snd_pcm_sframes_t snd_pcm_plug_client_size(struct snd_pcm_substream *plug, snd_pcm_uframes_t drv_frames)
 {
 	struct snd_pcm_plugin *plugin, *plugin_prev, *plugin_next;
-	int stream = snd_pcm_plug_stream(plug);
+	int stream;
 
 	if (snd_BUG_ON(!plug))
 		return -ENXIO;
 	if (drv_frames == 0)
 		return 0;
+	stream = snd_pcm_plug_stream(plug);
 	if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
 		plugin = snd_pcm_plug_last(plug);
 		while (plugin && drv_frames > 0) {
@@ -230,13 +231,14 @@
 {
 	struct snd_pcm_plugin *plugin, *plugin_prev, *plugin_next;
 	snd_pcm_sframes_t frames;
-	int stream = snd_pcm_plug_stream(plug);
+	int stream;
 	
 	if (snd_BUG_ON(!plug))
 		return -ENXIO;
 	if (clt_frames == 0)
 		return 0;
 	frames = clt_frames;
+	stream = snd_pcm_plug_stream(plug);
 	if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
 		plugin = snd_pcm_plug_first(plug);
 		while (plugin && frames > 0) {
diff --git a/sound/core/pcm.c b/sound/core/pcm.c
index 030102c..61798f8 100644
--- a/sound/core/pcm.c
+++ b/sound/core/pcm.c
@@ -981,8 +981,7 @@
 		       PAGE_ALIGN(sizeof(struct snd_pcm_mmap_control)));
 	kfree(runtime->hw_constraints.rules);
 #ifdef CONFIG_SND_PCM_XRUN_DEBUG
-	if (runtime->hwptr_log)
-		kfree(runtime->hwptr_log);
+	kfree(runtime->hwptr_log);
 #endif
 	kfree(runtime);
 	substream->runtime = NULL;
diff --git a/sound/core/pcm_compat.c b/sound/core/pcm_compat.c
index 91cdf94..af49721 100644
--- a/sound/core/pcm_compat.c
+++ b/sound/core/pcm_compat.c
@@ -190,7 +190,9 @@
 	u32 avail_max;
 	u32 overrange;
 	s32 suspended_state;
-	unsigned char reserved[60];
+	u32 reserved_alignment;
+	struct compat_timespec audio_tstamp;
+	unsigned char reserved[56-sizeof(struct compat_timespec)];
 } __attribute__((packed));
 
 
@@ -205,17 +207,16 @@
 		return err;
 
 	if (put_user(status.state, &src->state) ||
-	    put_user(status.trigger_tstamp.tv_sec, &src->trigger_tstamp.tv_sec) ||
-	    put_user(status.trigger_tstamp.tv_nsec, &src->trigger_tstamp.tv_nsec) ||
-	    put_user(status.tstamp.tv_sec, &src->tstamp.tv_sec) ||
-	    put_user(status.tstamp.tv_nsec, &src->tstamp.tv_nsec) ||
+	    compat_put_timespec(&status.trigger_tstamp, &src->trigger_tstamp) ||
+	    compat_put_timespec(&status.tstamp, &src->tstamp) ||
 	    put_user(status.appl_ptr, &src->appl_ptr) ||
 	    put_user(status.hw_ptr, &src->hw_ptr) ||
 	    put_user(status.delay, &src->delay) ||
 	    put_user(status.avail, &src->avail) ||
 	    put_user(status.avail_max, &src->avail_max) ||
 	    put_user(status.overrange, &src->overrange) ||
-	    put_user(status.suspended_state, &src->suspended_state))
+	    put_user(status.suspended_state, &src->suspended_state) ||
+	    compat_put_timespec(&status.audio_tstamp, &src->audio_tstamp))
 		return -EFAULT;
 
 	return err;
@@ -364,6 +365,7 @@
 	u32 hw_ptr;
 	struct compat_timespec tstamp;
 	s32 suspended_state;
+	struct compat_timespec audio_tstamp;
 } __attribute__((packed));
 
 struct snd_pcm_mmap_control32 {
@@ -426,12 +428,14 @@
 	sstatus.hw_ptr = status->hw_ptr % boundary;
 	sstatus.tstamp = status->tstamp;
 	sstatus.suspended_state = status->suspended_state;
+	sstatus.audio_tstamp = status->audio_tstamp;
 	snd_pcm_stream_unlock_irq(substream);
 	if (put_user(sstatus.state, &src->s.status.state) ||
 	    put_user(sstatus.hw_ptr, &src->s.status.hw_ptr) ||
-	    put_user(sstatus.tstamp.tv_sec, &src->s.status.tstamp.tv_sec) ||
-	    put_user(sstatus.tstamp.tv_nsec, &src->s.status.tstamp.tv_nsec) ||
+	    compat_put_timespec(&sstatus.tstamp, &src->s.status.tstamp) ||
 	    put_user(sstatus.suspended_state, &src->s.status.suspended_state) ||
+	    compat_put_timespec(&sstatus.audio_tstamp,
+		    &src->s.status.audio_tstamp) ||
 	    put_user(scontrol.appl_ptr, &src->c.control.appl_ptr) ||
 	    put_user(scontrol.avail_min, &src->c.control.avail_min))
 		return -EFAULT;
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c
index f42c10a..c4840ff 100644
--- a/sound/core/pcm_lib.c
+++ b/sound/core/pcm_lib.c
@@ -316,6 +316,8 @@
 	unsigned long jdelta;
 	unsigned long curr_jiffies;
 	struct timespec curr_tstamp;
+	struct timespec audio_tstamp;
+	int crossed_boundary = 0;
 
 	old_hw_ptr = runtime->status->hw_ptr;
 
@@ -327,9 +329,14 @@
 	 */
 	pos = substream->ops->pointer(substream);
 	curr_jiffies = jiffies;
-	if (runtime->tstamp_mode == SNDRV_PCM_TSTAMP_ENABLE)
+	if (runtime->tstamp_mode == SNDRV_PCM_TSTAMP_ENABLE) {
 		snd_pcm_gettime(runtime, (struct timespec *)&curr_tstamp);
 
+		if ((runtime->hw.info & SNDRV_PCM_INFO_HAS_WALL_CLOCK) &&
+			(substream->ops->wall_clock))
+			substream->ops->wall_clock(substream, &audio_tstamp);
+	}
+
 	if (pos == SNDRV_PCM_POS_XRUN) {
 		xrun(substream);
 		return -EPIPE;
@@ -360,8 +367,10 @@
 			hdelta = curr_jiffies - runtime->hw_ptr_jiffies;
 			if (hdelta > runtime->hw_ptr_buffer_jiffies/2) {
 				hw_base += runtime->buffer_size;
-				if (hw_base >= runtime->boundary)
+				if (hw_base >= runtime->boundary) {
 					hw_base = 0;
+					crossed_boundary++;
+				}
 				new_hw_ptr = hw_base + pos;
 				goto __delta;
 			}
@@ -371,8 +380,10 @@
 	/* pointer crosses the end of the ring buffer */
 	if (new_hw_ptr < old_hw_ptr) {
 		hw_base += runtime->buffer_size;
-		if (hw_base >= runtime->boundary)
+		if (hw_base >= runtime->boundary) {
 			hw_base = 0;
+			crossed_boundary++;
+		}
 		new_hw_ptr = hw_base + pos;
 	}
       __delta:
@@ -410,8 +421,10 @@
 		while (hdelta > xrun_threshold) {
 			delta += runtime->buffer_size;
 			hw_base += runtime->buffer_size;
-			if (hw_base >= runtime->boundary)
+			if (hw_base >= runtime->boundary) {
 				hw_base = 0;
+				crossed_boundary++;
+			}
 			new_hw_ptr = hw_base + pos;
 			hdelta -= runtime->hw_ptr_buffer_jiffies;
 		}
@@ -456,8 +469,10 @@
 		/* the delta value is small or zero in most cases */
 		while (delta > 0) {
 			new_hw_ptr += runtime->period_size;
-			if (new_hw_ptr >= runtime->boundary)
+			if (new_hw_ptr >= runtime->boundary) {
 				new_hw_ptr -= runtime->boundary;
+				crossed_boundary--;
+			}
 			delta--;
 		}
 		/* align hw_base to buffer_size */
@@ -507,9 +522,35 @@
 	runtime->hw_ptr_base = hw_base;
 	runtime->status->hw_ptr = new_hw_ptr;
 	runtime->hw_ptr_jiffies = curr_jiffies;
-	if (runtime->tstamp_mode == SNDRV_PCM_TSTAMP_ENABLE)
+	if (crossed_boundary) {
+		snd_BUG_ON(crossed_boundary != 1);
+		runtime->hw_ptr_wrap += runtime->boundary;
+	}
+	if (runtime->tstamp_mode == SNDRV_PCM_TSTAMP_ENABLE) {
 		runtime->status->tstamp = curr_tstamp;
 
+		if (!(runtime->hw.info & SNDRV_PCM_INFO_HAS_WALL_CLOCK)) {
+			/*
+			 * no wall clock available, provide audio timestamp
+			 * derived from pointer position+delay
+			 */
+			u64 audio_frames, audio_nsecs;
+
+			if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+				audio_frames = runtime->hw_ptr_wrap
+					+ runtime->status->hw_ptr
+					- runtime->delay;
+			else
+				audio_frames = runtime->hw_ptr_wrap
+					+ runtime->status->hw_ptr
+					+ runtime->delay;
+			audio_nsecs = div_u64(audio_frames * 1000000000LL,
+					runtime->rate);
+			audio_tstamp = ns_to_timespec(audio_nsecs);
+		}
+		runtime->status->audio_tstamp = audio_tstamp;
+	}
+
 	return snd_pcm_update_state(substream, runtime);
 }
 
@@ -1661,8 +1702,10 @@
 	if (snd_pcm_running(substream) &&
 	    snd_pcm_update_hw_ptr(substream) >= 0)
 		runtime->status->hw_ptr %= runtime->buffer_size;
-	else
+	else {
 		runtime->status->hw_ptr = 0;
+		runtime->hw_ptr_wrap = 0;
+	}
 	snd_pcm_stream_unlock_irqrestore(substream, flags);
 	return 0;
 }
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index f9ddecf..09b4286 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -602,6 +602,8 @@
 		snd_pcm_update_hw_ptr(substream);
 		if (runtime->tstamp_mode == SNDRV_PCM_TSTAMP_ENABLE) {
 			status->tstamp = runtime->status->tstamp;
+			status->audio_tstamp =
+				runtime->status->audio_tstamp;
 			goto _tstamp_end;
 		}
 	}
@@ -1998,7 +2000,7 @@
 	if (runtime->dma_bytes) {
 		err = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 0, runtime->dma_bytes);
 		if (err < 0)
-			return -EINVAL;
+			return err;
 	}
 
 	if (!(hw->rates & (SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_CONTINUOUS))) {
diff --git a/sound/core/seq/seq_device.c b/sound/core/seq/seq_device.c
index 60e8fc1..040c60e 100644
--- a/sound/core/seq/seq_device.c
+++ b/sound/core/seq/seq_device.c
@@ -66,7 +66,7 @@
 	/* operators */
 	struct snd_seq_dev_ops ops;
 
-	/* registred devices */
+	/* registered devices */
 	struct list_head dev_list;	/* list of devices */
 	int num_devices;	/* number of associated devices */
 	int num_init_devices;	/* number of initialized devices */
diff --git a/sound/drivers/Kconfig b/sound/drivers/Kconfig
index fe5ae09..7d02c32 100644
--- a/sound/drivers/Kconfig
+++ b/sound/drivers/Kconfig
@@ -14,6 +14,7 @@
 
 config SND_VX_LIB
 	tristate
+	select FW_LOADER
 	select SND_HWDEP
 	select SND_PCM
 
@@ -35,7 +36,6 @@
 	tristate "PC-Speaker support (READ HELP!)"
 	depends on PCSPKR_PLATFORM && X86 && HIGH_RES_TIMERS
 	depends on INPUT
-	depends on EXPERIMENTAL
 	select SND_PCM
 	help
 	  If you don't have a sound card in your computer, you can include a
diff --git a/sound/drivers/aloop.c b/sound/drivers/aloop.c
index 0fe6d64..3d82232 100644
--- a/sound/drivers/aloop.c
+++ b/sound/drivers/aloop.c
@@ -120,7 +120,6 @@
 	unsigned int last_drift;
 	unsigned long last_jiffies;
 	struct timer_list timer;
-	spinlock_t timer_lock;
 };
 
 static struct platform_device *devices[SNDRV_CARDS];
@@ -166,12 +165,12 @@
 	return get_setup(dpcm)->rate_shift;
 }
 
+/* call in cable->lock */
 static void loopback_timer_start(struct loopback_pcm *dpcm)
 {
 	unsigned long tick;
 	unsigned int rate_shift = get_rate_shift(dpcm);
 
-	spin_lock(&dpcm->timer_lock);
 	if (rate_shift != dpcm->pcm_rate_shift) {
 		dpcm->pcm_rate_shift = rate_shift;
 		dpcm->period_size_frac = frac_pos(dpcm, dpcm->pcm_period_size);
@@ -184,15 +183,13 @@
 	tick = (tick + dpcm->pcm_bps - 1) / dpcm->pcm_bps;
 	dpcm->timer.expires = jiffies + tick;
 	add_timer(&dpcm->timer);
-	spin_unlock(&dpcm->timer_lock);
 }
 
+/* call in cable->lock */
 static inline void loopback_timer_stop(struct loopback_pcm *dpcm)
 {
-	spin_lock(&dpcm->timer_lock);
 	del_timer(&dpcm->timer);
 	dpcm->timer.expires = 0;
-	spin_unlock(&dpcm->timer_lock);
 }
 
 #define CABLE_VALID_PLAYBACK	(1 << SNDRV_PCM_STREAM_PLAYBACK)
@@ -274,8 +271,8 @@
 		spin_lock(&cable->lock);	
 		cable->running |= stream;
 		cable->pause &= ~stream;
-		spin_unlock(&cable->lock);
 		loopback_timer_start(dpcm);
+		spin_unlock(&cable->lock);
 		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
 			loopback_active_notify(dpcm);
 		break;
@@ -283,23 +280,23 @@
 		spin_lock(&cable->lock);	
 		cable->running &= ~stream;
 		cable->pause &= ~stream;
-		spin_unlock(&cable->lock);
 		loopback_timer_stop(dpcm);
+		spin_unlock(&cable->lock);
 		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
 			loopback_active_notify(dpcm);
 		break;
 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
 		spin_lock(&cable->lock);	
 		cable->pause |= stream;
-		spin_unlock(&cable->lock);
 		loopback_timer_stop(dpcm);
+		spin_unlock(&cable->lock);
 		break;
 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
 		spin_lock(&cable->lock);
 		dpcm->last_jiffies = jiffies;
 		cable->pause &= ~stream;
-		spin_unlock(&cable->lock);
 		loopback_timer_start(dpcm);
+		spin_unlock(&cable->lock);
 		break;
 	default:
 		return -EINVAL;
@@ -477,6 +474,7 @@
 	dpcm->buf_pos %= dpcm->pcm_buffer_size;
 }
 
+/* call in cable->lock */
 static unsigned int loopback_pos_update(struct loopback_cable *cable)
 {
 	struct loopback_pcm *dpcm_play =
@@ -485,9 +483,7 @@
 			cable->streams[SNDRV_PCM_STREAM_CAPTURE];
 	unsigned long delta_play = 0, delta_capt = 0;
 	unsigned int running, count1, count2;
-	unsigned long flags;
 
-	spin_lock_irqsave(&cable->lock, flags);
 	running = cable->running ^ cable->pause;
 	if (running & (1 << SNDRV_PCM_STREAM_PLAYBACK)) {
 		delta_play = jiffies - dpcm_play->last_jiffies;
@@ -529,32 +525,39 @@
 	bytepos_finish(dpcm_play, count1);
 	bytepos_finish(dpcm_capt, count1);
  unlock:
-	spin_unlock_irqrestore(&cable->lock, flags);
 	return running;
 }
 
 static void loopback_timer_function(unsigned long data)
 {
 	struct loopback_pcm *dpcm = (struct loopback_pcm *)data;
-	unsigned int running;
+	unsigned long flags;
 
-	running = loopback_pos_update(dpcm->cable);
-	if (running & (1 << dpcm->substream->stream)) {
+	spin_lock_irqsave(&dpcm->cable->lock, flags);
+	if (loopback_pos_update(dpcm->cable) & (1 << dpcm->substream->stream)) {
 		loopback_timer_start(dpcm);
 		if (dpcm->period_update_pending) {
 			dpcm->period_update_pending = 0;
+			spin_unlock_irqrestore(&dpcm->cable->lock, flags);
+			/* need to unlock before calling below */
 			snd_pcm_period_elapsed(dpcm->substream);
+			return;
 		}
 	}
+	spin_unlock_irqrestore(&dpcm->cable->lock, flags);
 }
 
 static snd_pcm_uframes_t loopback_pointer(struct snd_pcm_substream *substream)
 {
 	struct snd_pcm_runtime *runtime = substream->runtime;
 	struct loopback_pcm *dpcm = runtime->private_data;
+	snd_pcm_uframes_t pos;
 
+	spin_lock(&dpcm->cable->lock);
 	loopback_pos_update(dpcm->cable);
-	return bytes_to_frames(runtime, dpcm->buf_pos);
+	pos = dpcm->buf_pos;
+	spin_unlock(&dpcm->cable->lock);
+	return bytes_to_frames(runtime, pos);
 }
 
 static struct snd_pcm_hardware loopback_pcm_hardware =
@@ -672,7 +675,6 @@
 	dpcm->substream = substream;
 	setup_timer(&dpcm->timer, loopback_timer_function,
 		    (unsigned long)dpcm);
-	spin_lock_init(&dpcm->timer_lock);
 
 	cable = loopback->cables[substream->number][dev];
 	if (!cable) {
@@ -772,8 +774,8 @@
 	.mmap =		snd_pcm_lib_mmap_vmalloc,
 };
 
-static int __devinit loopback_pcm_new(struct loopback *loopback,
-				      int device, int substreams)
+static int loopback_pcm_new(struct loopback *loopback,
+			    int device, int substreams)
 {
 	struct snd_pcm *pcm;
 	int err;
@@ -947,7 +949,7 @@
 	return 0;
 }
 
-static struct snd_kcontrol_new loopback_controls[]  __devinitdata = {
+static struct snd_kcontrol_new loopback_controls[]  = {
 {
 	.iface =        SNDRV_CTL_ELEM_IFACE_PCM,
 	.name =         "PCM Rate Shift 100000",
@@ -996,7 +998,7 @@
 }
 };
 
-static int __devinit loopback_mixer_new(struct loopback *loopback, int notify)
+static int loopback_mixer_new(struct loopback *loopback, int notify)
 {
 	struct snd_card *card = loopback->card;
 	struct snd_pcm *pcm;
@@ -1109,7 +1111,7 @@
 	mutex_unlock(&loopback->cable_lock);
 }
 
-static int __devinit loopback_proc_new(struct loopback *loopback, int cidx)
+static int loopback_proc_new(struct loopback *loopback, int cidx)
 {
 	char name[32];
 	struct snd_info_entry *entry;
@@ -1130,7 +1132,7 @@
 
 #endif
 
-static int __devinit loopback_probe(struct platform_device *devptr)
+static int loopback_probe(struct platform_device *devptr)
 {
 	struct snd_card *card;
 	struct loopback *loopback;
@@ -1175,7 +1177,7 @@
 	return err;
 }
 
-static int __devexit loopback_remove(struct platform_device *devptr)
+static int loopback_remove(struct platform_device *devptr)
 {
 	snd_card_free(platform_get_drvdata(devptr));
 	platform_set_drvdata(devptr, NULL);
@@ -1213,7 +1215,7 @@
 
 static struct platform_driver loopback_driver = {
 	.probe		= loopback_probe,
-	.remove		= __devexit_p(loopback_remove),
+	.remove		= loopback_remove,
 	.driver		= {
 		.name	= SND_LOOPBACK_DRIVER,
 		.owner	= THIS_MODULE,
diff --git a/sound/drivers/dummy.c b/sound/drivers/dummy.c
index 54bb664..fd798f7 100644
--- a/sound/drivers/dummy.c
+++ b/sound/drivers/dummy.c
@@ -134,6 +134,9 @@
 	spinlock_t mixer_lock;
 	int mixer_volume[MIXER_ADDR_LAST+1][2];
 	int capture_source[MIXER_ADDR_LAST+1][2];
+	int iobox;
+	struct snd_kcontrol *cd_volume_ctl;
+	struct snd_kcontrol *cd_switch_ctl;
 	const struct dummy_timer_ops *timer_ops;
 };
 
@@ -685,8 +688,8 @@
 	.page =		dummy_pcm_page,
 };
 
-static int __devinit snd_card_dummy_pcm(struct snd_dummy *dummy, int device,
-					int substreams)
+static int snd_card_dummy_pcm(struct snd_dummy *dummy, int device,
+			      int substreams)
 {
 	struct snd_pcm *pcm;
 	struct snd_pcm_ops *ops;
@@ -817,6 +820,57 @@
 	return change;
 }
 
+static int snd_dummy_iobox_info(struct snd_kcontrol *kcontrol,
+				struct snd_ctl_elem_info *info)
+{
+	const char *const names[] = { "None", "CD Player" };
+
+	return snd_ctl_enum_info(info, 1, 2, names);
+}
+
+static int snd_dummy_iobox_get(struct snd_kcontrol *kcontrol,
+			       struct snd_ctl_elem_value *value)
+{
+	struct snd_dummy *dummy = snd_kcontrol_chip(kcontrol);
+
+	value->value.enumerated.item[0] = dummy->iobox;
+	return 0;
+}
+
+static int snd_dummy_iobox_put(struct snd_kcontrol *kcontrol,
+			       struct snd_ctl_elem_value *value)
+{
+	struct snd_dummy *dummy = snd_kcontrol_chip(kcontrol);
+	int changed;
+
+	if (value->value.enumerated.item[0] > 1)
+		return -EINVAL;
+
+	changed = value->value.enumerated.item[0] != dummy->iobox;
+	if (changed) {
+		dummy->iobox = value->value.enumerated.item[0];
+
+		if (dummy->iobox) {
+			dummy->cd_volume_ctl->vd[0].access &=
+				~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
+			dummy->cd_switch_ctl->vd[0].access &=
+				~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
+		} else {
+			dummy->cd_volume_ctl->vd[0].access |=
+				SNDRV_CTL_ELEM_ACCESS_INACTIVE;
+			dummy->cd_switch_ctl->vd[0].access |=
+				SNDRV_CTL_ELEM_ACCESS_INACTIVE;
+		}
+
+		snd_ctl_notify(dummy->card, SNDRV_CTL_EVENT_MASK_INFO,
+			       &dummy->cd_volume_ctl->id);
+		snd_ctl_notify(dummy->card, SNDRV_CTL_EVENT_MASK_INFO,
+			       &dummy->cd_switch_ctl->id);
+	}
+
+	return changed;
+}
+
 static struct snd_kcontrol_new snd_dummy_controls[] = {
 DUMMY_VOLUME("Master Volume", 0, MIXER_ADDR_MASTER),
 DUMMY_CAPSRC("Master Capture Switch", 0, MIXER_ADDR_MASTER),
@@ -827,22 +881,37 @@
 DUMMY_VOLUME("Mic Volume", 0, MIXER_ADDR_MIC),
 DUMMY_CAPSRC("Mic Capture Switch", 0, MIXER_ADDR_MIC),
 DUMMY_VOLUME("CD Volume", 0, MIXER_ADDR_CD),
-DUMMY_CAPSRC("CD Capture Switch", 0, MIXER_ADDR_CD)
+DUMMY_CAPSRC("CD Capture Switch", 0, MIXER_ADDR_CD),
+{
+	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+	.name  = "External I/O Box",
+	.info  = snd_dummy_iobox_info,
+	.get   = snd_dummy_iobox_get,
+	.put   = snd_dummy_iobox_put,
+},
 };
 
-static int __devinit snd_card_dummy_new_mixer(struct snd_dummy *dummy)
+static int snd_card_dummy_new_mixer(struct snd_dummy *dummy)
 {
 	struct snd_card *card = dummy->card;
+	struct snd_kcontrol *kcontrol;
 	unsigned int idx;
 	int err;
 
 	spin_lock_init(&dummy->mixer_lock);
 	strcpy(card->mixername, "Dummy Mixer");
+	dummy->iobox = 1;
 
 	for (idx = 0; idx < ARRAY_SIZE(snd_dummy_controls); idx++) {
-		err = snd_ctl_add(card, snd_ctl_new1(&snd_dummy_controls[idx], dummy));
+		kcontrol = snd_ctl_new1(&snd_dummy_controls[idx], dummy);
+		err = snd_ctl_add(card, kcontrol);
 		if (err < 0)
 			return err;
+		if (!strcmp(kcontrol->id.name, "CD Volume"))
+			dummy->cd_volume_ctl = kcontrol;
+		else if (!strcmp(kcontrol->id.name, "CD Capture Switch"))
+			dummy->cd_switch_ctl = kcontrol;
+
 	}
 	return 0;
 }
@@ -962,7 +1031,7 @@
 	}
 }
 
-static void __devinit dummy_proc_init(struct snd_dummy *chip)
+static void dummy_proc_init(struct snd_dummy *chip)
 {
 	struct snd_info_entry *entry;
 
@@ -977,7 +1046,7 @@
 #define dummy_proc_init(x)
 #endif /* CONFIG_SND_DEBUG && CONFIG_PROC_FS */
 
-static int __devinit snd_dummy_probe(struct platform_device *devptr)
+static int snd_dummy_probe(struct platform_device *devptr)
 {
 	struct snd_card *card;
 	struct snd_dummy *dummy;
@@ -1057,7 +1126,7 @@
 	return err;
 }
 
-static int __devexit snd_dummy_remove(struct platform_device *devptr)
+static int snd_dummy_remove(struct platform_device *devptr)
 {
 	snd_card_free(platform_get_drvdata(devptr));
 	platform_set_drvdata(devptr, NULL);
@@ -1093,7 +1162,7 @@
 
 static struct platform_driver snd_dummy_driver = {
 	.probe		= snd_dummy_probe,
-	.remove		= __devexit_p(snd_dummy_remove),
+	.remove		= snd_dummy_remove,
 	.driver		= {
 		.name	= SND_DUMMY_DRIVER,
 		.owner	= THIS_MODULE,
diff --git a/sound/drivers/ml403-ac97cr.c b/sound/drivers/ml403-ac97cr.c
index 6c83b1a..8125a7e 100644
--- a/sound/drivers/ml403-ac97cr.c
+++ b/sound/drivers/ml403-ac97cr.c
@@ -1063,7 +1063,7 @@
 	return;
 }
 
-static int __devinit
+static int
 snd_ml403_ac97cr_chip_init(struct snd_ml403_ac97cr *ml403_ac97cr)
 {
 	unsigned long end_time;
@@ -1108,7 +1108,7 @@
 	return snd_ml403_ac97cr_free(ml403_ac97cr);
 }
 
-static int __devinit
+static int
 snd_ml403_ac97cr_create(struct snd_card *card, struct platform_device *pfdev,
 			struct snd_ml403_ac97cr **rml403_ac97cr)
 {
@@ -1204,7 +1204,7 @@
 	PDEBUG(INIT_INFO, "mixer_free(): (done)\n");
 }
 
-static int __devinit
+static int
 snd_ml403_ac97cr_mixer(struct snd_ml403_ac97cr *ml403_ac97cr)
 {
 	struct snd_ac97_bus *bus;
@@ -1237,7 +1237,7 @@
 	return err;
 }
 
-static int __devinit
+static int
 snd_ml403_ac97cr_pcm(struct snd_ml403_ac97cr *ml403_ac97cr, int device,
 		     struct snd_pcm **rpcm)
 {
@@ -1268,7 +1268,7 @@
 	return 0;
 }
 
-static int __devinit snd_ml403_ac97cr_probe(struct platform_device *pfdev)
+static int snd_ml403_ac97cr_probe(struct platform_device *pfdev)
 {
 	struct snd_card *card;
 	struct snd_ml403_ac97cr *ml403_ac97cr = NULL;
diff --git a/sound/drivers/mpu401/mpu401.c b/sound/drivers/mpu401/mpu401.c
index bc03a20..da1a29b 100644
--- a/sound/drivers/mpu401/mpu401.c
+++ b/sound/drivers/mpu401/mpu401.c
@@ -100,7 +100,7 @@
 	return err;
 }
 
-static int __devinit snd_mpu401_probe(struct platform_device *devptr)
+static int snd_mpu401_probe(struct platform_device *devptr)
 {
 	int dev = devptr->id;
 	int err;
@@ -126,7 +126,7 @@
 	return 0;
 }
 
-static int __devexit snd_mpu401_remove(struct platform_device *devptr)
+static int snd_mpu401_remove(struct platform_device *devptr)
 {
 	snd_card_free(platform_get_drvdata(devptr));
 	platform_set_drvdata(devptr, NULL);
@@ -137,7 +137,7 @@
 
 static struct platform_driver snd_mpu401_driver = {
 	.probe		= snd_mpu401_probe,
-	.remove		= __devexit_p(snd_mpu401_remove),
+	.remove		= snd_mpu401_remove,
 	.driver		= {
 		.name	= SND_MPU401_DRIVER,
 		.owner	= THIS_MODULE,
@@ -156,8 +156,8 @@
 
 MODULE_DEVICE_TABLE(pnp, snd_mpu401_pnpids);
 
-static int __devinit snd_mpu401_pnp(int dev, struct pnp_dev *device,
-				 const struct pnp_device_id *id)
+static int snd_mpu401_pnp(int dev, struct pnp_dev *device,
+			  const struct pnp_device_id *id)
 {
 	if (!pnp_port_valid(device, 0) ||
 	    pnp_port_flags(device, 0) & IORESOURCE_DISABLED) {
@@ -182,8 +182,8 @@
 	return 0;
 }
 
-static int __devinit snd_mpu401_pnp_probe(struct pnp_dev *pnp_dev,
-					  const struct pnp_device_id *id)
+static int snd_mpu401_pnp_probe(struct pnp_dev *pnp_dev,
+				const struct pnp_device_id *id)
 {
 	static int dev;
 	struct snd_card *card;
@@ -211,7 +211,7 @@
 	return -ENODEV;
 }
 
-static void __devexit snd_mpu401_pnp_remove(struct pnp_dev *dev)
+static void snd_mpu401_pnp_remove(struct pnp_dev *dev)
 {
 	struct snd_card *card = (struct snd_card *) pnp_get_drvdata(dev);
 
@@ -223,7 +223,7 @@
 	.name = "mpu401",
 	.id_table = snd_mpu401_pnpids,
 	.probe = snd_mpu401_pnp_probe,
-	.remove = __devexit_p(snd_mpu401_pnp_remove),
+	.remove = snd_mpu401_pnp_remove,
 };
 #else
 static struct pnp_driver snd_mpu401_pnp_driver;
diff --git a/sound/drivers/mtpav.c b/sound/drivers/mtpav.c
index cad73af..9f1815b 100644
--- a/sound/drivers/mtpav.c
+++ b/sound/drivers/mtpav.c
@@ -583,7 +583,7 @@
 /*
  * get ISA resources
  */
-static int __devinit snd_mtpav_get_ISA(struct mtpav * mcard)
+static int snd_mtpav_get_ISA(struct mtpav *mcard)
 {
 	if ((mcard->res_port = request_region(port, 3, "MotuMTPAV MIDI")) == NULL) {
 		snd_printk(KERN_ERR "MTVAP port 0x%lx is busy\n", port);
@@ -619,8 +619,8 @@
  * get RAWMIDI resources
  */
 
-static void __devinit snd_mtpav_set_name(struct mtpav *chip,
-				      struct snd_rawmidi_substream *substream)
+static void snd_mtpav_set_name(struct mtpav *chip,
+			       struct snd_rawmidi_substream *substream)
 {
 	if (substream->number >= 0 && substream->number < chip->num_ports)
 		sprintf(substream->name, "MTP direct %d", (substream->number % chip->num_ports) + 1);
@@ -634,7 +634,7 @@
 		strcpy(substream->name, "MTP broadcast");
 }
 
-static int __devinit snd_mtpav_get_RAWMIDI(struct mtpav *mcard)
+static int snd_mtpav_get_RAWMIDI(struct mtpav *mcard)
 {
 	int rval;
 	struct snd_rawmidi *rawmidi;
@@ -691,7 +691,7 @@
 
 /*
  */
-static int __devinit snd_mtpav_probe(struct platform_device *dev)
+static int snd_mtpav_probe(struct platform_device *dev)
 {
 	struct snd_card *card;
 	int err;
@@ -746,7 +746,7 @@
 	return err;
 }
 
-static int __devexit snd_mtpav_remove(struct platform_device *devptr)
+static int snd_mtpav_remove(struct platform_device *devptr)
 {
 	snd_card_free(platform_get_drvdata(devptr));
 	platform_set_drvdata(devptr, NULL);
@@ -757,7 +757,7 @@
 
 static struct platform_driver snd_mtpav_driver = {
 	.probe		= snd_mtpav_probe,
-	.remove		= __devexit_p(snd_mtpav_remove),
+	.remove		= snd_mtpav_remove,
 	.driver		= {
 		.name	= SND_MTPAV_DRIVER,
 		.owner	= THIS_MODULE,
diff --git a/sound/drivers/mts64.c b/sound/drivers/mts64.c
index 2d5514b..4e0dd22 100644
--- a/sound/drivers/mts64.c
+++ b/sound/drivers/mts64.c
@@ -83,9 +83,9 @@
 	return 0;
 }
 
-static int __devinit snd_mts64_create(struct snd_card *card, 
-				      struct pardevice *pardev, 
-				      struct mts64 **rchip)
+static int snd_mts64_create(struct snd_card *card,
+			    struct pardevice *pardev,
+			    struct mts64 **rchip)
 {
 	struct mts64 *mts;
 
@@ -214,7 +214,7 @@
  *  0 init ok
  *  -EIO failure
  */
-static int __devinit mts64_device_init(struct parport *p)
+static int mts64_device_init(struct parport *p)
 {
 	int i;
 
@@ -290,7 +290,7 @@
  *  0       device found
  *  -ENODEV no device
  */
-static int __devinit mts64_probe(struct parport *p)
+static int mts64_probe(struct parport *p)
 {
 	u8 c;
 
@@ -483,7 +483,7 @@
 	return changed;
 }
 
-static struct snd_kcontrol_new mts64_ctl_smpte_switch __devinitdata = {
+static struct snd_kcontrol_new mts64_ctl_smpte_switch = {
 	.iface = SNDRV_CTL_ELEM_IFACE_RAWMIDI,
 	.name  = "SMPTE Playback Switch",
 	.index = 0,
@@ -556,7 +556,7 @@
 	return changed;
 }
 
-static struct snd_kcontrol_new mts64_ctl_smpte_time_hours __devinitdata = {
+static struct snd_kcontrol_new mts64_ctl_smpte_time_hours = {
 	.iface = SNDRV_CTL_ELEM_IFACE_RAWMIDI,
 	.name  = "SMPTE Time Hours",
 	.index = 0,
@@ -567,7 +567,7 @@
 	.put  = snd_mts64_ctl_smpte_time_put
 };
 
-static struct snd_kcontrol_new mts64_ctl_smpte_time_minutes __devinitdata = {
+static struct snd_kcontrol_new mts64_ctl_smpte_time_minutes = {
 	.iface = SNDRV_CTL_ELEM_IFACE_RAWMIDI,
 	.name  = "SMPTE Time Minutes",
 	.index = 0,
@@ -578,7 +578,7 @@
 	.put  = snd_mts64_ctl_smpte_time_put
 };
 
-static struct snd_kcontrol_new mts64_ctl_smpte_time_seconds __devinitdata = {
+static struct snd_kcontrol_new mts64_ctl_smpte_time_seconds = {
 	.iface = SNDRV_CTL_ELEM_IFACE_RAWMIDI,
 	.name  = "SMPTE Time Seconds",
 	.index = 0,
@@ -589,7 +589,7 @@
 	.put  = snd_mts64_ctl_smpte_time_put
 };
 
-static struct snd_kcontrol_new mts64_ctl_smpte_time_frames __devinitdata = {
+static struct snd_kcontrol_new mts64_ctl_smpte_time_frames = {
 	.iface = SNDRV_CTL_ELEM_IFACE_RAWMIDI,
 	.name  = "SMPTE Time Frames",
 	.index = 0,
@@ -651,7 +651,7 @@
 	return changed;
 }
 
-static struct snd_kcontrol_new mts64_ctl_smpte_fps __devinitdata = {
+static struct snd_kcontrol_new mts64_ctl_smpte_fps = {
 	.iface = SNDRV_CTL_ELEM_IFACE_RAWMIDI,
 	.name  = "SMPTE Fps",
 	.index = 0,
@@ -663,11 +663,11 @@
 };
 
 
-static int __devinit snd_mts64_ctl_create(struct snd_card *card, 
-					  struct mts64 *mts) 
+static int snd_mts64_ctl_create(struct snd_card *card,
+				struct mts64 *mts)
 {
 	int err, i;
-	static struct snd_kcontrol_new *control[] __devinitdata = {
+	static struct snd_kcontrol_new *control[] = {
 		&mts64_ctl_smpte_switch,
 		&mts64_ctl_smpte_time_hours,
 		&mts64_ctl_smpte_time_minutes,
@@ -774,7 +774,7 @@
 };
 
 /* Create and initialize the rawmidi component */
-static int __devinit snd_mts64_rawmidi_create(struct snd_card *card)
+static int snd_mts64_rawmidi_create(struct snd_card *card)
 {
 	struct mts64 *mts = card->private_data;
 	struct snd_rawmidi *rmidi;
@@ -860,7 +860,7 @@
 	spin_unlock(&mts->lock);
 }
 
-static int __devinit snd_mts64_probe_port(struct parport *p)
+static int snd_mts64_probe_port(struct parport *p)
 {
 	struct pardevice *pardev;
 	int res;
@@ -884,7 +884,7 @@
 	return res;
 }
 
-static void __devinit snd_mts64_attach(struct parport *p)
+static void snd_mts64_attach(struct parport *p)
 {
 	struct platform_device *device;
 
@@ -940,7 +940,7 @@
 	snd_mts64_free(mts);
 }
 
-static int __devinit snd_mts64_probe(struct platform_device *pdev)
+static int snd_mts64_probe(struct platform_device *pdev)
 {
 	struct pardevice *pardev;
 	struct parport *p;
@@ -1025,7 +1025,7 @@
 	return err;
 }
 
-static int __devexit snd_mts64_remove(struct platform_device *pdev)
+static int snd_mts64_remove(struct platform_device *pdev)
 {
 	struct snd_card *card = platform_get_drvdata(pdev);
 
@@ -1038,7 +1038,7 @@
 
 static struct platform_driver snd_mts64_driver = {
 	.probe  = snd_mts64_probe,
-	.remove = __devexit_p(snd_mts64_remove),
+	.remove = snd_mts64_remove,
 	.driver = {
 		.name = PLATFORM_DRIVER,
 		.owner	= THIS_MODULE,
diff --git a/sound/drivers/pcsp/pcsp.c b/sound/drivers/pcsp/pcsp.c
index ef17129..7a5fdb9 100644
--- a/sound/drivers/pcsp/pcsp.c
+++ b/sound/drivers/pcsp/pcsp.c
@@ -39,7 +39,7 @@
 
 struct snd_pcsp pcsp_chip;
 
-static int __devinit snd_pcsp_create(struct snd_card *card)
+static int snd_pcsp_create(struct snd_card *card)
 {
 	static struct snd_device_ops ops = { };
 	struct timespec tp;
@@ -93,7 +93,7 @@
 	return 0;
 }
 
-static int __devinit snd_card_pcsp_probe(int devnum, struct device *dev)
+static int snd_card_pcsp_probe(int devnum, struct device *dev)
 {
 	struct snd_card *card;
 	int err;
@@ -142,7 +142,7 @@
 	return 0;
 }
 
-static int __devinit alsa_card_pcsp_init(struct device *dev)
+static int alsa_card_pcsp_init(struct device *dev)
 {
 	int err;
 
@@ -161,12 +161,12 @@
 	return 0;
 }
 
-static void __devexit alsa_card_pcsp_exit(struct snd_pcsp *chip)
+static void alsa_card_pcsp_exit(struct snd_pcsp *chip)
 {
 	snd_card_free(chip->card);
 }
 
-static int __devinit pcsp_probe(struct platform_device *dev)
+static int pcsp_probe(struct platform_device *dev)
 {
 	int err;
 
@@ -184,7 +184,7 @@
 	return 0;
 }
 
-static int __devexit pcsp_remove(struct platform_device *dev)
+static int pcsp_remove(struct platform_device *dev)
 {
 	struct snd_pcsp *chip = platform_get_drvdata(dev);
 	alsa_card_pcsp_exit(chip);
@@ -227,7 +227,7 @@
 		.pm	= PCSP_PM_OPS,
 	},
 	.probe		= pcsp_probe,
-	.remove		= __devexit_p(pcsp_remove),
+	.remove		= pcsp_remove,
 	.shutdown	= pcsp_shutdown,
 };
 
diff --git a/sound/drivers/pcsp/pcsp_input.c b/sound/drivers/pcsp/pcsp_input.c
index b5e2b54..b874b0a 100644
--- a/sound/drivers/pcsp/pcsp_input.c
+++ b/sound/drivers/pcsp/pcsp_input.c
@@ -77,7 +77,7 @@
 	return 0;
 }
 
-int __devinit pcspkr_input_init(struct input_dev **rdev, struct device *dev)
+int pcspkr_input_init(struct input_dev **rdev, struct device *dev)
 {
 	int err;
 
diff --git a/sound/drivers/pcsp/pcsp_input.h b/sound/drivers/pcsp/pcsp_input.h
index e66738c..d692749 100644
--- a/sound/drivers/pcsp/pcsp_input.h
+++ b/sound/drivers/pcsp/pcsp_input.h
@@ -7,7 +7,7 @@
 #ifndef __PCSP_INPUT_H__
 #define __PCSP_INPUT_H__
 
-int __devinit pcspkr_input_init(struct input_dev **rdev, struct device *dev);
+int pcspkr_input_init(struct input_dev **rdev, struct device *dev);
 int pcspkr_input_remove(struct input_dev *dev);
 void pcspkr_stop_sound(void);
 
diff --git a/sound/drivers/pcsp/pcsp_lib.c b/sound/drivers/pcsp/pcsp_lib.c
index 434981d..29ebaa4 100644
--- a/sound/drivers/pcsp/pcsp_lib.c
+++ b/sound/drivers/pcsp/pcsp_lib.c
@@ -334,7 +334,7 @@
 	.pointer = snd_pcsp_playback_pointer,
 };
 
-int __devinit snd_pcsp_new_pcm(struct snd_pcsp *chip)
+int snd_pcsp_new_pcm(struct snd_pcsp *chip)
 {
 	int err;
 
diff --git a/sound/drivers/pcsp/pcsp_mixer.c b/sound/drivers/pcsp/pcsp_mixer.c
index 6f633f4..f1e1def 100644
--- a/sound/drivers/pcsp/pcsp_mixer.c
+++ b/sound/drivers/pcsp/pcsp_mixer.c
@@ -119,17 +119,17 @@
 	.put =		pcsp_##ctl_type##_put, \
 }
 
-static struct snd_kcontrol_new __devinitdata snd_pcsp_controls_pcm[] = {
+static struct snd_kcontrol_new snd_pcsp_controls_pcm[] = {
 	PCSP_MIXER_CONTROL(enable, "Master Playback Switch"),
 	PCSP_MIXER_CONTROL(treble, "BaseFRQ Playback Volume"),
 };
 
-static struct snd_kcontrol_new __devinitdata snd_pcsp_controls_spkr[] = {
+static struct snd_kcontrol_new snd_pcsp_controls_spkr[] = {
 	PCSP_MIXER_CONTROL(pcspkr, "Beep Playback Switch"),
 };
 
-static int __devinit snd_pcsp_ctls_add(struct snd_pcsp *chip,
-	struct snd_kcontrol_new *ctls, int num)
+static int snd_pcsp_ctls_add(struct snd_pcsp *chip,
+			     struct snd_kcontrol_new *ctls, int num)
 {
 	int i, err;
 	struct snd_card *card = chip->card;
@@ -141,7 +141,7 @@
 	return 0;
 }
 
-int __devinit snd_pcsp_new_mixer(struct snd_pcsp *chip, int nopcm)
+int snd_pcsp_new_mixer(struct snd_pcsp *chip, int nopcm)
 {
 	int err;
 	struct snd_card *card = chip->card;
diff --git a/sound/drivers/portman2x4.c b/sound/drivers/portman2x4.c
index 8364855..991018d 100644
--- a/sound/drivers/portman2x4.c
+++ b/sound/drivers/portman2x4.c
@@ -96,9 +96,9 @@
 	return 0;
 }
 
-static int __devinit portman_create(struct snd_card *card, 
-				    struct pardevice *pardev, 
-				    struct portman **rchip)
+static int portman_create(struct snd_card *card,
+			  struct pardevice *pardev,
+			  struct portman **rchip)
 {
 	struct portman *pm;
 
@@ -561,7 +561,7 @@
 };
 
 /* Create and initialize the rawmidi component */
-static int __devinit snd_portman_rawmidi_create(struct snd_card *card)
+static int snd_portman_rawmidi_create(struct snd_card *card)
 {
 	struct portman *pm = card->private_data;
 	struct snd_rawmidi *rmidi;
@@ -648,7 +648,7 @@
 	spin_unlock(&pm->reg_lock);
 }
 
-static int __devinit snd_portman_probe_port(struct parport *p)
+static int snd_portman_probe_port(struct parport *p)
 {
 	struct pardevice *pardev;
 	int res;
@@ -672,7 +672,7 @@
 	return res ? -EIO : 0;
 }
 
-static void __devinit snd_portman_attach(struct parport *p)
+static void snd_portman_attach(struct parport *p)
 {
 	struct platform_device *device;
 
@@ -728,7 +728,7 @@
 	portman_free(pm);
 }
 
-static int __devinit snd_portman_probe(struct platform_device *pdev)
+static int snd_portman_probe(struct platform_device *pdev)
 {
 	struct pardevice *pardev;
 	struct parport *p;
@@ -814,7 +814,7 @@
 	return err;
 }
 
-static int __devexit snd_portman_remove(struct platform_device *pdev)
+static int snd_portman_remove(struct platform_device *pdev)
 {
 	struct snd_card *card = platform_get_drvdata(pdev);
 
@@ -827,7 +827,7 @@
 
 static struct platform_driver snd_portman_driver = {
 	.probe  = snd_portman_probe,
-	.remove = __devexit_p(snd_portman_remove),
+	.remove = snd_portman_remove,
 	.driver = {
 		.name = PLATFORM_DRIVER,
 		.owner	= THIS_MODULE,
diff --git a/sound/drivers/serial-u16550.c b/sound/drivers/serial-u16550.c
index 8670067..7425dd8 100644
--- a/sound/drivers/serial-u16550.c
+++ b/sound/drivers/serial-u16550.c
@@ -328,7 +328,7 @@
  *  return 0 if found
  *  return negative error if not found
  */
-static int __devinit snd_uart16550_detect(struct snd_uart16550 *uart)
+static int snd_uart16550_detect(struct snd_uart16550 *uart)
 {
 	unsigned long io_base = uart->base;
 	int ok;
@@ -783,14 +783,14 @@
 	return snd_uart16550_free(uart);
 }
 
-static int __devinit snd_uart16550_create(struct snd_card *card,
-				       unsigned long iobase,
-				       int irq,
-				       unsigned int speed,
-				       unsigned int base,
-				       int adaptor,
-				       int droponfull,
-				       struct snd_uart16550 **ruart)
+static int snd_uart16550_create(struct snd_card *card,
+				unsigned long iobase,
+				int irq,
+				unsigned int speed,
+				unsigned int base,
+				int adaptor,
+				int droponfull,
+				struct snd_uart16550 **ruart)
 {
 	static struct snd_device_ops ops = {
 		.dev_free =	snd_uart16550_dev_free,
@@ -863,7 +863,7 @@
 	return 0;
 }
 
-static void __devinit snd_uart16550_substreams(struct snd_rawmidi_str *stream)
+static void snd_uart16550_substreams(struct snd_rawmidi_str *stream)
 {
 	struct snd_rawmidi_substream *substream;
 
@@ -872,9 +872,9 @@
 	}
 }
 
-static int __devinit snd_uart16550_rmidi(struct snd_uart16550 *uart, int device,
-				      int outs, int ins,
-				      struct snd_rawmidi **rmidi)
+static int snd_uart16550_rmidi(struct snd_uart16550 *uart, int device,
+			       int outs, int ins,
+			       struct snd_rawmidi **rmidi)
 {
 	struct snd_rawmidi *rrawmidi;
 	int err;
@@ -899,7 +899,7 @@
 	return 0;
 }
 
-static int __devinit snd_serial_probe(struct platform_device *devptr)
+static int snd_serial_probe(struct platform_device *devptr)
 {
 	struct snd_card *card;
 	struct snd_uart16550 *uart;
@@ -982,7 +982,7 @@
 	return err;
 }
 
-static int __devexit snd_serial_remove(struct platform_device *devptr)
+static int snd_serial_remove(struct platform_device *devptr)
 {
 	snd_card_free(platform_get_drvdata(devptr));
 	platform_set_drvdata(devptr, NULL);
@@ -993,7 +993,7 @@
 
 static struct platform_driver snd_serial_driver = {
 	.probe		= snd_serial_probe,
-	.remove		= __devexit_p( snd_serial_remove),
+	.remove		=  snd_serial_remove,
 	.driver		= {
 		.name	= SND_SERIAL_DRIVER,
 		.owner	= THIS_MODULE,
diff --git a/sound/drivers/virmidi.c b/sound/drivers/virmidi.c
index d7d514d..cc4be88 100644
--- a/sound/drivers/virmidi.c
+++ b/sound/drivers/virmidi.c
@@ -83,7 +83,7 @@
 static struct platform_device *devices[SNDRV_CARDS];
 
 
-static int __devinit snd_virmidi_probe(struct platform_device *devptr)
+static int snd_virmidi_probe(struct platform_device *devptr)
 {
 	struct snd_card *card;
 	struct snd_card_virmidi *vmidi;
@@ -129,7 +129,7 @@
 	return err;
 }
 
-static int __devexit snd_virmidi_remove(struct platform_device *devptr)
+static int snd_virmidi_remove(struct platform_device *devptr)
 {
 	snd_card_free(platform_get_drvdata(devptr));
 	platform_set_drvdata(devptr, NULL);
@@ -140,7 +140,7 @@
 
 static struct platform_driver snd_virmidi_driver = {
 	.probe		= snd_virmidi_probe,
-	.remove		= __devexit_p(snd_virmidi_remove),
+	.remove		= snd_virmidi_remove,
 	.driver		= {
 		.name	= SND_VIRMIDI_DRIVER,
 		.owner	= THIS_MODULE,
diff --git a/sound/drivers/vx/vx_hwdep.c b/sound/drivers/vx/vx_hwdep.c
index 4a1fae9..3014b863 100644
--- a/sound/drivers/vx/vx_hwdep.c
+++ b/sound/drivers/vx/vx_hwdep.c
@@ -29,8 +29,6 @@
 #include <sound/hwdep.h>
 #include <sound/vx_core.h>
 
-#ifdef SND_VX_FW_LOADER
-
 MODULE_FIRMWARE("vx/bx_1_vxp.b56");
 MODULE_FIRMWARE("vx/bx_1_vp4.b56");
 MODULE_FIRMWARE("vx/x1_1_vx2.xlx");
@@ -119,142 +117,5 @@
 #endif
 }
 
-#else /* old style firmware loading */
-
-static int vx_hwdep_dsp_status(struct snd_hwdep *hw,
-			       struct snd_hwdep_dsp_status *info)
-{
-	static char *type_ids[VX_TYPE_NUMS] = {
-		[VX_TYPE_BOARD] = "vxboard",
-		[VX_TYPE_V2] = "vx222",
-		[VX_TYPE_MIC] = "vx222",
-		[VX_TYPE_VXPOCKET] = "vxpocket",
-		[VX_TYPE_VXP440] = "vxp440",
-	};
-	struct vx_core *vx = hw->private_data;
-
-	if (snd_BUG_ON(!type_ids[vx->type]))
-		return -EINVAL;
-	strcpy(info->id, type_ids[vx->type]);
-	if (vx_is_pcmcia(vx))
-		info->num_dsps = 4;
-	else
-		info->num_dsps = 3;
-	if (vx->chip_status & VX_STAT_CHIP_INIT)
-		info->chip_ready = 1;
-	info->version = VX_DRIVER_VERSION;
-	return 0;
-}
-
-static void free_fw(const struct firmware *fw)
-{
-	if (fw) {
-		vfree(fw->data);
-		kfree(fw);
-	}
-}
-
-static int vx_hwdep_dsp_load(struct snd_hwdep *hw,
-			     struct snd_hwdep_dsp_image *dsp)
-{
-	struct vx_core *vx = hw->private_data;
-	int index, err;
-	struct firmware *fw;
-
-	if (snd_BUG_ON(!vx->ops->load_dsp))
-		return -ENXIO;
-
-	fw = kmalloc(sizeof(*fw), GFP_KERNEL);
-	if (! fw) {
-		snd_printk(KERN_ERR "cannot allocate firmware\n");
-		return -ENOMEM;
-	}
-	fw->size = dsp->length;
-	fw->data = vmalloc(fw->size);
-	if (! fw->data) {
-		snd_printk(KERN_ERR "cannot allocate firmware image (length=%d)\n",
-			   (int)fw->size);
-		kfree(fw);
-		return -ENOMEM;
-	}
-	if (copy_from_user((void *)fw->data, dsp->image, dsp->length)) {
-		free_fw(fw);
-		return -EFAULT;
-	}
-
-	index = dsp->index;
-	if (! vx_is_pcmcia(vx))
-		index++;
-	err = vx->ops->load_dsp(vx, index, fw);
-	if (err < 0) {
-		free_fw(fw);
-		return err;
-	}
-#ifdef CONFIG_PM
-	vx->firmware[index] = fw;
-#else
-	free_fw(fw);
-#endif
-
-	if (index == 1)
-		vx->chip_status |= VX_STAT_XILINX_LOADED;
-	if (index < 3)
-		return 0;
-
-	/* ok, we reached to the last one */
-	/* create the devices if not built yet */
-	if (! (vx->chip_status & VX_STAT_DEVICE_INIT)) {
-		if ((err = snd_vx_pcm_new(vx)) < 0)
-			return err;
-
-		if ((err = snd_vx_mixer_new(vx)) < 0)
-			return err;
-
-		if (vx->ops->add_controls)
-			if ((err = vx->ops->add_controls(vx)) < 0)
-				return err;
-
-		if ((err = snd_card_register(vx->card)) < 0)
-			return err;
-
-		vx->chip_status |= VX_STAT_DEVICE_INIT;
-	}
-	vx->chip_status |= VX_STAT_CHIP_INIT;
-	return 0;
-}
-
-
-/* exported */
-int snd_vx_setup_firmware(struct vx_core *chip)
-{
-	int err;
-	struct snd_hwdep *hw;
-
-	if ((err = snd_hwdep_new(chip->card, SND_VX_HWDEP_ID, 0, &hw)) < 0)
-		return err;
-
-	hw->iface = SNDRV_HWDEP_IFACE_VX;
-	hw->private_data = chip;
-	hw->ops.dsp_status = vx_hwdep_dsp_status;
-	hw->ops.dsp_load = vx_hwdep_dsp_load;
-	hw->exclusive = 1;
-	sprintf(hw->name, "VX Loader (%s)", chip->card->driver);
-	chip->hwdep = hw;
-
-	return snd_card_register(chip->card);
-}
-
-/* exported */
-void snd_vx_free_firmware(struct vx_core *chip)
-{
-#ifdef CONFIG_PM
-	int i;
-	for (i = 0; i < 4; i++)
-		free_fw(chip->firmware[i]);
-#endif
-}
-
-#endif /* SND_VX_FW_LOADER */
-
 EXPORT_SYMBOL(snd_vx_setup_firmware);
 EXPORT_SYMBOL(snd_vx_free_firmware);
diff --git a/sound/firewire/Kconfig b/sound/firewire/Kconfig
index 2607148..ea063e1 100644
--- a/sound/firewire/Kconfig
+++ b/sound/firewire/Kconfig
@@ -33,4 +33,17 @@
 	  To compile this driver as a module, choose M here: the module
 	  will be called snd-isight.
 
+config SND_SCS1X
+	tristate "Stanton Control System 1 MIDI"
+	select SND_PCM
+	select SND_RAWMIDI
+	select SND_FIREWIRE_LIB
+	help
+	  Say Y here to include support for the MIDI ports of the Stanton
+	  SCS.1d/SCS.1m DJ controllers.  (SCS.1m audio is still handled
+	  by FFADO.)
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-scs1x.
+
 endif # SND_FIREWIRE
diff --git a/sound/firewire/Makefile b/sound/firewire/Makefile
index d71ed89..460179d 100644
--- a/sound/firewire/Makefile
+++ b/sound/firewire/Makefile
@@ -2,7 +2,9 @@
 			 fcp.o cmp.o amdtp.o
 snd-firewire-speakers-objs := speakers.o
 snd-isight-objs := isight.o
+snd-scs1x-objs := scs1x.o
 
 obj-$(CONFIG_SND_FIREWIRE_LIB) += snd-firewire-lib.o
 obj-$(CONFIG_SND_FIREWIRE_SPEAKERS) += snd-firewire-speakers.o
 obj-$(CONFIG_SND_ISIGHT) += snd-isight.o
+obj-$(CONFIG_SND_SCS1X) += snd-scs1x.o
diff --git a/sound/firewire/scs1x.c b/sound/firewire/scs1x.c
new file mode 100644
index 0000000..844a555
--- /dev/null
+++ b/sound/firewire/scs1x.c
@@ -0,0 +1,527 @@
+/*
+ * Stanton Control System 1 MIDI driver
+ *
+ * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
+ * Licensed under the terms of the GNU General Public License, version 2.
+ */
+
+#include <linux/device.h>
+#include <linux/firewire.h>
+#include <linux/firewire-constants.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/mod_devicetable.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/wait.h>
+#include <sound/core.h>
+#include <sound/initval.h>
+#include <sound/rawmidi.h>
+#include "lib.h"
+
+#define OUI_STANTON	0x001260
+#define MODEL_SCS_1M	0x001000
+#define MODEL_SCS_1D	0x002000
+
+#define HSS1394_ADDRESS			0xc007dedadadaULL
+#define HSS1394_MAX_PACKET_SIZE		64
+
+#define HSS1394_TAG_USER_DATA		0x00
+#define HSS1394_TAG_CHANGE_ADDRESS	0xf1
+
+struct scs {
+	struct snd_card *card;
+	struct fw_unit *unit;
+	struct fw_address_handler hss_handler;
+	struct fw_transaction transaction;
+	bool transaction_running;
+	bool output_idle;
+	u8 output_status;
+	u8 output_bytes;
+	bool output_escaped;
+	bool output_escape_high_nibble;
+	u8 input_escape_count;
+	struct snd_rawmidi_substream *output;
+	struct snd_rawmidi_substream *input;
+	struct tasklet_struct tasklet;
+	wait_queue_head_t idle_wait;
+	u8 *buffer;
+};
+
+static const u8 sysex_escape_prefix[] = {
+	0xf0,			/* SysEx begin */
+	0x00, 0x01, 0x60,	/* Stanton DJ */
+	0x48, 0x53, 0x53,	/* "HSS" */
+};
+
+static int scs_output_open(struct snd_rawmidi_substream *stream)
+{
+	struct scs *scs = stream->rmidi->private_data;
+
+	scs->output_status = 0;
+	scs->output_bytes = 1;
+	scs->output_escaped = false;
+
+	return 0;
+}
+
+static int scs_output_close(struct snd_rawmidi_substream *stream)
+{
+	return 0;
+}
+
+static void scs_output_trigger(struct snd_rawmidi_substream *stream, int up)
+{
+	struct scs *scs = stream->rmidi->private_data;
+
+	ACCESS_ONCE(scs->output) = up ? stream : NULL;
+	if (up) {
+		scs->output_idle = false;
+		tasklet_schedule(&scs->tasklet);
+	}
+}
+
+static void scs_write_callback(struct fw_card *card, int rcode,
+			       void *data, size_t length, void *callback_data)
+{
+	struct scs *scs = callback_data;
+
+	if (rcode == RCODE_GENERATION) {
+		/* TODO: retry this packet */
+	}
+
+	scs->transaction_running = false;
+	tasklet_schedule(&scs->tasklet);
+}
+
+static bool is_valid_running_status(u8 status)
+{
+	return status >= 0x80 && status <= 0xef;
+}
+
+static bool is_one_byte_cmd(u8 status)
+{
+	return status == 0xf6 ||
+	       status >= 0xf8;
+}
+
+static bool is_two_bytes_cmd(u8 status)
+{
+	return (status >= 0xc0 && status <= 0xdf) ||
+	       status == 0xf1 ||
+	       status == 0xf3;
+}
+
+static bool is_three_bytes_cmd(u8 status)
+{
+	return (status >= 0x80 && status <= 0xbf) ||
+	       (status >= 0xe0 && status <= 0xef) ||
+	       status == 0xf2;
+}
+
+static bool is_invalid_cmd(u8 status)
+{
+	return status == 0xf4 ||
+	       status == 0xf5 ||
+	       status == 0xf9 ||
+	       status == 0xfd;
+}
+
+static void scs_output_tasklet(unsigned long data)
+{
+	struct scs *scs = (void *)data;
+	struct snd_rawmidi_substream *stream;
+	unsigned int i;
+	u8 byte;
+	struct fw_device *dev;
+	int generation;
+
+	if (scs->transaction_running)
+		return;
+
+	stream = ACCESS_ONCE(scs->output);
+	if (!stream) {
+		scs->output_idle = true;
+		wake_up(&scs->idle_wait);
+		return;
+	}
+
+	i = scs->output_bytes;
+	for (;;) {
+		if (snd_rawmidi_transmit(stream, &byte, 1) != 1) {
+			scs->output_bytes = i;
+			scs->output_idle = true;
+			wake_up(&scs->idle_wait);
+			return;
+		}
+		/*
+		 * Convert from real MIDI to what I think the device expects (no
+		 * running status, one command per packet, unescaped SysExs).
+		 */
+		if (scs->output_escaped && byte < 0x80) {
+			if (scs->output_escape_high_nibble) {
+				if (i < HSS1394_MAX_PACKET_SIZE) {
+					scs->buffer[i] = byte << 4;
+					scs->output_escape_high_nibble = false;
+				}
+			} else {
+				scs->buffer[i++] |= byte & 0x0f;
+				scs->output_escape_high_nibble = true;
+			}
+		} else if (byte < 0x80) {
+			if (i == 1) {
+				if (!is_valid_running_status(scs->output_status))
+					continue;
+				scs->buffer[0] = HSS1394_TAG_USER_DATA;
+				scs->buffer[i++] = scs->output_status;
+			}
+			scs->buffer[i++] = byte;
+			if ((i == 3 && is_two_bytes_cmd(scs->output_status)) ||
+			    (i == 4 && is_three_bytes_cmd(scs->output_status)))
+				break;
+			if (i == 1 + ARRAY_SIZE(sysex_escape_prefix) &&
+			    !memcmp(scs->buffer + 1, sysex_escape_prefix,
+				    ARRAY_SIZE(sysex_escape_prefix))) {
+				scs->output_escaped = true;
+				scs->output_escape_high_nibble = true;
+				i = 0;
+			}
+			if (i >= HSS1394_MAX_PACKET_SIZE)
+				i = 1;
+		} else if (byte == 0xf7) {
+			if (scs->output_escaped) {
+				if (i >= 1 && scs->output_escape_high_nibble &&
+				    scs->buffer[0] != HSS1394_TAG_CHANGE_ADDRESS)
+					break;
+			} else {
+				if (i > 1 && scs->output_status == 0xf0) {
+					scs->buffer[i++] = 0xf7;
+					break;
+				}
+			}
+			i = 1;
+			scs->output_escaped = false;
+		} else if (!is_invalid_cmd(byte) &&
+			   byte < 0xf8) {
+			i = 1;
+			scs->buffer[0] = HSS1394_TAG_USER_DATA;
+			scs->buffer[i++] = byte;
+			scs->output_status = byte;
+			scs->output_escaped = false;
+			if (is_one_byte_cmd(byte))
+				break;
+		}
+	}
+	scs->output_bytes = 1;
+	scs->output_escaped = false;
+
+	scs->transaction_running = true;
+	dev = fw_parent_device(scs->unit);
+	generation = dev->generation;
+	smp_rmb(); /* node_id vs. generation */
+	fw_send_request(dev->card, &scs->transaction, TCODE_WRITE_BLOCK_REQUEST,
+			dev->node_id, generation, dev->max_speed,
+			HSS1394_ADDRESS, scs->buffer, i,
+			scs_write_callback, scs);
+}
+
+static void scs_output_drain(struct snd_rawmidi_substream *stream)
+{
+	struct scs *scs = stream->rmidi->private_data;
+
+	wait_event(scs->idle_wait, scs->output_idle);
+}
+
+static struct snd_rawmidi_ops output_ops = {
+	.open    = scs_output_open,
+	.close   = scs_output_close,
+	.trigger = scs_output_trigger,
+	.drain   = scs_output_drain,
+};
+
+static int scs_input_open(struct snd_rawmidi_substream *stream)
+{
+	struct scs *scs = stream->rmidi->private_data;
+
+	scs->input_escape_count = 0;
+
+	return 0;
+}
+
+static int scs_input_close(struct snd_rawmidi_substream *stream)
+{
+	return 0;
+}
+
+static void scs_input_trigger(struct snd_rawmidi_substream *stream, int up)
+{
+	struct scs *scs = stream->rmidi->private_data;
+
+	ACCESS_ONCE(scs->input) = up ? stream : NULL;
+}
+
+static void scs_input_escaped_byte(struct snd_rawmidi_substream *stream,
+				   u8 byte)
+{
+	u8 nibbles[2];
+
+	nibbles[0] = byte >> 4;
+	nibbles[1] = byte & 0x0f;
+	snd_rawmidi_receive(stream, nibbles, 2);
+}
+
+static void scs_input_midi_byte(struct scs *scs,
+				struct snd_rawmidi_substream *stream,
+				u8 byte)
+{
+	if (scs->input_escape_count > 0) {
+		scs_input_escaped_byte(stream, byte);
+		scs->input_escape_count--;
+		if (scs->input_escape_count == 0)
+			snd_rawmidi_receive(stream, (const u8[]) { 0xf7 }, 1);
+	} else if (byte == 0xf9) {
+		snd_rawmidi_receive(stream, sysex_escape_prefix,
+				    ARRAY_SIZE(sysex_escape_prefix));
+		scs_input_escaped_byte(stream, 0x00);
+		scs_input_escaped_byte(stream, 0xf9);
+		scs->input_escape_count = 3;
+	} else {
+		snd_rawmidi_receive(stream, &byte, 1);
+	}
+}
+
+static void scs_input_packet(struct scs *scs,
+			     struct snd_rawmidi_substream *stream,
+			     const u8 *data, unsigned int bytes)
+{
+	unsigned int i;
+
+	if (data[0] == HSS1394_TAG_USER_DATA) {
+		for (i = 1; i < bytes; ++i)
+			scs_input_midi_byte(scs, stream, data[i]);
+	} else {
+		snd_rawmidi_receive(stream, sysex_escape_prefix,
+				    ARRAY_SIZE(sysex_escape_prefix));
+		for (i = 0; i < bytes; ++i)
+			scs_input_escaped_byte(stream, data[i]);
+		snd_rawmidi_receive(stream, (const u8[]) { 0xf7 }, 1);
+	}
+}
+
+static struct snd_rawmidi_ops input_ops = {
+	.open    = scs_input_open,
+	.close   = scs_input_close,
+	.trigger = scs_input_trigger,
+};
+
+static int scs_create_midi(struct scs *scs)
+{
+	struct snd_rawmidi *rmidi;
+	int err;
+
+	err = snd_rawmidi_new(scs->card, "SCS.1x", 0, 1, 1, &rmidi);
+	if (err < 0)
+		return err;
+	snprintf(rmidi->name, sizeof(rmidi->name),
+		 "%s MIDI", scs->card->shortname);
+	rmidi->info_flags = SNDRV_RAWMIDI_INFO_OUTPUT |
+	                    SNDRV_RAWMIDI_INFO_INPUT |
+	                    SNDRV_RAWMIDI_INFO_DUPLEX;
+	rmidi->private_data = scs;
+	snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, &output_ops);
+	snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, &input_ops);
+
+	return 0;
+}
+
+static void handle_hss(struct fw_card *card, struct fw_request *request,
+		       int tcode, int destination, int source, int generation,
+		       unsigned long long offset, void *data, size_t length,
+		       void *callback_data)
+{
+	struct scs *scs = callback_data;
+	struct snd_rawmidi_substream *stream;
+
+	if (offset != scs->hss_handler.offset) {
+		fw_send_response(card, request, RCODE_ADDRESS_ERROR);
+		return;
+	}
+	if (tcode != TCODE_WRITE_QUADLET_REQUEST &&
+	    tcode != TCODE_WRITE_BLOCK_REQUEST) {
+		fw_send_response(card, request, RCODE_TYPE_ERROR);
+		return;
+	}
+
+	if (length >= 1) {
+		stream = ACCESS_ONCE(scs->input);
+		if (stream)
+			scs_input_packet(scs, stream, data, length);
+	}
+
+	fw_send_response(card, request, RCODE_COMPLETE);
+}
+
+static int scs_init_hss_address(struct scs *scs)
+{
+	__be64 data;
+	int err;
+
+	data = cpu_to_be64(((u64)HSS1394_TAG_CHANGE_ADDRESS << 56) |
+			   scs->hss_handler.offset);
+	err = snd_fw_transaction(scs->unit, TCODE_WRITE_BLOCK_REQUEST,
+				 HSS1394_ADDRESS, &data, 8);
+	if (err < 0)
+		dev_err(&scs->unit->device, "HSS1394 communication failed\n");
+
+	return err;
+}
+
+static void scs_card_free(struct snd_card *card)
+{
+	struct scs *scs = card->private_data;
+
+	fw_core_remove_address_handler(&scs->hss_handler);
+	kfree(scs->buffer);
+}
+
+static int scs_probe(struct device *unit_dev)
+{
+	struct fw_unit *unit = fw_unit(unit_dev);
+	struct fw_device *fw_dev = fw_parent_device(unit);
+	struct snd_card *card;
+	struct scs *scs;
+	int err;
+
+	err = snd_card_create(-16, NULL, THIS_MODULE, sizeof(*scs), &card);
+	if (err < 0)
+		return err;
+	snd_card_set_dev(card, unit_dev);
+
+	scs = card->private_data;
+	scs->card = card;
+	scs->unit = unit;
+	tasklet_init(&scs->tasklet, scs_output_tasklet, (unsigned long)scs);
+	init_waitqueue_head(&scs->idle_wait);
+	scs->output_idle = true;
+
+	scs->buffer = kmalloc(HSS1394_MAX_PACKET_SIZE, GFP_KERNEL);
+	if (!scs->buffer)
+		goto err_card;
+
+	scs->hss_handler.length = HSS1394_MAX_PACKET_SIZE;
+	scs->hss_handler.address_callback = handle_hss;
+	scs->hss_handler.callback_data = scs;
+	err = fw_core_add_address_handler(&scs->hss_handler,
+					  &fw_high_memory_region);
+	if (err < 0)
+		goto err_buffer;
+
+	card->private_free = scs_card_free;
+
+	strcpy(card->driver, "SCS.1x");
+	strcpy(card->shortname, "SCS.1x");
+	fw_csr_string(unit->directory, CSR_MODEL,
+		      card->shortname, sizeof(card->shortname));
+	snprintf(card->longname, sizeof(card->longname),
+		 "Stanton DJ %s (GUID %08x%08x) at %s, S%d",
+		 card->shortname, fw_dev->config_rom[3], fw_dev->config_rom[4],
+		 dev_name(&unit->device), 100 << fw_dev->max_speed);
+	strcpy(card->mixername, card->shortname);
+
+	err = scs_init_hss_address(scs);
+	if (err < 0)
+		goto err_card;
+
+	err = scs_create_midi(scs);
+	if (err < 0)
+		goto err_card;
+
+	err = snd_card_register(card);
+	if (err < 0)
+		goto err_card;
+
+	dev_set_drvdata(unit_dev, scs);
+
+	return 0;
+
+err_buffer:
+	kfree(scs->buffer);
+err_card:
+	snd_card_free(card);
+	return err;
+}
+
+static int scs_remove(struct device *dev)
+{
+	struct scs *scs = dev_get_drvdata(dev);
+
+	snd_card_disconnect(scs->card);
+
+	ACCESS_ONCE(scs->output) = NULL;
+	ACCESS_ONCE(scs->input) = NULL;
+
+	wait_event(scs->idle_wait, scs->output_idle);
+
+	tasklet_kill(&scs->tasklet);
+
+	snd_card_free_when_closed(scs->card);
+
+	return 0;
+}
+
+static void scs_update(struct fw_unit *unit)
+{
+	struct scs *scs = dev_get_drvdata(&unit->device);
+	__be64 data;
+
+	data = cpu_to_be64(((u64)HSS1394_TAG_CHANGE_ADDRESS << 56) |
+			   scs->hss_handler.offset);
+	snd_fw_transaction(scs->unit, TCODE_WRITE_BLOCK_REQUEST,
+			   HSS1394_ADDRESS, &data, 8);
+}
+
+static const struct ieee1394_device_id scs_id_table[] = {
+	{
+		.match_flags = IEEE1394_MATCH_VENDOR_ID |
+		               IEEE1394_MATCH_MODEL_ID,
+		.vendor_id   = OUI_STANTON,
+		.model_id    = MODEL_SCS_1M,
+	},
+	{
+		.match_flags = IEEE1394_MATCH_VENDOR_ID |
+		               IEEE1394_MATCH_MODEL_ID,
+		.vendor_id   = OUI_STANTON,
+		.model_id    = MODEL_SCS_1D,
+	},
+	{}
+};
+MODULE_DEVICE_TABLE(ieee1394, scs_id_table);
+
+MODULE_DESCRIPTION("SCS.1x MIDI driver");
+MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>");
+MODULE_LICENSE("GPL v2");
+
+static struct fw_driver scs_driver = {
+	.driver = {
+		.owner  = THIS_MODULE,
+		.name   = KBUILD_MODNAME,
+		.bus    = &fw_bus_type,
+		.probe  = scs_probe,
+		.remove = scs_remove,
+	},
+	.update   = scs_update,
+	.id_table = scs_id_table,
+};
+
+static int __init alsa_scs1x_init(void)
+{
+	return driver_register(&scs_driver.driver);
+}
+
+static void __exit alsa_scs1x_exit(void)
+{
+	driver_unregister(&scs_driver.driver);
+}
+
+module_init(alsa_scs1x_init);
+module_exit(alsa_scs1x_exit);
diff --git a/sound/firewire/speakers.c b/sound/firewire/speakers.c
index 297244e..d684655 100644
--- a/sound/firewire/speakers.c
+++ b/sound/firewire/speakers.c
@@ -663,7 +663,7 @@
 	mutex_destroy(&fwspk->mutex);
 }
 
-static const struct device_info *__devinit fwspk_detect(struct fw_device *dev)
+static const struct device_info *fwspk_detect(struct fw_device *dev)
 {
 	static const struct device_info griffin_firewave = {
 		.driver_name = "FireWave",
@@ -699,7 +699,7 @@
 	return NULL;
 }
 
-static int __devinit fwspk_probe(struct device *unit_dev)
+static int fwspk_probe(struct device *unit_dev)
 {
 	struct fw_unit *unit = fw_unit(unit_dev);
 	struct fw_device *fw_dev = fw_parent_device(unit);
@@ -770,7 +770,7 @@
 	return err;
 }
 
-static int __devexit fwspk_remove(struct device *dev)
+static int fwspk_remove(struct device *dev)
 {
 	struct fwspk *fwspk = dev_get_drvdata(dev);
 
@@ -834,7 +834,7 @@
 		.name	= KBUILD_MODNAME,
 		.bus	= &fw_bus_type,
 		.probe	= fwspk_probe,
-		.remove	= __devexit_p(fwspk_remove),
+		.remove	= fwspk_remove,
 	},
 	.update   = fwspk_bus_reset,
 	.id_table = fwspk_id_table,
diff --git a/sound/isa/Kconfig b/sound/isa/Kconfig
index a38d964..affa134 100644
--- a/sound/isa/Kconfig
+++ b/sound/isa/Kconfig
@@ -425,7 +425,7 @@
 
 config SND_MSND_PINNACLE
 	tristate "Turtle Beach MultiSound Pinnacle/Fiji driver"
-	depends on X86 && EXPERIMENTAL
+	depends on X86
 	select FW_LOADER
 	select SND_MPU401_UART
 	select SND_PCM
@@ -438,7 +438,7 @@
 
 config SND_MSND_CLASSIC
 	tristate "Support for Turtle Beach MultiSound Classic, Tahiti, Monterey"
-	depends on X86 && EXPERIMENTAL
+	depends on X86
 	select FW_LOADER
 	select SND_MPU401_UART
 	select SND_PCM
diff --git a/sound/isa/ad1816a/ad1816a.c b/sound/isa/ad1816a/ad1816a.c
index 2c2f829..26ce26a 100644
--- a/sound/isa/ad1816a/ad1816a.c
+++ b/sound/isa/ad1816a/ad1816a.c
@@ -94,8 +94,8 @@
 #define	DRIVER_NAME	"snd-card-ad1816a"
 
 
-static int __devinit snd_card_ad1816a_pnp(int dev, struct pnp_card_link *card,
-					  const struct pnp_card_device_id *id)
+static int snd_card_ad1816a_pnp(int dev, struct pnp_card_link *card,
+				const struct pnp_card_device_id *id)
 {
 	struct pnp_dev *pdev;
 	int err;
@@ -135,8 +135,8 @@
 	return 0;
 }
 
-static int __devinit snd_card_ad1816a_probe(int dev, struct pnp_card_link *pcard,
-					    const struct pnp_card_device_id *pid)
+static int snd_card_ad1816a_probe(int dev, struct pnp_card_link *pcard,
+				  const struct pnp_card_device_id *pid)
 {
 	int error;
 	struct snd_card *card;
@@ -217,10 +217,10 @@
 	return 0;
 }
 
-static unsigned int __devinitdata ad1816a_devices;
+static unsigned int ad1816a_devices;
 
-static int __devinit snd_ad1816a_pnp_detect(struct pnp_card_link *card,
-					    const struct pnp_card_device_id *id)
+static int snd_ad1816a_pnp_detect(struct pnp_card_link *card,
+				  const struct pnp_card_device_id *id)
 {
 	static int dev;
 	int res;
@@ -238,7 +238,7 @@
         return -ENODEV;
 }
 
-static void __devexit snd_ad1816a_pnp_remove(struct pnp_card_link * pcard)
+static void snd_ad1816a_pnp_remove(struct pnp_card_link *pcard)
 {
 	snd_card_free(pnp_get_card_drvdata(pcard));
 	pnp_set_card_drvdata(pcard, NULL);
@@ -270,7 +270,7 @@
 	.name		= "ad1816a",
 	.id_table	= snd_ad1816a_pnpids,
 	.probe		= snd_ad1816a_pnp_detect,
-	.remove		= __devexit_p(snd_ad1816a_pnp_remove),
+	.remove		= snd_ad1816a_pnp_remove,
 #ifdef CONFIG_PM
 	.suspend	= snd_ad1816a_pnp_suspend,
 	.resume		= snd_ad1816a_pnp_resume,
diff --git a/sound/isa/ad1816a/ad1816a_lib.c b/sound/isa/ad1816a/ad1816a_lib.c
index db64df6..f0fd98e 100644
--- a/sound/isa/ad1816a/ad1816a_lib.c
+++ b/sound/isa/ad1816a/ad1816a_lib.c
@@ -537,7 +537,7 @@
 }
 #endif
 
-static int __devinit snd_ad1816a_probe(struct snd_ad1816a *chip)
+static int snd_ad1816a_probe(struct snd_ad1816a *chip)
 {
 	unsigned long flags;
 
@@ -583,7 +583,7 @@
 	return snd_ad1816a_free(chip);
 }
 
-static const char __devinit *snd_ad1816a_chip_id(struct snd_ad1816a *chip)
+static const char *snd_ad1816a_chip_id(struct snd_ad1816a *chip)
 {
 	switch (chip->hardware) {
 	case AD1816A_HW_AD1816A: return "AD1816A";
@@ -596,9 +596,9 @@
 	}
 }
 
-int __devinit snd_ad1816a_create(struct snd_card *card,
-				 unsigned long port, int irq, int dma1, int dma2,
-				 struct snd_ad1816a *chip)
+int snd_ad1816a_create(struct snd_card *card,
+		       unsigned long port, int irq, int dma1, int dma2,
+		       struct snd_ad1816a *chip)
 {
         static struct snd_device_ops ops = {
 		.dev_free =	snd_ad1816a_dev_free,
@@ -675,7 +675,7 @@
 	.pointer =	snd_ad1816a_capture_pointer,
 };
 
-int __devinit snd_ad1816a_pcm(struct snd_ad1816a *chip, int device, struct snd_pcm **rpcm)
+int snd_ad1816a_pcm(struct snd_ad1816a *chip, int device, struct snd_pcm **rpcm)
 {
 	int error;
 	struct snd_pcm *pcm;
@@ -702,7 +702,8 @@
 	return 0;
 }
 
-int __devinit snd_ad1816a_timer(struct snd_ad1816a *chip, int device, struct snd_timer **rtimer)
+int snd_ad1816a_timer(struct snd_ad1816a *chip, int device,
+		      struct snd_timer **rtimer)
 {
 	struct snd_timer *timer;
 	struct snd_timer_id tid;
@@ -923,7 +924,7 @@
 static const DECLARE_TLV_DB_SCALE(db_scale_5bit_12db_max, -3450, 150, 0);
 static const DECLARE_TLV_DB_SCALE(db_scale_rec_gain, 0, 150, 0);
 
-static struct snd_kcontrol_new snd_ad1816a_controls[] __devinitdata = {
+static struct snd_kcontrol_new snd_ad1816a_controls[] = {
 AD1816A_DOUBLE("Master Playback Switch", AD1816A_MASTER_ATT, 15, 7, 1, 1),
 AD1816A_DOUBLE_TLV("Master Playback Volume", AD1816A_MASTER_ATT, 8, 0, 31, 1,
 		   db_scale_5bit),
@@ -969,7 +970,7 @@
 AD1816A_SINGLE("3D Control - Level", AD1816A_3D_PHAT_CTRL, 0, 15, 0),
 };
                                         
-int __devinit snd_ad1816a_mixer(struct snd_ad1816a *chip)
+int snd_ad1816a_mixer(struct snd_ad1816a *chip)
 {
 	struct snd_card *card;
 	unsigned int idx;
diff --git a/sound/isa/ad1848/ad1848.c b/sound/isa/ad1848/ad1848.c
index 2af77fa..c214ecf 100644
--- a/sound/isa/ad1848/ad1848.c
+++ b/sound/isa/ad1848/ad1848.c
@@ -64,7 +64,7 @@
 module_param_array(thinkpad, bool, NULL, 0444);
 MODULE_PARM_DESC(thinkpad, "Enable only for the onboard CS4248 of IBM Thinkpad 360/750/755 series.");
 
-static int __devinit snd_ad1848_match(struct device *dev, unsigned int n)
+static int snd_ad1848_match(struct device *dev, unsigned int n)
 {
 	if (!enable[n])
 		return 0;
@@ -84,7 +84,7 @@
 	return 1;
 }
 
-static int __devinit snd_ad1848_probe(struct device *dev, unsigned int n)
+static int snd_ad1848_probe(struct device *dev, unsigned int n)
 {
 	struct snd_card *card;
 	struct snd_wss *chip;
@@ -132,7 +132,7 @@
 	return error;
 }
 
-static int __devexit snd_ad1848_remove(struct device *dev, unsigned int n)
+static int snd_ad1848_remove(struct device *dev, unsigned int n)
 {
 	snd_card_free(dev_get_drvdata(dev));
 	dev_set_drvdata(dev, NULL);
@@ -164,7 +164,7 @@
 static struct isa_driver snd_ad1848_driver = {
 	.match		= snd_ad1848_match,
 	.probe		= snd_ad1848_probe,
-	.remove		= __devexit_p(snd_ad1848_remove),
+	.remove		= snd_ad1848_remove,
 #ifdef CONFIG_PM
 	.suspend	= snd_ad1848_suspend,
 	.resume		= snd_ad1848_resume,
diff --git a/sound/isa/adlib.c b/sound/isa/adlib.c
index 4d50c69..d265455 100644
--- a/sound/isa/adlib.c
+++ b/sound/isa/adlib.c
@@ -30,7 +30,7 @@
 module_param_array(port, long, NULL, 0444);
 MODULE_PARM_DESC(port, "Port # for " CRD_NAME " driver.");
 
-static int __devinit snd_adlib_match(struct device *dev, unsigned int n)
+static int snd_adlib_match(struct device *dev, unsigned int n)
 {
 	if (!enable[n])
 		return 0;
@@ -47,7 +47,7 @@
 	release_and_free_resource(card->private_data);
 }
 
-static int __devinit snd_adlib_probe(struct device *dev, unsigned int n)
+static int snd_adlib_probe(struct device *dev, unsigned int n)
 {
 	struct snd_card *card;
 	struct snd_opl3 *opl3;
@@ -98,7 +98,7 @@
 	return error;
 }
 
-static int __devexit snd_adlib_remove(struct device *dev, unsigned int n)
+static int snd_adlib_remove(struct device *dev, unsigned int n)
 {
 	snd_card_free(dev_get_drvdata(dev));
 	dev_set_drvdata(dev, NULL);
@@ -108,7 +108,7 @@
 static struct isa_driver snd_adlib_driver = {
 	.match		= snd_adlib_match,
 	.probe		= snd_adlib_probe,
-	.remove		= __devexit_p(snd_adlib_remove),
+	.remove		= snd_adlib_remove,
 
 	.driver		= {
 		.name	= DEV_NAME
diff --git a/sound/isa/als100.c b/sound/isa/als100.c
index f7cdaf5..10f08a1 100644
--- a/sound/isa/als100.c
+++ b/sound/isa/als100.c
@@ -117,9 +117,9 @@
 
 MODULE_DEVICE_TABLE(pnp_card, snd_als100_pnpids);
 
-static int __devinit snd_card_als100_pnp(int dev, struct snd_card_als100 *acard,
-					 struct pnp_card_link *card,
-					 const struct pnp_card_device_id *id)
+static int snd_card_als100_pnp(int dev, struct snd_card_als100 *acard,
+			       struct pnp_card_link *card,
+			       const struct pnp_card_device_id *id)
 {
 	struct pnp_dev *pdev;
 	int err;
@@ -183,9 +183,9 @@
 	return 0;
 }
 
-static int __devinit snd_card_als100_probe(int dev,
-					struct pnp_card_link *pcard,
-					const struct pnp_card_device_id *pid)
+static int snd_card_als100_probe(int dev,
+				 struct pnp_card_link *pcard,
+				 const struct pnp_card_device_id *pid)
 {
 	int error;
 	struct snd_sb *chip;
@@ -286,10 +286,10 @@
 	return 0;
 }
 
-static unsigned int __devinitdata als100_devices;
+static unsigned int als100_devices;
 
-static int __devinit snd_als100_pnp_detect(struct pnp_card_link *card,
-					   const struct pnp_card_device_id *id)
+static int snd_als100_pnp_detect(struct pnp_card_link *card,
+				 const struct pnp_card_device_id *id)
 {
 	static int dev;
 	int res;
@@ -307,7 +307,7 @@
 	return -ENODEV;
 }
 
-static void __devexit snd_als100_pnp_remove(struct pnp_card_link * pcard)
+static void snd_als100_pnp_remove(struct pnp_card_link *pcard)
 {
 	snd_card_free(pnp_get_card_drvdata(pcard));
 	pnp_set_card_drvdata(pcard, NULL);
@@ -344,7 +344,7 @@
 	.name		= "als100",
         .id_table       = snd_als100_pnpids,
         .probe          = snd_als100_pnp_detect,
-        .remove         = __devexit_p(snd_als100_pnp_remove),
+	.remove		= snd_als100_pnp_remove,
 #ifdef CONFIG_PM
 	.suspend	= snd_als100_pnp_suspend,
 	.resume		= snd_als100_pnp_resume,
diff --git a/sound/isa/azt2320.c b/sound/isa/azt2320.c
index 6a2c78e..db301ff 100644
--- a/sound/isa/azt2320.c
+++ b/sound/isa/azt2320.c
@@ -99,9 +99,9 @@
 
 #define	DRIVER_NAME	"snd-card-azt2320"
 
-static int __devinit snd_card_azt2320_pnp(int dev, struct snd_card_azt2320 *acard,
-					  struct pnp_card_link *card,
-					  const struct pnp_card_device_id *id)
+static int snd_card_azt2320_pnp(int dev, struct snd_card_azt2320 *acard,
+				struct pnp_card_link *card,
+				const struct pnp_card_device_id *id)
 {
 	struct pnp_dev *pdev;
 	int err;
@@ -147,7 +147,7 @@
 }
 
 /* same of snd_sbdsp_command by Jaroslav Kysela */
-static int __devinit snd_card_azt2320_command(unsigned long port, unsigned char val)
+static int snd_card_azt2320_command(unsigned long port, unsigned char val)
 {
 	int i;
 	unsigned long limit;
@@ -161,7 +161,7 @@
 	return -EBUSY;
 }
 
-static int __devinit snd_card_azt2320_enable_wss(unsigned long port)
+static int snd_card_azt2320_enable_wss(unsigned long port)
 {
 	int error;
 
@@ -174,9 +174,9 @@
 	return 0;
 }
 
-static int __devinit snd_card_azt2320_probe(int dev,
-					    struct pnp_card_link *pcard,
-					    const struct pnp_card_device_id *pid)
+static int snd_card_azt2320_probe(int dev,
+				  struct pnp_card_link *pcard,
+				  const struct pnp_card_device_id *pid)
 {
 	int error;
 	struct snd_card *card;
@@ -264,10 +264,10 @@
 	return 0;
 }
 
-static unsigned int __devinitdata azt2320_devices;
+static unsigned int azt2320_devices;
 
-static int __devinit snd_azt2320_pnp_detect(struct pnp_card_link *card,
-					    const struct pnp_card_device_id *id)
+static int snd_azt2320_pnp_detect(struct pnp_card_link *card,
+				  const struct pnp_card_device_id *id)
 {
 	static int dev;
 	int res;
@@ -285,7 +285,7 @@
         return -ENODEV;
 }
 
-static void __devexit snd_azt2320_pnp_remove(struct pnp_card_link * pcard)
+static void snd_azt2320_pnp_remove(struct pnp_card_link *pcard)
 {
 	snd_card_free(pnp_get_card_drvdata(pcard));
 	pnp_set_card_drvdata(pcard, NULL);
@@ -320,7 +320,7 @@
 	.name           = "azt2320",
 	.id_table       = snd_azt2320_pnpids,
 	.probe          = snd_azt2320_pnp_detect,
-	.remove         = __devexit_p(snd_azt2320_pnp_remove),
+	.remove         = snd_azt2320_pnp_remove,
 #ifdef CONFIG_PM
 	.suspend	= snd_azt2320_pnp_suspend,
 	.resume		= snd_azt2320_pnp_resume,
diff --git a/sound/isa/cmi8328.c b/sound/isa/cmi8328.c
index bde6013..a7369fe 100644
--- a/sound/isa/cmi8328.c
+++ b/sound/isa/cmi8328.c
@@ -140,7 +140,7 @@
 	snd_cmi8328_cfg_write(port, CFG3, cfg[2]);
 }
 
-static int __devinit snd_cmi8328_mixer(struct snd_wss *chip)
+static int snd_cmi8328_mixer(struct snd_wss *chip)
 {
 	struct snd_card *card;
 	struct snd_ctl_elem_id id1, id2;
@@ -212,7 +212,7 @@
 	return -1;
 }
 
-static int __devinit snd_cmi8328_probe(struct device *pdev, unsigned int ndev)
+static int snd_cmi8328_probe(struct device *pdev, unsigned int ndev)
 {
 	struct snd_card *card;
 	struct snd_opl3 *opl3;
@@ -401,7 +401,7 @@
 	return err;
 }
 
-static int __devexit snd_cmi8328_remove(struct device *pdev, unsigned int dev)
+static int snd_cmi8328_remove(struct device *pdev, unsigned int dev)
 {
 	struct snd_card *card = dev_get_drvdata(pdev);
 	struct snd_cmi8328 *cmi = card->private_data;
@@ -459,7 +459,7 @@
 
 static struct isa_driver snd_cmi8328_driver = {
 	.probe		= snd_cmi8328_probe,
-	.remove		= __devexit_p(snd_cmi8328_remove),
+	.remove		= snd_cmi8328_remove,
 #ifdef CONFIG_PM
 	.suspend	= snd_cmi8328_suspend,
 	.resume		= snd_cmi8328_resume,
diff --git a/sound/isa/cmi8330.c b/sound/isa/cmi8330.c
index 7bd5e33..c707c52 100644
--- a/sound/isa/cmi8330.c
+++ b/sound/isa/cmi8330.c
@@ -193,7 +193,7 @@
 #endif
 
 
-static struct snd_kcontrol_new snd_cmi8330_controls[] __devinitdata = {
+static struct snd_kcontrol_new snd_cmi8330_controls[] = {
 WSS_DOUBLE("Master Playback Volume", 0,
 		CMI8330_MASTVOL, CMI8330_MASTVOL, 4, 0, 15, 0),
 WSS_SINGLE("Loud Playback Switch", 0,
@@ -249,7 +249,7 @@
 };
 
 #ifdef ENABLE_SB_MIXER
-static struct sbmix_elem cmi8330_sb_mixers[] __devinitdata = {
+static struct sbmix_elem cmi8330_sb_mixers[] = {
 SB_DOUBLE("SB Master Playback Volume", SB_DSP4_MASTER_DEV, (SB_DSP4_MASTER_DEV + 1), 3, 3, 31),
 SB_DOUBLE("Tone Control - Bass", SB_DSP4_BASS_DEV, (SB_DSP4_BASS_DEV + 1), 4, 4, 15),
 SB_DOUBLE("Tone Control - Treble", SB_DSP4_TREBLE_DEV, (SB_DSP4_TREBLE_DEV + 1), 4, 4, 15),
@@ -267,7 +267,7 @@
 SB_SINGLE("SB Mic Auto Gain", SB_DSP4_MIC_AGC, 0, 1),
 };
 
-static unsigned char cmi8330_sb_init_values[][2] __devinitdata = {
+static unsigned char cmi8330_sb_init_values[][2] = {
 	{ SB_DSP4_MASTER_DEV + 0, 0 },
 	{ SB_DSP4_MASTER_DEV + 1, 0 },
 	{ SB_DSP4_PCM_DEV + 0, 0 },
@@ -281,7 +281,7 @@
 };
 
 
-static int __devinit cmi8330_add_sb_mixers(struct snd_sb *chip)
+static int cmi8330_add_sb_mixers(struct snd_sb *chip)
 {
 	int idx, err;
 	unsigned long flags;
@@ -306,7 +306,7 @@
 }
 #endif
 
-static int __devinit snd_cmi8330_mixer(struct snd_card *card, struct snd_cmi8330 *acard)
+static int snd_cmi8330_mixer(struct snd_card *card, struct snd_cmi8330 *acard)
 {
 	unsigned int idx;
 	int err;
@@ -329,9 +329,9 @@
 }
 
 #ifdef CONFIG_PNP
-static int __devinit snd_cmi8330_pnp(int dev, struct snd_cmi8330 *acard,
-				     struct pnp_card_link *card,
-				     const struct pnp_card_device_id *id)
+static int snd_cmi8330_pnp(int dev, struct snd_cmi8330 *acard,
+			   struct pnp_card_link *card,
+			   const struct pnp_card_device_id *id)
 {
 	struct pnp_dev *pdev;
 	int err;
@@ -437,7 +437,7 @@
 	return chip->streams[SNDRV_PCM_STREAM_CAPTURE].open(substream);
 }
 
-static int __devinit snd_cmi8330_pcm(struct snd_card *card, struct snd_cmi8330 *chip)
+static int snd_cmi8330_pcm(struct snd_card *card, struct snd_cmi8330 *chip)
 {
 	struct snd_pcm *pcm;
 	const struct snd_pcm_ops *ops;
@@ -532,7 +532,7 @@
 	return 0;
 }
 
-static int __devinit snd_cmi8330_probe(struct snd_card *card, int dev)
+static int snd_cmi8330_probe(struct snd_card *card, int dev)
 {
 	struct snd_cmi8330 *acard;
 	int i, err;
@@ -613,8 +613,8 @@
 	return snd_card_register(card);
 }
 
-static int __devinit snd_cmi8330_isa_match(struct device *pdev,
-					   unsigned int dev)
+static int snd_cmi8330_isa_match(struct device *pdev,
+				 unsigned int dev)
 {
 	if (!enable[dev] || is_isapnp_selected(dev))
 		return 0;
@@ -629,8 +629,8 @@
 	return 1;
 }
 
-static int __devinit snd_cmi8330_isa_probe(struct device *pdev,
-					   unsigned int dev)
+static int snd_cmi8330_isa_probe(struct device *pdev,
+				 unsigned int dev)
 {
 	struct snd_card *card;
 	int err;
@@ -647,8 +647,8 @@
 	return 0;
 }
 
-static int __devexit snd_cmi8330_isa_remove(struct device *devptr,
-					    unsigned int dev)
+static int snd_cmi8330_isa_remove(struct device *devptr,
+				  unsigned int dev)
 {
 	snd_card_free(dev_get_drvdata(devptr));
 	dev_set_drvdata(devptr, NULL);
@@ -673,7 +673,7 @@
 static struct isa_driver snd_cmi8330_driver = {
 	.match		= snd_cmi8330_isa_match,
 	.probe		= snd_cmi8330_isa_probe,
-	.remove		= __devexit_p(snd_cmi8330_isa_remove),
+	.remove		= snd_cmi8330_isa_remove,
 #ifdef CONFIG_PM
 	.suspend	= snd_cmi8330_isa_suspend,
 	.resume		= snd_cmi8330_isa_resume,
@@ -685,8 +685,8 @@
 
 
 #ifdef CONFIG_PNP
-static int __devinit snd_cmi8330_pnp_detect(struct pnp_card_link *pcard,
-					    const struct pnp_card_device_id *pid)
+static int snd_cmi8330_pnp_detect(struct pnp_card_link *pcard,
+				  const struct pnp_card_device_id *pid)
 {
 	static int dev;
 	struct snd_card *card;
@@ -717,7 +717,7 @@
 	return 0;
 }
 
-static void __devexit snd_cmi8330_pnp_remove(struct pnp_card_link * pcard)
+static void snd_cmi8330_pnp_remove(struct pnp_card_link *pcard)
 {
 	snd_card_free(pnp_get_card_drvdata(pcard));
 	pnp_set_card_drvdata(pcard, NULL);
@@ -740,7 +740,7 @@
 	.name = "cmi8330",
 	.id_table = snd_cmi8330_pnpids,
 	.probe = snd_cmi8330_pnp_detect,
-	.remove = __devexit_p(snd_cmi8330_pnp_remove),
+	.remove = snd_cmi8330_pnp_remove,
 #ifdef CONFIG_PM
 	.suspend	= snd_cmi8330_pnp_suspend,
 	.resume		= snd_cmi8330_pnp_resume,
diff --git a/sound/isa/cs423x/cs4231.c b/sound/isa/cs423x/cs4231.c
index 99dda45..aa7a5d8 100644
--- a/sound/isa/cs423x/cs4231.c
+++ b/sound/isa/cs423x/cs4231.c
@@ -68,7 +68,7 @@
 module_param_array(dma2, int, NULL, 0444);
 MODULE_PARM_DESC(dma2, "DMA2 # for " CRD_NAME " driver.");
 
-static int __devinit snd_cs4231_match(struct device *dev, unsigned int n)
+static int snd_cs4231_match(struct device *dev, unsigned int n)
 {
 	if (!enable[n])
 		return 0;
@@ -88,7 +88,7 @@
 	return 1;
 }
 
-static int __devinit snd_cs4231_probe(struct device *dev, unsigned int n)
+static int snd_cs4231_probe(struct device *dev, unsigned int n)
 {
 	struct snd_card *card;
 	struct snd_wss *chip;
@@ -148,7 +148,7 @@
 	return error;
 }
 
-static int __devexit snd_cs4231_remove(struct device *dev, unsigned int n)
+static int snd_cs4231_remove(struct device *dev, unsigned int n)
 {
 	snd_card_free(dev_get_drvdata(dev));
 	dev_set_drvdata(dev, NULL);
@@ -180,7 +180,7 @@
 static struct isa_driver snd_cs4231_driver = {
 	.match		= snd_cs4231_match,
 	.probe		= snd_cs4231_probe,
-	.remove		= __devexit_p(snd_cs4231_remove),
+	.remove		= snd_cs4231_remove,
 #ifdef CONFIG_PM
 	.suspend	= snd_cs4231_suspend,
 	.resume		= snd_cs4231_resume,
diff --git a/sound/isa/cs423x/cs4236.c b/sound/isa/cs423x/cs4236.c
index 740c51a..252e9fb 100644
--- a/sound/isa/cs423x/cs4236.c
+++ b/sound/isa/cs423x/cs4236.c
@@ -251,7 +251,7 @@
 MODULE_DEVICE_TABLE(pnp_card, snd_cs423x_pnpids);
 
 /* WSS initialization */
-static int __devinit snd_cs423x_pnp_init_wss(int dev, struct pnp_dev *pdev)
+static int snd_cs423x_pnp_init_wss(int dev, struct pnp_dev *pdev)
 {
 	if (pnp_activate_dev(pdev) < 0) {
 		printk(KERN_ERR IDENT " WSS PnP configure failed for WSS (out of resources?)\n");
@@ -272,7 +272,7 @@
 }
 
 /* CTRL initialization */
-static int __devinit snd_cs423x_pnp_init_ctrl(int dev, struct pnp_dev *pdev)
+static int snd_cs423x_pnp_init_ctrl(int dev, struct pnp_dev *pdev)
 {
 	if (pnp_activate_dev(pdev) < 0) {
 		printk(KERN_ERR IDENT " CTRL PnP configure failed for WSS (out of resources?)\n");
@@ -284,7 +284,7 @@
 }
 
 /* MPU initialization */
-static int __devinit snd_cs423x_pnp_init_mpu(int dev, struct pnp_dev *pdev)
+static int snd_cs423x_pnp_init_mpu(int dev, struct pnp_dev *pdev)
 {
 	if (pnp_activate_dev(pdev) < 0) {
 		printk(KERN_ERR IDENT " MPU401 PnP configure failed for WSS (out of resources?)\n");
@@ -303,9 +303,9 @@
 	return 0;
 }
 
-static int __devinit snd_card_cs423x_pnp(int dev, struct snd_card_cs4236 *acard,
-					 struct pnp_dev *pdev,
-					 struct pnp_dev *cdev)
+static int snd_card_cs423x_pnp(int dev, struct snd_card_cs4236 *acard,
+			       struct pnp_dev *pdev,
+			       struct pnp_dev *cdev)
 {
 	acard->wss = pdev;
 	if (snd_cs423x_pnp_init_wss(dev, acard->wss) < 0)
@@ -317,9 +317,9 @@
 	return 0;
 }
 
-static int __devinit snd_card_cs423x_pnpc(int dev, struct snd_card_cs4236 *acard,
-					  struct pnp_card_link *card,
-					  const struct pnp_card_device_id *id)
+static int snd_card_cs423x_pnpc(int dev, struct snd_card_cs4236 *acard,
+				struct pnp_card_link *card,
+				const struct pnp_card_device_id *id)
 {
 	acard->wss = pnp_request_card_device(card, id->devs[0].id, NULL);
 	if (acard->wss == NULL)
@@ -378,7 +378,7 @@
 	return 0;
 }
 
-static int __devinit snd_cs423x_probe(struct snd_card *card, int dev)
+static int snd_cs423x_probe(struct snd_card *card, int dev)
 {
 	struct snd_card_cs4236 *acard;
 	struct snd_pcm *pcm;
@@ -456,8 +456,8 @@
 	return snd_card_register(card);
 }
 
-static int __devinit snd_cs423x_isa_match(struct device *pdev,
-					  unsigned int dev)
+static int snd_cs423x_isa_match(struct device *pdev,
+				unsigned int dev)
 {
 	if (!enable[dev] || is_isapnp_selected(dev))
 		return 0;
@@ -481,8 +481,8 @@
 	return 1;
 }
 
-static int __devinit snd_cs423x_isa_probe(struct device *pdev,
-					  unsigned int dev)
+static int snd_cs423x_isa_probe(struct device *pdev,
+				unsigned int dev)
 {
 	struct snd_card *card;
 	int err;
@@ -500,8 +500,8 @@
 	return 0;
 }
 
-static int __devexit snd_cs423x_isa_remove(struct device *pdev,
-					   unsigned int dev)
+static int snd_cs423x_isa_remove(struct device *pdev,
+				 unsigned int dev)
 {
 	snd_card_free(dev_get_drvdata(pdev));
 	dev_set_drvdata(pdev, NULL);
@@ -540,7 +540,7 @@
 static struct isa_driver cs423x_isa_driver = {
 	.match		= snd_cs423x_isa_match,
 	.probe		= snd_cs423x_isa_probe,
-	.remove		= __devexit_p(snd_cs423x_isa_remove),
+	.remove		= snd_cs423x_isa_remove,
 #ifdef CONFIG_PM
 	.suspend	= snd_cs423x_isa_suspend,
 	.resume		= snd_cs423x_isa_resume,
@@ -552,8 +552,8 @@
 
 
 #ifdef CONFIG_PNP
-static int __devinit snd_cs423x_pnpbios_detect(struct pnp_dev *pdev,
-					       const struct pnp_device_id *id)
+static int snd_cs423x_pnpbios_detect(struct pnp_dev *pdev,
+				     const struct pnp_device_id *id)
 {
 	static int dev;
 	int err;
@@ -597,7 +597,7 @@
 	return 0;
 }
 
-static void __devexit snd_cs423x_pnp_remove(struct pnp_dev *pdev)
+static void snd_cs423x_pnp_remove(struct pnp_dev *pdev)
 {
 	snd_card_free(pnp_get_drvdata(pdev));
 	pnp_set_drvdata(pdev, NULL);
@@ -619,15 +619,15 @@
 	.name = "cs423x-pnpbios",
 	.id_table = snd_cs423x_pnpbiosids,
 	.probe = snd_cs423x_pnpbios_detect,
-	.remove = __devexit_p(snd_cs423x_pnp_remove),
+	.remove = snd_cs423x_pnp_remove,
 #ifdef CONFIG_PM
 	.suspend	= snd_cs423x_pnp_suspend,
 	.resume		= snd_cs423x_pnp_resume,
 #endif
 };
 
-static int __devinit snd_cs423x_pnpc_detect(struct pnp_card_link *pcard,
-					    const struct pnp_card_device_id *pid)
+static int snd_cs423x_pnpc_detect(struct pnp_card_link *pcard,
+				  const struct pnp_card_device_id *pid)
 {
 	static int dev;
 	struct snd_card *card;
@@ -659,7 +659,7 @@
 	return 0;
 }
 
-static void __devexit snd_cs423x_pnpc_remove(struct pnp_card_link * pcard)
+static void snd_cs423x_pnpc_remove(struct pnp_card_link *pcard)
 {
 	snd_card_free(pnp_get_card_drvdata(pcard));
 	pnp_set_card_drvdata(pcard, NULL);
@@ -682,7 +682,7 @@
 	.name = CS423X_ISAPNP_DRIVER,
 	.id_table = snd_cs423x_pnpids,
 	.probe = snd_cs423x_pnpc_detect,
-	.remove = __devexit_p(snd_cs423x_pnpc_remove),
+	.remove = snd_cs423x_pnpc_remove,
 #ifdef CONFIG_PM
 	.suspend	= snd_cs423x_pnpc_suspend,
 	.resume		= snd_cs423x_pnpc_resume,
diff --git a/sound/isa/es1688/es1688.c b/sound/isa/es1688/es1688.c
index b036e60..102874a 100644
--- a/sound/isa/es1688/es1688.c
+++ b/sound/isa/es1688/es1688.c
@@ -90,13 +90,13 @@
 #define is_isapnp_selected(dev)		0
 #endif
 
-static int __devinit snd_es1688_match(struct device *dev, unsigned int n)
+static int snd_es1688_match(struct device *dev, unsigned int n)
 {
 	return enable[n] && !is_isapnp_selected(n);
 }
 
-static int __devinit snd_es1688_legacy_create(struct snd_card *card,
-					struct device *dev, unsigned int n)
+static int snd_es1688_legacy_create(struct snd_card *card,
+				    struct device *dev, unsigned int n)
 {
 	struct snd_es1688 *chip = card->private_data;
 	static long possible_ports[] = {0x220, 0x240, 0x260};
@@ -134,7 +134,7 @@
 	return error;
 }
 
-static int __devinit snd_es1688_probe(struct snd_card *card, unsigned int n)
+static int snd_es1688_probe(struct snd_card *card, unsigned int n)
 {
 	struct snd_es1688 *chip = card->private_data;
 	struct snd_opl3 *opl3;
@@ -182,7 +182,7 @@
 	return snd_card_register(card);
 }
 
-static int __devinit snd_es1688_isa_probe(struct device *dev, unsigned int n)
+static int snd_es1688_isa_probe(struct device *dev, unsigned int n)
 {
 	struct snd_card *card;
 	int error;
@@ -210,7 +210,7 @@
 	return error;
 }
 
-static int __devexit snd_es1688_isa_remove(struct device *dev, unsigned int n)
+static int snd_es1688_isa_remove(struct device *dev, unsigned int n)
 {
 	snd_card_free(dev_get_drvdata(dev));
 	dev_set_drvdata(dev, NULL);
@@ -220,7 +220,7 @@
 static struct isa_driver snd_es1688_driver = {
 	.match		= snd_es1688_match,
 	.probe		= snd_es1688_isa_probe,
-	.remove		= __devexit_p(snd_es1688_isa_remove),
+	.remove		= snd_es1688_isa_remove,
 #if 0	/* FIXME */
 	.suspend	= snd_es1688_suspend,
 	.resume		= snd_es1688_resume,
@@ -233,9 +233,9 @@
 static int snd_es968_pnp_is_probed;
 
 #ifdef CONFIG_PNP
-static int __devinit snd_card_es968_pnp(struct snd_card *card, unsigned int n,
-					struct pnp_card_link *pcard,
-					const struct pnp_card_device_id *pid)
+static int snd_card_es968_pnp(struct snd_card *card, unsigned int n,
+			      struct pnp_card_link *pcard,
+			      const struct pnp_card_device_id *pid)
 {
 	struct snd_es1688 *chip = card->private_data;
 	struct pnp_dev *pdev;
@@ -258,8 +258,8 @@
 				 mpu_irq[n], dma8[n], ES1688_HW_AUTO);
 }
 
-static int __devinit snd_es968_pnp_detect(struct pnp_card_link *pcard,
-					  const struct pnp_card_device_id *pid)
+static int snd_es968_pnp_detect(struct pnp_card_link *pcard,
+				const struct pnp_card_device_id *pid)
 {
 	struct snd_card *card;
 	static unsigned int dev;
@@ -295,7 +295,7 @@
 	return 0;
 }
 
-static void __devexit snd_es968_pnp_remove(struct pnp_card_link * pcard)
+static void snd_es968_pnp_remove(struct pnp_card_link *pcard)
 {
 	snd_card_free(pnp_get_card_drvdata(pcard));
 	pnp_set_card_drvdata(pcard, NULL);
@@ -338,7 +338,7 @@
 	.name		= DEV_NAME " PnP",
 	.id_table	= snd_es968_pnpids,
 	.probe		= snd_es968_pnp_detect,
-	.remove		= __devexit_p(snd_es968_pnp_remove),
+	.remove		= snd_es968_pnp_remove,
 #ifdef CONFIG_PM
 	.suspend	= snd_es968_pnp_suspend,
 	.resume		= snd_es968_pnp_resume,
diff --git a/sound/isa/es18xx.c b/sound/isa/es18xx.c
index c20baaf..24380ef 100644
--- a/sound/isa/es18xx.c
+++ b/sound/isa/es18xx.c
@@ -348,7 +348,7 @@
 }
 
 
-static int __devinit snd_es18xx_reset(struct snd_es18xx *chip)
+static int snd_es18xx_reset(struct snd_es18xx *chip)
 {
 	int i;
         outb(0x03, chip->port + 0x06);
@@ -1363,7 +1363,7 @@
 ES18XX_SINGLE("Hardware Master Volume Split", 0, 0x64, 7, 1, 0),
 };
 
-static int __devinit snd_es18xx_config_read(struct snd_es18xx *chip, unsigned char reg)
+static int snd_es18xx_config_read(struct snd_es18xx *chip, unsigned char reg)
 {
 	int data;
 
@@ -1372,8 +1372,8 @@
 	return data;
 }
 
-static void __devinit snd_es18xx_config_write(struct snd_es18xx *chip, 
-					      unsigned char reg, unsigned char data)
+static void snd_es18xx_config_write(struct snd_es18xx *chip,
+				    unsigned char reg, unsigned char data)
 {
 	/* No need for spinlocks, this function is used only in
 	   otherwise protected init code */
@@ -1384,9 +1384,9 @@
 #endif
 }
 
-static int __devinit snd_es18xx_initialize(struct snd_es18xx *chip,
-					   unsigned long mpu_port,
-					   unsigned long fm_port)
+static int snd_es18xx_initialize(struct snd_es18xx *chip,
+				 unsigned long mpu_port,
+				 unsigned long fm_port)
 {
 	int mask = 0;
 
@@ -1549,7 +1549,7 @@
         return 0;
 }
 
-static int __devinit snd_es18xx_identify(struct snd_es18xx *chip)
+static int snd_es18xx_identify(struct snd_es18xx *chip)
 {
 	int hi,lo;
 
@@ -1618,9 +1618,9 @@
 	return 0;
 }
 
-static int __devinit snd_es18xx_probe(struct snd_es18xx *chip,
-					unsigned long mpu_port,
-					unsigned long fm_port)
+static int snd_es18xx_probe(struct snd_es18xx *chip,
+			    unsigned long mpu_port,
+			    unsigned long fm_port)
 {
 	if (snd_es18xx_identify(chip) < 0) {
 		snd_printk(KERN_ERR PFX "[0x%lx] ESS chip not found\n", chip->port);
@@ -1680,8 +1680,8 @@
 	.pointer =	snd_es18xx_capture_pointer,
 };
 
-static int __devinit snd_es18xx_pcm(struct snd_card *card, int device,
-				    struct snd_pcm **rpcm)
+static int snd_es18xx_pcm(struct snd_card *card, int device,
+			  struct snd_pcm **rpcm)
 {
 	struct snd_es18xx *chip = card->private_data;
         struct snd_pcm *pcm;
@@ -1777,11 +1777,11 @@
 	return snd_es18xx_free(device->card);
 }
 
-static int __devinit snd_es18xx_new_device(struct snd_card *card,
-					   unsigned long port,
-					   unsigned long mpu_port,
-					   unsigned long fm_port,
-					   int irq, int dma1, int dma2)
+static int snd_es18xx_new_device(struct snd_card *card,
+				 unsigned long port,
+				 unsigned long mpu_port,
+				 unsigned long fm_port,
+				 int irq, int dma1, int dma2)
 {
 	struct snd_es18xx *chip = card->private_data;
 	static struct snd_device_ops ops = {
@@ -1839,7 +1839,7 @@
         return 0;
 }
 
-static int __devinit snd_es18xx_mixer(struct snd_card *card)
+static int snd_es18xx_mixer(struct snd_card *card)
 {
 	struct snd_es18xx *chip = card->private_data;
 	int err;
@@ -2016,7 +2016,7 @@
 MODULE_DEVICE_TABLE(pnp, snd_audiodrive_pnpbiosids);
 
 /* PnP main device initialization */
-static int __devinit snd_audiodrive_pnp_init_main(int dev, struct pnp_dev *pdev)
+static int snd_audiodrive_pnp_init_main(int dev, struct pnp_dev *pdev)
 {
 	if (pnp_activate_dev(pdev) < 0) {
 		snd_printk(KERN_ERR PFX "PnP configure failure (out of resources?)\n");
@@ -2043,8 +2043,8 @@
 	return 0;
 }
 
-static int __devinit snd_audiodrive_pnp(int dev, struct snd_es18xx *chip,
-					struct pnp_dev *pdev)
+static int snd_audiodrive_pnp(int dev, struct snd_es18xx *chip,
+			      struct pnp_dev *pdev)
 {
 	chip->dev = pdev;
 	if (snd_audiodrive_pnp_init_main(dev, chip->dev) < 0)
@@ -2073,9 +2073,9 @@
 
 MODULE_DEVICE_TABLE(pnp_card, snd_audiodrive_pnpids);
 
-static int __devinit snd_audiodrive_pnpc(int dev, struct snd_es18xx *chip,
-					struct pnp_card_link *card,
-					const struct pnp_card_device_id *id)
+static int snd_audiodrive_pnpc(int dev, struct snd_es18xx *chip,
+			       struct pnp_card_link *card,
+			       const struct pnp_card_device_id *id)
 {
 	chip->dev = pnp_request_card_device(card, id->devs[0].id, NULL);
 	if (chip->dev == NULL)
@@ -2111,7 +2111,7 @@
 			       sizeof(struct snd_es18xx), cardp);
 }
 
-static int __devinit snd_audiodrive_probe(struct snd_card *card, int dev)
+static int snd_audiodrive_probe(struct snd_card *card, int dev)
 {
 	struct snd_es18xx *chip = card->private_data;
 	struct snd_opl3 *opl3;
@@ -2169,12 +2169,12 @@
 	return snd_card_register(card);
 }
 
-static int __devinit snd_es18xx_isa_match(struct device *pdev, unsigned int dev)
+static int snd_es18xx_isa_match(struct device *pdev, unsigned int dev)
 {
 	return enable[dev] && !is_isapnp_selected(dev);
 }
 
-static int __devinit snd_es18xx_isa_probe1(int dev, struct device *devptr)
+static int snd_es18xx_isa_probe1(int dev, struct device *devptr)
 {
 	struct snd_card *card;
 	int err;
@@ -2191,7 +2191,7 @@
 	return 0;
 }
 
-static int __devinit snd_es18xx_isa_probe(struct device *pdev, unsigned int dev)
+static int snd_es18xx_isa_probe(struct device *pdev, unsigned int dev)
 {
 	int err;
 	static int possible_irqs[] = {5, 9, 10, 7, 11, 12, -1};
@@ -2231,8 +2231,8 @@
 	}
 }
 
-static int __devexit snd_es18xx_isa_remove(struct device *devptr,
-					   unsigned int dev)
+static int snd_es18xx_isa_remove(struct device *devptr,
+				 unsigned int dev)
 {
 	snd_card_free(dev_get_drvdata(devptr));
 	dev_set_drvdata(devptr, NULL);
@@ -2257,7 +2257,7 @@
 static struct isa_driver snd_es18xx_isa_driver = {
 	.match		= snd_es18xx_isa_match,
 	.probe		= snd_es18xx_isa_probe,
-	.remove		= __devexit_p(snd_es18xx_isa_remove),
+	.remove		= snd_es18xx_isa_remove,
 #ifdef CONFIG_PM
 	.suspend	= snd_es18xx_isa_suspend,
 	.resume		= snd_es18xx_isa_resume,
@@ -2269,8 +2269,8 @@
 
 
 #ifdef CONFIG_PNP
-static int __devinit snd_audiodrive_pnp_detect(struct pnp_dev *pdev,
-					    const struct pnp_device_id *id)
+static int snd_audiodrive_pnp_detect(struct pnp_dev *pdev,
+				     const struct pnp_device_id *id)
 {
 	static int dev;
 	int err;
@@ -2302,7 +2302,7 @@
 	return 0;
 }
 
-static void __devexit snd_audiodrive_pnp_remove(struct pnp_dev * pdev)
+static void snd_audiodrive_pnp_remove(struct pnp_dev *pdev)
 {
 	snd_card_free(pnp_get_drvdata(pdev));
 	pnp_set_drvdata(pdev, NULL);
@@ -2323,15 +2323,15 @@
 	.name = "es18xx-pnpbios",
 	.id_table = snd_audiodrive_pnpbiosids,
 	.probe = snd_audiodrive_pnp_detect,
-	.remove = __devexit_p(snd_audiodrive_pnp_remove),
+	.remove = snd_audiodrive_pnp_remove,
 #ifdef CONFIG_PM
 	.suspend = snd_audiodrive_pnp_suspend,
 	.resume = snd_audiodrive_pnp_resume,
 #endif
 };
 
-static int __devinit snd_audiodrive_pnpc_detect(struct pnp_card_link *pcard,
-					       const struct pnp_card_device_id *pid)
+static int snd_audiodrive_pnpc_detect(struct pnp_card_link *pcard,
+				      const struct pnp_card_device_id *pid)
 {
 	static int dev;
 	struct snd_card *card;
@@ -2363,7 +2363,7 @@
 	return 0;
 }
 
-static void __devexit snd_audiodrive_pnpc_remove(struct pnp_card_link * pcard)
+static void snd_audiodrive_pnpc_remove(struct pnp_card_link *pcard)
 {
 	snd_card_free(pnp_get_card_drvdata(pcard));
 	pnp_set_card_drvdata(pcard, NULL);
@@ -2387,7 +2387,7 @@
 	.name = "es18xx",
 	.id_table = snd_audiodrive_pnpids,
 	.probe = snd_audiodrive_pnpc_detect,
-	.remove = __devexit_p(snd_audiodrive_pnpc_remove),
+	.remove = snd_audiodrive_pnpc_remove,
 #ifdef CONFIG_PM
 	.suspend	= snd_audiodrive_pnpc_suspend,
 	.resume		= snd_audiodrive_pnpc_resume,
diff --git a/sound/isa/galaxy/galaxy.c b/sound/isa/galaxy/galaxy.c
index 55e2078..672184e 100644
--- a/sound/isa/galaxy/galaxy.c
+++ b/sound/isa/galaxy/galaxy.c
@@ -84,7 +84,7 @@
 
 #define DSP_COMMAND_GET_VERSION	0xe1
 
-static int __devinit dsp_get_byte(void __iomem *port, u8 *val)
+static int dsp_get_byte(void __iomem *port, u8 *val)
 {
 	int loops = 1000;
 
@@ -97,7 +97,7 @@
 	return 0;
 }
 
-static int __devinit dsp_reset(void __iomem *port)
+static int dsp_reset(void __iomem *port)
 {
 	u8 val;
 
@@ -111,7 +111,7 @@
 	return 0;
 }
 
-static int __devinit dsp_command(void __iomem *port, u8 cmd)
+static int dsp_command(void __iomem *port, u8 cmd)
 {
 	int loops = 1000;
 
@@ -124,7 +124,7 @@
 	return 0;
 }
 
-static int __devinit dsp_get_version(void __iomem *port, u8 *major, u8 *minor)
+static int dsp_get_version(void __iomem *port, u8 *major, u8 *minor)
 {
 	int err;
 
@@ -161,7 +161,7 @@
 
 #define WSS_SIGNATURE		4
 
-static int __devinit wss_detect(void __iomem *wss_port)
+static int wss_detect(void __iomem *wss_port)
 {
 	if ((ioread8(wss_port + WSS_PORT_SIGNATURE) & 0x3f) != WSS_SIGNATURE)
 		return -ENODEV;
@@ -204,7 +204,7 @@
 static u32 config[SNDRV_CARDS];
 static u8 wss_config[SNDRV_CARDS];
 
-static int __devinit snd_galaxy_match(struct device *dev, unsigned int n)
+static int snd_galaxy_match(struct device *dev, unsigned int n)
 {
 	if (!enable[n])
 		return 0;
@@ -379,7 +379,7 @@
 	return 1;
 }
 
-static int __devinit galaxy_init(struct snd_galaxy *galaxy, u8 *type)
+static int galaxy_init(struct snd_galaxy *galaxy, u8 *type)
 {
 	u8 major;
 	u8 minor;
@@ -411,7 +411,7 @@
 	return 0;
 }
 
-static int __devinit galaxy_set_mode(struct snd_galaxy *galaxy, u8 mode)
+static int galaxy_set_mode(struct snd_galaxy *galaxy, u8 mode)
 {
 	int err;
 
@@ -449,7 +449,7 @@
 	msleep(10);
 }
 
-static void __devinit galaxy_config(struct snd_galaxy *galaxy, u32 config)
+static void galaxy_config(struct snd_galaxy *galaxy, u32 config)
 {
 	int i;
 
@@ -461,7 +461,7 @@
 	galaxy_set_config(galaxy, config);
 }
 
-static int __devinit galaxy_wss_config(struct snd_galaxy *galaxy, u8 wss_config)
+static int galaxy_wss_config(struct snd_galaxy *galaxy, u8 wss_config)
 {
 	int err;
 
@@ -498,7 +498,7 @@
 	}
 }
 
-static int __devinit snd_galaxy_probe(struct device *dev, unsigned int n)
+static int snd_galaxy_probe(struct device *dev, unsigned int n)
 {
 	struct snd_galaxy *galaxy;
 	struct snd_wss *chip;
@@ -620,7 +620,7 @@
 	return err;
 }
 
-static int __devexit snd_galaxy_remove(struct device *dev, unsigned int n)
+static int snd_galaxy_remove(struct device *dev, unsigned int n)
 {
 	snd_card_free(dev_get_drvdata(dev));
 	dev_set_drvdata(dev, NULL);
@@ -630,7 +630,7 @@
 static struct isa_driver snd_galaxy_driver = {
 	.match		= snd_galaxy_match,
 	.probe		= snd_galaxy_probe,
-	.remove		= __devexit_p(snd_galaxy_remove),
+	.remove		= snd_galaxy_remove,
 
 	.driver		= {
 		.name	= DEV_NAME
diff --git a/sound/isa/gus/gusclassic.c b/sound/isa/gus/gusclassic.c
index bf63336..16bca4e 100644
--- a/sound/isa/gus/gusclassic.c
+++ b/sound/isa/gus/gusclassic.c
@@ -73,13 +73,14 @@
 module_param_array(pcm_channels, int, NULL, 0444);
 MODULE_PARM_DESC(pcm_channels, "Reserved PCM channels for " CRD_NAME " driver.");
 
-static int __devinit snd_gusclassic_match(struct device *dev, unsigned int n)
+static int snd_gusclassic_match(struct device *dev, unsigned int n)
 {
 	return enable[n];
 }
 
-static int __devinit snd_gusclassic_create(struct snd_card *card,
-		struct device *dev, unsigned int n, struct snd_gus_card **rgus)
+static int snd_gusclassic_create(struct snd_card *card,
+				 struct device *dev, unsigned int n,
+				 struct snd_gus_card **rgus)
 {
 	static long possible_ports[] = {0x220, 0x230, 0x240, 0x250, 0x260};
 	static int possible_irqs[] = {5, 11, 12, 9, 7, 15, 3, 4, -1};
@@ -123,7 +124,7 @@
 	return error;
 }
 
-static int __devinit snd_gusclassic_detect(struct snd_gus_card *gus)
+static int snd_gusclassic_detect(struct snd_gus_card *gus)
 {
 	unsigned char d;
 
@@ -142,7 +143,7 @@
 	return 0;
 }
 
-static int __devinit snd_gusclassic_probe(struct device *dev, unsigned int n)
+static int snd_gusclassic_probe(struct device *dev, unsigned int n)
 {
 	struct snd_card *card;
 	struct snd_gus_card *gus;
@@ -211,7 +212,7 @@
 	return error;
 }
 
-static int __devexit snd_gusclassic_remove(struct device *dev, unsigned int n)
+static int snd_gusclassic_remove(struct device *dev, unsigned int n)
 {
 	snd_card_free(dev_get_drvdata(dev));
 	dev_set_drvdata(dev, NULL);
@@ -221,7 +222,7 @@
 static struct isa_driver snd_gusclassic_driver = {
 	.match		= snd_gusclassic_match,
 	.probe		= snd_gusclassic_probe,
-	.remove		= __devexit_p(snd_gusclassic_remove),
+	.remove		= snd_gusclassic_remove,
 #if 0	/* FIXME */
 	.suspend	= snd_gusclassic_suspend,
 	.remove		= snd_gusclassic_remove,
diff --git a/sound/isa/gus/gusextreme.c b/sound/isa/gus/gusextreme.c
index bc10cc2..0b9c242 100644
--- a/sound/isa/gus/gusextreme.c
+++ b/sound/isa/gus/gusextreme.c
@@ -89,13 +89,14 @@
 module_param_array(pcm_channels, int, NULL, 0444);
 MODULE_PARM_DESC(pcm_channels, "Reserved PCM channels for " CRD_NAME " driver.");
 
-static int __devinit snd_gusextreme_match(struct device *dev, unsigned int n)
+static int snd_gusextreme_match(struct device *dev, unsigned int n)
 {
 	return enable[n];
 }
 
-static int __devinit snd_gusextreme_es1688_create(struct snd_card *card,
-		struct snd_es1688 *chip, struct device *dev, unsigned int n)
+static int snd_gusextreme_es1688_create(struct snd_card *card,
+					struct snd_es1688 *chip,
+					struct device *dev, unsigned int n)
 {
 	static long possible_ports[] = {0x220, 0x240, 0x260};
 	static int possible_irqs[] = {5, 9, 10, 7, -1};
@@ -132,8 +133,9 @@
 	return error;
 }
 
-static int __devinit snd_gusextreme_gus_card_create(struct snd_card *card,
-		struct device *dev, unsigned int n, struct snd_gus_card **rgus)
+static int snd_gusextreme_gus_card_create(struct snd_card *card,
+					  struct device *dev, unsigned int n,
+					  struct snd_gus_card **rgus)
 {
 	static int possible_irqs[] = {11, 12, 15, 9, 5, 7, 3, -1};
 	static int possible_dmas[] = {5, 6, 7, 3, 1, -1};
@@ -156,8 +158,8 @@
 			0, channels[n], pcm_channels[n], 0, rgus);
 }
 
-static int __devinit snd_gusextreme_detect(struct snd_gus_card *gus,
-	struct snd_es1688 *es1688)
+static int snd_gusextreme_detect(struct snd_gus_card *gus,
+				 struct snd_es1688 *es1688)
 {
 	unsigned long flags;
 	unsigned char d;
@@ -206,7 +208,7 @@
 	return 0;
 }
 
-static int __devinit snd_gusextreme_mixer(struct snd_card *card)
+static int snd_gusextreme_mixer(struct snd_card *card)
 {
 	struct snd_ctl_elem_id id1, id2;
 	int error;
@@ -232,7 +234,7 @@
 	return 0;
 }
 
-static int __devinit snd_gusextreme_probe(struct device *dev, unsigned int n)
+static int snd_gusextreme_probe(struct device *dev, unsigned int n)
 {
 	struct snd_card *card;
 	struct snd_gus_card *gus;
@@ -339,7 +341,7 @@
 	return error;
 }
 
-static int __devexit snd_gusextreme_remove(struct device *dev, unsigned int n)
+static int snd_gusextreme_remove(struct device *dev, unsigned int n)
 {
 	snd_card_free(dev_get_drvdata(dev));
 	dev_set_drvdata(dev, NULL);
@@ -349,7 +351,7 @@
 static struct isa_driver snd_gusextreme_driver = {
 	.match		= snd_gusextreme_match,
 	.probe		= snd_gusextreme_probe,
-	.remove		= __devexit_p(snd_gusextreme_remove),
+	.remove		= snd_gusextreme_remove,
 #if 0	/* FIXME */
 	.suspend	= snd_gusextreme_suspend,
 	.resume		= snd_gusextreme_resume,
diff --git a/sound/isa/gus/gusmax.c b/sound/isa/gus/gusmax.c
index 41c3f44..c309a5d 100644
--- a/sound/isa/gus/gusmax.c
+++ b/sound/isa/gus/gusmax.c
@@ -82,7 +82,7 @@
 
 #define PFX	"gusmax: "
 
-static int __devinit snd_gusmax_detect(struct snd_gus_card * gus)
+static int snd_gusmax_detect(struct snd_gus_card *gus)
 {
 	unsigned char d;
 
@@ -124,8 +124,8 @@
 	return IRQ_RETVAL(handled);
 }
 
-static void __devinit snd_gusmax_init(int dev, struct snd_card *card,
-				      struct snd_gus_card * gus)
+static void snd_gusmax_init(int dev, struct snd_card *card,
+			    struct snd_gus_card *gus)
 {
 	gus->equal_irq = 1;
 	gus->codec_flag = 1;
@@ -140,7 +140,7 @@
 	outb(gus->max_cntrl_val, GUSP(gus, MAXCNTRLPORT));
 }
 
-static int __devinit snd_gusmax_mixer(struct snd_wss *chip)
+static int snd_gusmax_mixer(struct snd_wss *chip)
 {
 	struct snd_card *card = chip->card;
 	struct snd_ctl_elem_id id1, id2;
@@ -199,12 +199,12 @@
 		free_irq(maxcard->irq, (void *)maxcard);
 }
 
-static int __devinit snd_gusmax_match(struct device *pdev, unsigned int dev)
+static int snd_gusmax_match(struct device *pdev, unsigned int dev)
 {
 	return enable[dev];
 }
 
-static int __devinit snd_gusmax_probe(struct device *pdev, unsigned int dev)
+static int snd_gusmax_probe(struct device *pdev, unsigned int dev)
 {
 	static int possible_irqs[] = {5, 11, 12, 9, 7, 15, 3, -1};
 	static int possible_dmas[] = {5, 6, 7, 1, 3, -1};
@@ -354,7 +354,7 @@
 	return err;
 }
 
-static int __devexit snd_gusmax_remove(struct device *devptr, unsigned int dev)
+static int snd_gusmax_remove(struct device *devptr, unsigned int dev)
 {
 	snd_card_free(dev_get_drvdata(devptr));
 	dev_set_drvdata(devptr, NULL);
@@ -366,7 +366,7 @@
 static struct isa_driver snd_gusmax_driver = {
 	.match		= snd_gusmax_match,
 	.probe		= snd_gusmax_probe,
-	.remove		= __devexit_p(snd_gusmax_remove),
+	.remove		= snd_gusmax_remove,
 	/* FIXME: suspend/resume */
 	.driver		= {
 		.name	= DEV_NAME
diff --git a/sound/isa/gus/interwave.c b/sound/isa/gus/interwave.c
index 3fc8b66..78bc574 100644
--- a/sound/isa/gus/interwave.c
+++ b/sound/isa/gus/interwave.c
@@ -207,9 +207,9 @@
 	.getdata  = snd_interwave_i2c_getdataline,
 };
 
-static int __devinit snd_interwave_detect_stb(struct snd_interwave *iwcard,
-					      struct snd_gus_card * gus, int dev,
-					      struct snd_i2c_bus **rbus)
+static int snd_interwave_detect_stb(struct snd_interwave *iwcard,
+				    struct snd_gus_card *gus, int dev,
+				    struct snd_i2c_bus **rbus)
 {
 	unsigned long port;
 	struct snd_i2c_bus *bus;
@@ -249,11 +249,11 @@
 }
 #endif
 
-static int __devinit snd_interwave_detect(struct snd_interwave *iwcard,
-				          struct snd_gus_card * gus,
-				          int dev
+static int snd_interwave_detect(struct snd_interwave *iwcard,
+				struct snd_gus_card *gus,
+				int dev
 #ifdef SNDRV_STB
-				          , struct snd_i2c_bus **rbus
+				, struct snd_i2c_bus **rbus
 #endif
 				          )
 {
@@ -318,7 +318,7 @@
 	return IRQ_RETVAL(handled);
 }
 
-static void __devinit snd_interwave_reset(struct snd_gus_card * gus)
+static void snd_interwave_reset(struct snd_gus_card *gus)
 {
 	snd_gf1_write8(gus, SNDRV_GF1_GB_RESET, 0x00);
 	udelay(160);
@@ -326,7 +326,7 @@
 	udelay(160);
 }
 
-static void __devinit snd_interwave_bank_sizes(struct snd_gus_card * gus, int *sizes)
+static void snd_interwave_bank_sizes(struct snd_gus_card *gus, int *sizes)
 {
 	unsigned int idx;
 	unsigned int local;
@@ -377,7 +377,7 @@
 	/* 511 */ unsigned char csum;
 };
 
-static void __devinit snd_interwave_detect_memory(struct snd_gus_card * gus)
+static void snd_interwave_detect_memory(struct snd_gus_card *gus)
 {
 	static unsigned int lmc[13] =
 	{
@@ -475,7 +475,7 @@
 		snd_interwave_reset(gus);
 }
 
-static void __devinit snd_interwave_init(int dev, struct snd_gus_card * gus)
+static void snd_interwave_init(int dev, struct snd_gus_card *gus)
 {
 	unsigned long flags;
 
@@ -508,7 +508,7 @@
 		CS4231_LEFT_MIC_INPUT, CS4231_RIGHT_MIC_INPUT, 0, 0, 31, 1)
 };
 
-static int __devinit snd_interwave_mixer(struct snd_wss *chip)
+static int snd_interwave_mixer(struct snd_wss *chip)
 {
 	struct snd_card *card = chip->card;
 	struct snd_ctl_elem_id id1, id2;
@@ -558,9 +558,9 @@
 
 #ifdef CONFIG_PNP
 
-static int __devinit snd_interwave_pnp(int dev, struct snd_interwave *iwcard,
-				       struct pnp_card_link *card,
-				       const struct pnp_card_device_id *id)
+static int snd_interwave_pnp(int dev, struct snd_interwave *iwcard,
+			     struct pnp_card_link *card,
+			     const struct pnp_card_device_id *id)
 {
 	struct pnp_dev *pdev;
 	int err;
@@ -644,7 +644,7 @@
 	return 0;
 }
 
-static int __devinit snd_interwave_probe(struct snd_card *card, int dev)
+static int snd_interwave_probe(struct snd_card *card, int dev)
 {
 	int xirq, xdma1, xdma2;
 	struct snd_interwave *iwcard = card->private_data;
@@ -775,7 +775,7 @@
 	return 0;
 }
 
-static int __devinit snd_interwave_isa_probe1(int dev, struct device *devptr)
+static int snd_interwave_isa_probe1(int dev, struct device *devptr)
 {
 	struct snd_card *card;
 	int err;
@@ -793,8 +793,8 @@
 	return 0;
 }
 
-static int __devinit snd_interwave_isa_match(struct device *pdev,
-					     unsigned int dev)
+static int snd_interwave_isa_match(struct device *pdev,
+				   unsigned int dev)
 {
 	if (!enable[dev])
 		return 0;
@@ -805,8 +805,8 @@
 	return 1;
 }
 
-static int __devinit snd_interwave_isa_probe(struct device *pdev,
-					     unsigned int dev)
+static int snd_interwave_isa_probe(struct device *pdev,
+				   unsigned int dev)
 {
 	int err;
 	static int possible_irqs[] = {5, 11, 12, 9, 7, 15, 3, -1};
@@ -846,7 +846,7 @@
 	}
 }
 
-static int __devexit snd_interwave_isa_remove(struct device *devptr, unsigned int dev)
+static int snd_interwave_isa_remove(struct device *devptr, unsigned int dev)
 {
 	snd_card_free(dev_get_drvdata(devptr));
 	dev_set_drvdata(devptr, NULL);
@@ -856,7 +856,7 @@
 static struct isa_driver snd_interwave_driver = {
 	.match		= snd_interwave_isa_match,
 	.probe		= snd_interwave_isa_probe,
-	.remove		= __devexit_p(snd_interwave_isa_remove),
+	.remove		= snd_interwave_isa_remove,
 	/* FIXME: suspend,resume */
 	.driver		= {
 		.name	= INTERWAVE_DRIVER
@@ -864,8 +864,8 @@
 };
 
 #ifdef CONFIG_PNP
-static int __devinit snd_interwave_pnp_detect(struct pnp_card_link *pcard,
-					      const struct pnp_card_device_id *pid)
+static int snd_interwave_pnp_detect(struct pnp_card_link *pcard,
+				    const struct pnp_card_device_id *pid)
 {
 	static int dev;
 	struct snd_card *card;
@@ -896,7 +896,7 @@
 	return 0;
 }
 
-static void __devexit snd_interwave_pnp_remove(struct pnp_card_link * pcard)
+static void snd_interwave_pnp_remove(struct pnp_card_link *pcard)
 {
 	snd_card_free(pnp_get_card_drvdata(pcard));
 	pnp_set_card_drvdata(pcard, NULL);
@@ -907,7 +907,7 @@
 	.name = INTERWAVE_PNP_DRIVER,
 	.id_table = snd_interwave_pnpids,
 	.probe = snd_interwave_pnp_detect,
-	.remove = __devexit_p(snd_interwave_pnp_remove),
+	.remove = snd_interwave_pnp_remove,
 	/* FIXME: suspend,resume */
 };
 
diff --git a/sound/isa/msnd/msnd.h b/sound/isa/msnd/msnd.h
index a168ba3..dbac3a4 100644
--- a/sound/isa/msnd/msnd.h
+++ b/sound/isa/msnd/msnd.h
@@ -303,6 +303,6 @@
 void snd_msndmidi_input_read(void *mpu);
 
 void snd_msndmix_setup(struct snd_msnd *chip);
-int __devinit snd_msndmix_new(struct snd_card *card);
+int snd_msndmix_new(struct snd_card *card);
 int snd_msndmix_force_recsrc(struct snd_msnd *chip, int recsrc);
 #endif /* __MSND_H */
diff --git a/sound/isa/msnd/msnd_pinnacle.c b/sound/isa/msnd/msnd_pinnacle.c
index 29cc8e1..ddabb40 100644
--- a/sound/isa/msnd/msnd_pinnacle.c
+++ b/sound/isa/msnd/msnd_pinnacle.c
@@ -78,7 +78,7 @@
 #  define LOGNAME			"snd_msnd_pinnacle"
 #endif
 
-static void __devinit set_default_audio_parameters(struct snd_msnd *chip)
+static void set_default_audio_parameters(struct snd_msnd *chip)
 {
 	chip->play_sample_size = DEFSAMPLESIZE;
 	chip->play_sample_rate = DEFSAMPLERATE;
@@ -213,7 +213,7 @@
 	return -EIO;
 }
 
-static int __devinit snd_msnd_probe(struct snd_card *card)
+static int snd_msnd_probe(struct snd_card *card)
 {
 	struct snd_msnd *chip = card->private_data;
 	unsigned char info;
@@ -497,7 +497,7 @@
 	return snd_msnd_send_dsp_cmd(chip, cmd);
 }
 
-static int __devinit snd_msnd_calibrate_adc(struct snd_msnd *chip, u16 srate)
+static int snd_msnd_calibrate_adc(struct snd_msnd *chip, u16 srate)
 {
 	snd_printdd("snd_msnd_calibrate_adc(%i)\n", srate);
 	writew(srate, chip->SMA + SMA_wCalFreqAtoD);
@@ -535,7 +535,7 @@
 static long mpu_io[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;
 static int mpu_irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ;
 
-static int __devinit snd_msnd_attach(struct snd_card *card)
+static int snd_msnd_attach(struct snd_card *card)
 {
 	struct snd_msnd *chip = card->private_data;
 	int err;
@@ -634,7 +634,7 @@
 }
 
 
-static void __devexit snd_msnd_unload(struct snd_card *card)
+static void snd_msnd_unload(struct snd_card *card)
 {
 	struct snd_msnd *chip = card->private_data;
 
@@ -649,7 +649,7 @@
 
 /* Pinnacle/Fiji Logical Device Configuration */
 
-static int __devinit snd_msnd_write_cfg(int cfg, int reg, int value)
+static int snd_msnd_write_cfg(int cfg, int reg, int value)
 {
 	outb(reg, cfg);
 	outb(value, cfg + 1);
@@ -660,7 +660,7 @@
 	return 0;
 }
 
-static int __devinit snd_msnd_write_cfg_io0(int cfg, int num, u16 io)
+static int snd_msnd_write_cfg_io0(int cfg, int num, u16 io)
 {
 	if (snd_msnd_write_cfg(cfg, IREG_LOGDEVICE, num))
 		return -EIO;
@@ -671,7 +671,7 @@
 	return 0;
 }
 
-static int __devinit snd_msnd_write_cfg_io1(int cfg, int num, u16 io)
+static int snd_msnd_write_cfg_io1(int cfg, int num, u16 io)
 {
 	if (snd_msnd_write_cfg(cfg, IREG_LOGDEVICE, num))
 		return -EIO;
@@ -682,7 +682,7 @@
 	return 0;
 }
 
-static int __devinit snd_msnd_write_cfg_irq(int cfg, int num, u16 irq)
+static int snd_msnd_write_cfg_irq(int cfg, int num, u16 irq)
 {
 	if (snd_msnd_write_cfg(cfg, IREG_LOGDEVICE, num))
 		return -EIO;
@@ -693,7 +693,7 @@
 	return 0;
 }
 
-static int __devinit snd_msnd_write_cfg_mem(int cfg, int num, int mem)
+static int snd_msnd_write_cfg_mem(int cfg, int num, int mem)
 {
 	u16 wmem;
 
@@ -711,7 +711,7 @@
 	return 0;
 }
 
-static int __devinit snd_msnd_activate_logical(int cfg, int num)
+static int snd_msnd_activate_logical(int cfg, int num)
 {
 	if (snd_msnd_write_cfg(cfg, IREG_LOGDEVICE, num))
 		return -EIO;
@@ -720,8 +720,8 @@
 	return 0;
 }
 
-static int __devinit snd_msnd_write_cfg_logical(int cfg, int num, u16 io0,
-						u16 io1, u16 irq, int mem)
+static int snd_msnd_write_cfg_logical(int cfg, int num, u16 io0,
+				      u16 io1, u16 irq, int mem)
 {
 	if (snd_msnd_write_cfg(cfg, IREG_LOGDEVICE, num))
 		return -EIO;
@@ -738,7 +738,7 @@
 	return 0;
 }
 
-static int __devinit snd_msnd_pinnacle_cfg_reset(int cfg)
+static int snd_msnd_pinnacle_cfg_reset(int cfg)
 {
 	int i;
 
@@ -818,7 +818,7 @@
 #endif
 
 
-static int __devinit snd_msnd_isa_match(struct device *pdev, unsigned int i)
+static int snd_msnd_isa_match(struct device *pdev, unsigned int i)
 {
 	if (io[i] == SNDRV_AUTO_PORT)
 		return 0;
@@ -888,7 +888,7 @@
 	return 1;
 }
 
-static int __devinit snd_msnd_isa_probe(struct device *pdev, unsigned int idx)
+static int snd_msnd_isa_probe(struct device *pdev, unsigned int idx)
 {
 	int err;
 	struct snd_card *card;
@@ -1061,7 +1061,7 @@
 #endif
 }
 
-static int __devexit snd_msnd_isa_remove(struct device *pdev, unsigned int dev)
+static int snd_msnd_isa_remove(struct device *pdev, unsigned int dev)
 {
 	snd_msnd_unload(dev_get_drvdata(pdev));
 	dev_set_drvdata(pdev, NULL);
@@ -1073,7 +1073,7 @@
 static struct isa_driver snd_msnd_driver = {
 	.match		= snd_msnd_isa_match,
 	.probe		= snd_msnd_isa_probe,
-	.remove		= __devexit_p(snd_msnd_isa_remove),
+	.remove		= snd_msnd_isa_remove,
 	/* FIXME: suspend, resume */
 	.driver		= {
 		.name	= DEV_NAME
@@ -1081,8 +1081,8 @@
 };
 
 #ifdef CONFIG_PNP
-static int __devinit snd_msnd_pnp_detect(struct pnp_card_link *pcard,
-					 const struct pnp_card_device_id *pid)
+static int snd_msnd_pnp_detect(struct pnp_card_link *pcard,
+			       const struct pnp_card_device_id *pid)
 {
 	static int idx;
 	struct pnp_dev *pnp_dev;
@@ -1185,7 +1185,7 @@
 	return ret;
 }
 
-static void __devexit snd_msnd_pnp_remove(struct pnp_card_link *pcard)
+static void snd_msnd_pnp_remove(struct pnp_card_link *pcard)
 {
 	snd_msnd_unload(pnp_get_card_drvdata(pcard));
 	pnp_set_card_drvdata(pcard, NULL);
@@ -1207,7 +1207,7 @@
 	.name = "msnd_pinnacle",
 	.id_table = msnd_pnpids,
 	.probe = snd_msnd_pnp_detect,
-	.remove = __devexit_p(snd_msnd_pnp_remove),
+	.remove = snd_msnd_pnp_remove,
 };
 #endif /* CONFIG_PNP */
 
diff --git a/sound/isa/msnd/msnd_pinnacle_mixer.c b/sound/isa/msnd/msnd_pinnacle_mixer.c
index 1de59d4..031dc69 100644
--- a/sound/isa/msnd/msnd_pinnacle_mixer.c
+++ b/sound/isa/msnd/msnd_pinnacle_mixer.c
@@ -302,7 +302,7 @@
 };
 
 
-int __devinit snd_msndmix_new(struct snd_card *card)
+int snd_msndmix_new(struct snd_card *card)
 {
 	struct snd_msnd *chip = card->private_data;
 	unsigned int idx;
diff --git a/sound/isa/opl3sa2.c b/sound/isa/opl3sa2.c
index f6cc0b9..075777a 100644
--- a/sound/isa/opl3sa2.c
+++ b/sound/isa/opl3sa2.c
@@ -221,7 +221,7 @@
 	spin_unlock_irqrestore(&chip->reg_lock, flags);
 }
 
-static int __devinit snd_opl3sa2_detect(struct snd_card *card)
+static int snd_opl3sa2_detect(struct snd_card *card)
 {
 	struct snd_opl3sa2 *chip = card->private_data;
 	unsigned long port;
@@ -496,7 +496,7 @@
 	chip->master_volume = NULL;
 }
 
-static int __devinit snd_opl3sa2_mixer(struct snd_card *card)
+static int snd_opl3sa2_mixer(struct snd_card *card)
 {
 	struct snd_opl3sa2 *chip = card->private_data;
 	struct snd_ctl_elem_id id1, id2;
@@ -596,8 +596,8 @@
 #endif /* CONFIG_PM */
 
 #ifdef CONFIG_PNP
-static int __devinit snd_opl3sa2_pnp(int dev, struct snd_opl3sa2 *chip,
-				     struct pnp_dev *pdev)
+static int snd_opl3sa2_pnp(int dev, struct snd_opl3sa2 *chip,
+			   struct pnp_dev *pdev)
 {
 	if (pnp_activate_dev(pdev) < 0) {
 		snd_printk(KERN_ERR "PnP configure failure (out of resources?)\n");
@@ -647,7 +647,7 @@
 	return 0;
 }
 
-static int __devinit snd_opl3sa2_probe(struct snd_card *card, int dev)
+static int snd_opl3sa2_probe(struct snd_card *card, int dev)
 {
 	int xirq, xdma1, xdma2;
 	struct snd_opl3sa2 *chip;
@@ -721,8 +721,8 @@
 }
 
 #ifdef CONFIG_PNP
-static int __devinit snd_opl3sa2_pnp_detect(struct pnp_dev *pdev,
-					    const struct pnp_device_id *id)
+static int snd_opl3sa2_pnp_detect(struct pnp_dev *pdev,
+				  const struct pnp_device_id *id)
 {
 	static int dev;
 	int err;
@@ -754,7 +754,7 @@
 	return 0;
 }
 
-static void __devexit snd_opl3sa2_pnp_remove(struct pnp_dev * pdev)
+static void snd_opl3sa2_pnp_remove(struct pnp_dev *pdev)
 {
 	snd_card_free(pnp_get_drvdata(pdev));
 	pnp_set_drvdata(pdev, NULL);
@@ -775,15 +775,15 @@
 	.name = "snd-opl3sa2-pnpbios",
 	.id_table = snd_opl3sa2_pnpbiosids,
 	.probe = snd_opl3sa2_pnp_detect,
-	.remove = __devexit_p(snd_opl3sa2_pnp_remove),
+	.remove = snd_opl3sa2_pnp_remove,
 #ifdef CONFIG_PM
 	.suspend = snd_opl3sa2_pnp_suspend,
 	.resume = snd_opl3sa2_pnp_resume,
 #endif
 };
 
-static int __devinit snd_opl3sa2_pnp_cdetect(struct pnp_card_link *pcard,
-					     const struct pnp_card_device_id *id)
+static int snd_opl3sa2_pnp_cdetect(struct pnp_card_link *pcard,
+				   const struct pnp_card_device_id *id)
 {
 	static int dev;
 	struct pnp_dev *pdev;
@@ -820,7 +820,7 @@
 	return 0;
 }
 
-static void __devexit snd_opl3sa2_pnp_cremove(struct pnp_card_link * pcard)
+static void snd_opl3sa2_pnp_cremove(struct pnp_card_link *pcard)
 {
 	snd_card_free(pnp_get_card_drvdata(pcard));
 	pnp_set_card_drvdata(pcard, NULL);
@@ -842,7 +842,7 @@
 	.name = "snd-opl3sa2-cpnp",
 	.id_table = snd_opl3sa2_pnpids,
 	.probe = snd_opl3sa2_pnp_cdetect,
-	.remove = __devexit_p(snd_opl3sa2_pnp_cremove),
+	.remove = snd_opl3sa2_pnp_cremove,
 #ifdef CONFIG_PM
 	.suspend = snd_opl3sa2_pnp_csuspend,
 	.resume = snd_opl3sa2_pnp_cresume,
@@ -850,8 +850,8 @@
 };
 #endif /* CONFIG_PNP */
 
-static int __devinit snd_opl3sa2_isa_match(struct device *pdev,
-					   unsigned int dev)
+static int snd_opl3sa2_isa_match(struct device *pdev,
+				 unsigned int dev)
 {
 	if (!enable[dev])
 		return 0;
@@ -878,8 +878,8 @@
 	return 1;
 }
 
-static int __devinit snd_opl3sa2_isa_probe(struct device *pdev,
-					   unsigned int dev)
+static int snd_opl3sa2_isa_probe(struct device *pdev,
+				 unsigned int dev)
 {
 	struct snd_card *card;
 	int err;
@@ -896,8 +896,8 @@
 	return 0;
 }
 
-static int __devexit snd_opl3sa2_isa_remove(struct device *devptr,
-					    unsigned int dev)
+static int snd_opl3sa2_isa_remove(struct device *devptr,
+				  unsigned int dev)
 {
 	snd_card_free(dev_get_drvdata(devptr));
 	dev_set_drvdata(devptr, NULL);
@@ -922,7 +922,7 @@
 static struct isa_driver snd_opl3sa2_isa_driver = {
 	.match		= snd_opl3sa2_isa_match,
 	.probe		= snd_opl3sa2_isa_probe,
-	.remove		= __devexit_p(snd_opl3sa2_isa_remove),
+	.remove		= snd_opl3sa2_isa_remove,
 #ifdef CONFIG_PM
 	.suspend	= snd_opl3sa2_isa_suspend,
 	.resume		= snd_opl3sa2_isa_resume,
diff --git a/sound/isa/opti9xx/miro.c b/sound/isa/opti9xx/miro.c
index 4a7ff4e..c3da1df 100644
--- a/sound/isa/opti9xx/miro.c
+++ b/sound/isa/opti9xx/miro.c
@@ -587,7 +587,7 @@
 	return change;
 }
 
-static struct snd_kcontrol_new snd_miro_controls[] __devinitdata = {
+static struct snd_kcontrol_new snd_miro_controls[] = {
 MIRO_DOUBLE("Master Playback Volume", 0, ACI_GET_MASTER, ACI_SET_MASTER),
 MIRO_DOUBLE("Mic Playback Volume", 1, ACI_GET_MIC, ACI_SET_MIC),
 MIRO_DOUBLE("Line Playback Volume", 1, ACI_GET_LINE, ACI_SET_LINE),
@@ -599,7 +599,7 @@
 
 /* Equalizer with seven bands (only PCM20) 
    from -12dB up to +12dB on each band */
-static struct snd_kcontrol_new snd_miro_eq_controls[] __devinitdata = {
+static struct snd_kcontrol_new snd_miro_eq_controls[] = {
 MIRO_DOUBLE("Tone Control - 28 Hz", 0, ACI_GET_EQ1, ACI_SET_EQ1),
 MIRO_DOUBLE("Tone Control - 160 Hz", 0, ACI_GET_EQ2, ACI_SET_EQ2),
 MIRO_DOUBLE("Tone Control - 400 Hz", 0, ACI_GET_EQ3, ACI_SET_EQ3),
@@ -609,15 +609,15 @@
 MIRO_DOUBLE("Tone Control - 16 kHz", 0, ACI_GET_EQ7, ACI_SET_EQ7),
 };
 
-static struct snd_kcontrol_new snd_miro_radio_control[] __devinitdata = {
+static struct snd_kcontrol_new snd_miro_radio_control[] = {
 MIRO_DOUBLE("Radio Playback Volume", 0, ACI_GET_LINE1, ACI_SET_LINE1),
 };
 
-static struct snd_kcontrol_new snd_miro_line_control[] __devinitdata = {
+static struct snd_kcontrol_new snd_miro_line_control[] = {
 MIRO_DOUBLE("Line Playback Volume", 2, ACI_GET_LINE1, ACI_SET_LINE1),
 };
 
-static struct snd_kcontrol_new snd_miro_preamp_control[] __devinitdata = {
+static struct snd_kcontrol_new snd_miro_preamp_control[] = {
 {
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name = "Mic Boost",
@@ -627,7 +627,7 @@
 	.put = snd_miro_put_preamp,
 }};
 
-static struct snd_kcontrol_new snd_miro_amp_control[] __devinitdata = {
+static struct snd_kcontrol_new snd_miro_amp_control[] = {
 {
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name = "Line Boost",
@@ -637,7 +637,7 @@
 	.put = snd_miro_put_amp,
 }};
 
-static struct snd_kcontrol_new snd_miro_capture_control[] __devinitdata = {
+static struct snd_kcontrol_new snd_miro_capture_control[] = {
 {
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name = "PCM Capture Switch",
@@ -647,7 +647,7 @@
 	.put = snd_miro_put_capture,
 }};
 
-static unsigned char aci_init_values[][2] __devinitdata = {
+static unsigned char aci_init_values[][2] = {
 	{ ACI_SET_MUTE, 0x00 },
 	{ ACI_SET_POWERAMP, 0x00 },
 	{ ACI_SET_PREAMP, 0x00 },
@@ -670,7 +670,7 @@
 	{ ACI_SET_MASTER + 1, 0x20 },
 };
 
-static int __devinit snd_set_aci_init_values(struct snd_miro *miro)
+static int snd_set_aci_init_values(struct snd_miro *miro)
 {
 	int idx, error;
 	struct snd_miro_aci *aci = miro->aci;
@@ -713,8 +713,8 @@
 	return 0;
 }
 
-static int __devinit snd_miro_mixer(struct snd_card *card,
-				    struct snd_miro *miro)
+static int snd_miro_mixer(struct snd_card *card,
+			  struct snd_miro *miro)
 {
 	unsigned int idx;
 	int err;
@@ -771,8 +771,8 @@
 	return 0;
 }
 
-static int __devinit snd_miro_init(struct snd_miro *chip,
-				   unsigned short hardware)
+static int snd_miro_init(struct snd_miro *chip,
+			 unsigned short hardware)
 {
 	static int opti9xx_mc_size[] = {7, 7, 10, 10, 2, 2, 2};
 
@@ -989,8 +989,8 @@
 	snd_iprintf(buffer, "  preamp  : 0x%x\n", aci->aci_preamp);
 }
 
-static void __devinit snd_miro_proc_init(struct snd_card *card,
-					 struct snd_miro *miro)
+static void snd_miro_proc_init(struct snd_card *card,
+			       struct snd_miro *miro)
 {
 	struct snd_info_entry *entry;
 
@@ -1002,7 +1002,7 @@
  *  Init
  */
 
-static int __devinit snd_miro_configure(struct snd_miro *chip)
+static int snd_miro_configure(struct snd_miro *chip)
 {
 	unsigned char wss_base_bits;
 	unsigned char irq_bits;
@@ -1162,7 +1162,7 @@
 	return 0;
 }
 
-static int __devinit snd_miro_opti_check(struct snd_miro *chip)
+static int snd_miro_opti_check(struct snd_miro *chip)
 {
 	unsigned char value;
 
@@ -1182,8 +1182,8 @@
 	return -ENODEV;
 }
 
-static int __devinit snd_card_miro_detect(struct snd_card *card,
-					  struct snd_miro *chip)
+static int snd_card_miro_detect(struct snd_card *card,
+				struct snd_miro *chip)
 {
 	int i, err;
 
@@ -1200,8 +1200,8 @@
 	return -ENODEV;
 }
 
-static int __devinit snd_card_miro_aci_detect(struct snd_card *card,
-					      struct snd_miro *miro)
+static int snd_card_miro_aci_detect(struct snd_card *card,
+				    struct snd_miro *miro)
 {
 	unsigned char regval;
 	int i;
@@ -1265,7 +1265,7 @@
 	release_and_free_resource(miro->res_mc_base);
 }
 
-static int __devinit snd_miro_probe(struct snd_card *card)
+static int snd_miro_probe(struct snd_card *card)
 {
 	int error;
 	struct snd_miro *miro = card->private_data;
@@ -1386,7 +1386,7 @@
 	return snd_card_register(card);
 }
 
-static int __devinit snd_miro_isa_match(struct device *devptr, unsigned int n)
+static int snd_miro_isa_match(struct device *devptr, unsigned int n)
 {
 #ifdef CONFIG_PNP
 	if (snd_miro_pnp_is_probed)
@@ -1397,7 +1397,7 @@
 	return 1;
 }
 
-static int __devinit snd_miro_isa_probe(struct device *devptr, unsigned int n)
+static int snd_miro_isa_probe(struct device *devptr, unsigned int n)
 {
 	static long possible_ports[] = {0x530, 0xe80, 0xf40, 0x604, -1};
 	static long possible_mpu_ports[] = {0x330, 0x300, 0x310, 0x320, -1};
@@ -1491,8 +1491,8 @@
 	return 0;
 }
 
-static int __devexit snd_miro_isa_remove(struct device *devptr,
-					 unsigned int dev)
+static int snd_miro_isa_remove(struct device *devptr,
+			       unsigned int dev)
 {
 	snd_card_free(dev_get_drvdata(devptr));
 	dev_set_drvdata(devptr, NULL);
@@ -1504,7 +1504,7 @@
 static struct isa_driver snd_miro_driver = {
 	.match		= snd_miro_isa_match,
 	.probe		= snd_miro_isa_probe,
-	.remove		= __devexit_p(snd_miro_isa_remove),
+	.remove		= snd_miro_isa_remove,
 	/* FIXME: suspend/resume */
 	.driver		= {
 		.name	= DEV_NAME
@@ -1513,9 +1513,9 @@
 
 #ifdef CONFIG_PNP
 
-static int __devinit snd_card_miro_pnp(struct snd_miro *chip,
-					struct pnp_card_link *card,
-					const struct pnp_card_device_id *pid)
+static int snd_card_miro_pnp(struct snd_miro *chip,
+			     struct pnp_card_link *card,
+			     const struct pnp_card_device_id *pid)
 {
 	struct pnp_dev *pdev;
 	int err;
@@ -1574,8 +1574,8 @@
 	return 0;
 }
 
-static int __devinit snd_miro_pnp_probe(struct pnp_card_link *pcard,
-					const struct pnp_card_device_id *pid)
+static int snd_miro_pnp_probe(struct pnp_card_link *pcard,
+			      const struct pnp_card_device_id *pid)
 {
 	struct snd_card *card;
 	int err;
@@ -1624,7 +1624,7 @@
 	return 0;
 }
 
-static void __devexit snd_miro_pnp_remove(struct pnp_card_link * pcard)
+static void snd_miro_pnp_remove(struct pnp_card_link *pcard)
 {
 	snd_card_free(pnp_get_card_drvdata(pcard));
 	pnp_set_card_drvdata(pcard, NULL);
@@ -1636,7 +1636,7 @@
 	.name		= "miro",
 	.id_table	= snd_miro_pnpids,
 	.probe		= snd_miro_pnp_probe,
-	.remove		= __devexit_p(snd_miro_pnp_remove),
+	.remove		= snd_miro_pnp_remove,
 };
 #endif
 
diff --git a/sound/isa/opti9xx/opti92x-ad1848.c b/sound/isa/opti9xx/opti92x-ad1848.c
index 2899c9f..b41ed86 100644
--- a/sound/isa/opti9xx/opti92x-ad1848.c
+++ b/sound/isa/opti9xx/opti92x-ad1848.c
@@ -186,8 +186,8 @@
 	"82C930",	"82C931",	"82C933"
 };
 
-static int __devinit snd_opti9xx_init(struct snd_opti9xx *chip,
-				      unsigned short hardware)
+static int snd_opti9xx_init(struct snd_opti9xx *chip,
+			    unsigned short hardware)
 {
 	static int opti9xx_mc_size[] = {7, 7, 10, 10, 2, 2, 2};
 
@@ -593,7 +593,7 @@
 		db_scale_4bit_12db_max),
 };
 
-static int __devinit snd_opti93x_mixer(struct snd_wss *chip)
+static int snd_opti93x_mixer(struct snd_wss *chip)
 {
 	struct snd_card *card;
 	unsigned int idx;
@@ -666,7 +666,7 @@
 
 #endif /* OPTi93X */
 
-static int __devinit snd_opti9xx_read_check(struct snd_opti9xx *chip)
+static int snd_opti9xx_read_check(struct snd_opti9xx *chip)
 {
 	unsigned char value;
 #ifdef OPTi93X
@@ -707,8 +707,8 @@
 	return -ENODEV;
 }
 
-static int __devinit snd_card_opti9xx_detect(struct snd_card *card,
-					     struct snd_opti9xx *chip)
+static int snd_card_opti9xx_detect(struct snd_card *card,
+				   struct snd_opti9xx *chip)
 {
 	int i, err;
 
@@ -732,9 +732,9 @@
 }
 
 #ifdef CONFIG_PNP
-static int __devinit snd_card_opti9xx_pnp(struct snd_opti9xx *chip,
-					  struct pnp_card_link *card,
-					  const struct pnp_card_device_id *pid)
+static int snd_card_opti9xx_pnp(struct snd_opti9xx *chip,
+				struct pnp_card_link *card,
+				const struct pnp_card_device_id *pid)
 {
 	struct pnp_dev *pdev;
 	int err;
@@ -817,7 +817,7 @@
 	}
 }
 
-static int __devinit snd_opti9xx_probe(struct snd_card *card)
+static int snd_opti9xx_probe(struct snd_card *card)
 {
 	static long possible_ports[] = {0x530, 0xe80, 0xf40, 0x604, -1};
 	int error;
@@ -952,8 +952,8 @@
 	return 0;
 }
 
-static int __devinit snd_opti9xx_isa_match(struct device *devptr,
-					   unsigned int dev)
+static int snd_opti9xx_isa_match(struct device *devptr,
+				 unsigned int dev)
 {
 #ifdef CONFIG_PNP
 	if (snd_opti9xx_pnp_is_probed)
@@ -964,8 +964,8 @@
 	return 1;
 }
 
-static int __devinit snd_opti9xx_isa_probe(struct device *devptr,
-					   unsigned int dev)
+static int snd_opti9xx_isa_probe(struct device *devptr,
+				 unsigned int dev)
 {
 	struct snd_card *card;
 	int error;
@@ -1031,8 +1031,8 @@
 	return 0;
 }
 
-static int __devexit snd_opti9xx_isa_remove(struct device *devptr,
-					    unsigned int dev)
+static int snd_opti9xx_isa_remove(struct device *devptr,
+				  unsigned int dev)
 {
 	snd_card_free(dev_get_drvdata(devptr));
 	dev_set_drvdata(devptr, NULL);
@@ -1083,7 +1083,7 @@
 static struct isa_driver snd_opti9xx_driver = {
 	.match		= snd_opti9xx_isa_match,
 	.probe		= snd_opti9xx_isa_probe,
-	.remove		= __devexit_p(snd_opti9xx_isa_remove),
+	.remove		= snd_opti9xx_isa_remove,
 #ifdef CONFIG_PM
 	.suspend	= snd_opti9xx_isa_suspend,
 	.resume		= snd_opti9xx_isa_resume,
@@ -1094,8 +1094,8 @@
 };
 
 #ifdef CONFIG_PNP
-static int __devinit snd_opti9xx_pnp_probe(struct pnp_card_link *pcard,
-					   const struct pnp_card_device_id *pid)
+static int snd_opti9xx_pnp_probe(struct pnp_card_link *pcard,
+				 const struct pnp_card_device_id *pid)
 {
 	struct snd_card *card;
 	int error, hw;
@@ -1146,7 +1146,7 @@
 	return 0;
 }
 
-static void __devexit snd_opti9xx_pnp_remove(struct pnp_card_link * pcard)
+static void snd_opti9xx_pnp_remove(struct pnp_card_link *pcard)
 {
 	snd_card_free(pnp_get_card_drvdata(pcard));
 	pnp_set_card_drvdata(pcard, NULL);
@@ -1171,7 +1171,7 @@
 	.name		= "opti9xx",
 	.id_table	= snd_opti9xx_pnpids,
 	.probe		= snd_opti9xx_pnp_probe,
-	.remove		= __devexit_p(snd_opti9xx_pnp_remove),
+	.remove		= snd_opti9xx_pnp_remove,
 #ifdef CONFIG_PM
 	.suspend	= snd_opti9xx_pnp_suspend,
 	.resume		= snd_opti9xx_pnp_resume,
diff --git a/sound/isa/sb/emu8000.c b/sound/isa/sb/emu8000.c
index 2aae6a0..45fcdff 100644
--- a/sound/isa/sb/emu8000.c
+++ b/sound/isa/sb/emu8000.c
@@ -131,7 +131,7 @@
 
 /*
  */
-static void __devinit
+static void
 snd_emu8000_read_wait(struct snd_emu8000 *emu)
 {
 	while ((EMU8000_SMALR_READ(emu) & 0x80000000) != 0) {
@@ -143,7 +143,7 @@
 
 /*
  */
-static void __devinit
+static void
 snd_emu8000_write_wait(struct snd_emu8000 *emu)
 {
 	while ((EMU8000_SMALW_READ(emu) & 0x80000000) != 0) {
@@ -156,7 +156,7 @@
 /*
  * detect a card at the given port
  */
-static int __devinit
+static int
 snd_emu8000_detect(struct snd_emu8000 *emu)
 {
 	/* Initialise */
@@ -182,7 +182,7 @@
 /*
  * intiailize audio channels
  */
-static void __devinit
+static void
 init_audio(struct snd_emu8000 *emu)
 {
 	int ch;
@@ -223,7 +223,7 @@
 /*
  * initialize DMA address
  */
-static void __devinit
+static void
 init_dma(struct snd_emu8000 *emu)
 {
 	EMU8000_SMALR_WRITE(emu, 0);
@@ -235,7 +235,7 @@
 /*
  * initialization arrays; from ADIP
  */
-static unsigned short init1[128] /*__devinitdata*/ = {
+static unsigned short init1[128] = {
 	0x03ff, 0x0030,  0x07ff, 0x0130, 0x0bff, 0x0230,  0x0fff, 0x0330,
 	0x13ff, 0x0430,  0x17ff, 0x0530, 0x1bff, 0x0630,  0x1fff, 0x0730,
 	0x23ff, 0x0830,  0x27ff, 0x0930, 0x2bff, 0x0a30,  0x2fff, 0x0b30,
@@ -257,7 +257,7 @@
 	0xf3ff, 0x0c30,  0xf7ff, 0x0d30, 0xfbff, 0x0e30,  0xffff, 0x0f30,
 };
 
-static unsigned short init2[128] /*__devinitdata*/ = {
+static unsigned short init2[128] = {
 	0x03ff, 0x8030, 0x07ff, 0x8130, 0x0bff, 0x8230, 0x0fff, 0x8330,
 	0x13ff, 0x8430, 0x17ff, 0x8530, 0x1bff, 0x8630, 0x1fff, 0x8730,
 	0x23ff, 0x8830, 0x27ff, 0x8930, 0x2bff, 0x8a30, 0x2fff, 0x8b30,
@@ -279,7 +279,7 @@
 	0xf3ff, 0x8c30, 0xf7ff, 0x8d30, 0xfbff, 0x8e30, 0xffff, 0x8f30,
 };
 
-static unsigned short init3[128] /*__devinitdata*/ = {
+static unsigned short init3[128] = {
 	0x0C10, 0x8470, 0x14FE, 0xB488, 0x167F, 0xA470, 0x18E7, 0x84B5,
 	0x1B6E, 0x842A, 0x1F1D, 0x852A, 0x0DA3, 0x8F7C, 0x167E, 0xF254,
 	0x0000, 0x842A, 0x0001, 0x852A, 0x18E6, 0x8BAA, 0x1B6D, 0xF234,
@@ -301,7 +301,7 @@
 	0x1342, 0xD36E, 0x3EC7, 0xB3FF, 0x0000, 0x8365, 0x1420, 0x9570,
 };
 
-static unsigned short init4[128] /*__devinitdata*/ = {
+static unsigned short init4[128] = {
 	0x0C10, 0x8470, 0x14FE, 0xB488, 0x167F, 0xA470, 0x18E7, 0x84B5,
 	0x1B6E, 0x842A, 0x1F1D, 0x852A, 0x0DA3, 0x0F7C, 0x167E, 0x7254,
 	0x0000, 0x842A, 0x0001, 0x852A, 0x18E6, 0x0BAA, 0x1B6D, 0x7234,
@@ -327,7 +327,7 @@
  * Taken from the oss driver, not obvious from the doc how this
  * is meant to work
  */
-static void __devinit
+static void
 send_array(struct snd_emu8000 *emu, unsigned short *data, int size)
 {
 	int i;
@@ -349,7 +349,7 @@
  * Send initialization arrays to start up, this just follows the
  * initialisation sequence in the adip.
  */
-static void __devinit
+static void
 init_arrays(struct snd_emu8000 *emu)
 {
 	send_array(emu, init1, ARRAY_SIZE(init1)/4);
@@ -375,7 +375,7 @@
  * seems that the only way to do this is to use the one channel and keep
  * reallocating between read and write.
  */
-static void __devinit
+static void
 size_dram(struct snd_emu8000 *emu)
 {
 	int i, size, detected_size;
@@ -512,7 +512,7 @@
 /*
  * The main initialization routine.
  */
-static void __devinit
+static void
 snd_emu8000_init_hw(struct snd_emu8000 *emu)
 {
 	int i;
@@ -1031,7 +1031,7 @@
 /*
  * create and attach mixer elements for WaveTable treble/bass controls
  */
-static int __devinit
+static int
 snd_emu8000_create_mixer(struct snd_card *card, struct snd_emu8000 *emu)
 {
 	int i, err = 0;
@@ -1082,7 +1082,7 @@
 /*
  * initialize and register emu8000 synth device.
  */
-int __devinit
+int
 snd_emu8000_new(struct snd_card *card, int index, long port, int seq_ports,
 		struct snd_seq_device **awe_ret)
 {
diff --git a/sound/isa/sb/jazz16.c b/sound/isa/sb/jazz16.c
index 410758c..4961da4 100644
--- a/sound/isa/sb/jazz16.c
+++ b/sound/isa/sb/jazz16.c
@@ -78,8 +78,8 @@
 	return snd_sb8dsp_interrupt(chip);
 }
 
-static int __devinit jazz16_configure_ports(unsigned long port,
-					    unsigned long mpu_port, int idx)
+static int jazz16_configure_ports(unsigned long port,
+				  unsigned long mpu_port, int idx)
 {
 	unsigned char val;
 
@@ -99,8 +99,8 @@
 	return 0;
 }
 
-static int __devinit jazz16_detect_board(unsigned long port,
-					 unsigned long mpu_port)
+static int jazz16_detect_board(unsigned long port,
+			       unsigned long mpu_port)
 {
 	int err;
 	int val;
@@ -156,7 +156,7 @@
 	return err;
 }
 
-static int __devinit jazz16_configure_board(struct snd_sb *chip, int mpu_irq)
+static int jazz16_configure_board(struct snd_sb *chip, int mpu_irq)
 {
 	static unsigned char jazz_irq_bits[] = { 0, 0, 2, 3, 0, 1, 0, 4,
 						 0, 2, 5, 0, 0, 0, 0, 6 };
@@ -183,7 +183,7 @@
 	return 0;
 }
 
-static int __devinit snd_jazz16_match(struct device *devptr, unsigned int dev)
+static int snd_jazz16_match(struct device *devptr, unsigned int dev)
 {
 	if (!enable[dev])
 		return 0;
@@ -218,7 +218,7 @@
 	return 1;
 }
 
-static int __devinit snd_jazz16_probe(struct device *devptr, unsigned int dev)
+static int snd_jazz16_probe(struct device *devptr, unsigned int dev)
 {
 	struct snd_card *card;
 	struct snd_card_jazz16 *jazz16;
@@ -341,7 +341,7 @@
 	return err;
 }
 
-static int __devexit snd_jazz16_remove(struct device *devptr, unsigned int dev)
+static int snd_jazz16_remove(struct device *devptr, unsigned int dev)
 {
 	struct snd_card *card = dev_get_drvdata(devptr);
 
@@ -380,7 +380,7 @@
 static struct isa_driver snd_jazz16_driver = {
 	.match		= snd_jazz16_match,
 	.probe		= snd_jazz16_probe,
-	.remove		= __devexit_p(snd_jazz16_remove),
+	.remove		= snd_jazz16_remove,
 #ifdef CONFIG_PM
 	.suspend	= snd_jazz16_suspend,
 	.resume		= snd_jazz16_resume,
diff --git a/sound/isa/sb/sb16.c b/sound/isa/sb/sb16.c
index 39b8eca..50dbec4 100644
--- a/sound/isa/sb/sb16.c
+++ b/sound/isa/sb/sb16.c
@@ -250,9 +250,9 @@
 
 #ifdef CONFIG_PNP
 
-static int __devinit snd_card_sb16_pnp(int dev, struct snd_card_sb16 *acard,
-				       struct pnp_card_link *card,
-				       const struct pnp_card_device_id *id)
+static int snd_card_sb16_pnp(int dev, struct snd_card_sb16 *acard,
+			     struct pnp_card_link *card,
+			     const struct pnp_card_device_id *id)
 {
 	struct pnp_dev *pdev;
 	int err;
@@ -337,7 +337,7 @@
 	return 0;
 }
 
-static int __devinit snd_sb16_probe(struct snd_card *card, int dev)
+static int snd_sb16_probe(struct snd_card *card, int dev)
 {
 	int xirq, xdma8, xdma16;
 	struct snd_sb *chip;
@@ -487,7 +487,7 @@
 }
 #endif
 
-static int __devinit snd_sb16_isa_probe1(int dev, struct device *pdev)
+static int snd_sb16_isa_probe1(int dev, struct device *pdev)
 {
 	struct snd_card_sb16 *acard;
 	struct snd_card *card;
@@ -517,12 +517,12 @@
 }
 
 
-static int __devinit snd_sb16_isa_match(struct device *pdev, unsigned int dev)
+static int snd_sb16_isa_match(struct device *pdev, unsigned int dev)
 {
 	return enable[dev] && !is_isapnp_selected(dev);
 }
 
-static int __devinit snd_sb16_isa_probe(struct device *pdev, unsigned int dev)
+static int snd_sb16_isa_probe(struct device *pdev, unsigned int dev)
 {
 	int err;
 	static int possible_irqs[] = {5, 9, 10, 7, -1};
@@ -563,7 +563,7 @@
 	}
 }
 
-static int __devexit snd_sb16_isa_remove(struct device *pdev, unsigned int dev)
+static int snd_sb16_isa_remove(struct device *pdev, unsigned int dev)
 {
 	snd_card_free(dev_get_drvdata(pdev));
 	dev_set_drvdata(pdev, NULL);
@@ -592,7 +592,7 @@
 static struct isa_driver snd_sb16_isa_driver = {
 	.match		= snd_sb16_isa_match,
 	.probe		= snd_sb16_isa_probe,
-	.remove		= __devexit_p(snd_sb16_isa_remove),
+	.remove		= snd_sb16_isa_remove,
 #ifdef CONFIG_PM
 	.suspend	= snd_sb16_isa_suspend,
 	.resume		= snd_sb16_isa_resume,
@@ -604,8 +604,8 @@
 
 
 #ifdef CONFIG_PNP
-static int __devinit snd_sb16_pnp_detect(struct pnp_card_link *pcard,
-					 const struct pnp_card_device_id *pid)
+static int snd_sb16_pnp_detect(struct pnp_card_link *pcard,
+			       const struct pnp_card_device_id *pid)
 {
 	static int dev;
 	struct snd_card *card;
@@ -631,7 +631,7 @@
 	return -ENODEV;
 }
 
-static void __devexit snd_sb16_pnp_remove(struct pnp_card_link * pcard)
+static void snd_sb16_pnp_remove(struct pnp_card_link *pcard)
 {
 	snd_card_free(pnp_get_card_drvdata(pcard));
 	pnp_set_card_drvdata(pcard, NULL);
@@ -657,7 +657,7 @@
 #endif
 	.id_table = snd_sb16_pnpids,
 	.probe = snd_sb16_pnp_detect,
-	.remove = __devexit_p(snd_sb16_pnp_remove),
+	.remove = snd_sb16_pnp_remove,
 #ifdef CONFIG_PM
 	.suspend = snd_sb16_pnp_suspend,
 	.resume = snd_sb16_pnp_resume,
diff --git a/sound/isa/sb/sb8.c b/sound/isa/sb/sb8.c
index ab5cebe..237d964 100644
--- a/sound/isa/sb/sb8.c
+++ b/sound/isa/sb/sb8.c
@@ -79,7 +79,7 @@
 	release_and_free_resource(acard->fm_res);
 }
 
-static int __devinit snd_sb8_match(struct device *pdev, unsigned int dev)
+static int snd_sb8_match(struct device *pdev, unsigned int dev)
 {
 	if (!enable[dev])
 		return 0;
@@ -94,7 +94,7 @@
 	return 1;
 }
 
-static int __devinit snd_sb8_probe(struct device *pdev, unsigned int dev)
+static int snd_sb8_probe(struct device *pdev, unsigned int dev)
 {
 	struct snd_sb *chip;
 	struct snd_card *card;
@@ -205,7 +205,7 @@
 	return err;
 }
 
-static int __devexit snd_sb8_remove(struct device *pdev, unsigned int dev)
+static int snd_sb8_remove(struct device *pdev, unsigned int dev)
 {
 	snd_card_free(dev_get_drvdata(pdev));
 	dev_set_drvdata(pdev, NULL);
@@ -244,7 +244,7 @@
 static struct isa_driver snd_sb8_driver = {
 	.match		= snd_sb8_match,
 	.probe		= snd_sb8_probe,
-	.remove		= __devexit_p(snd_sb8_remove),
+	.remove		= snd_sb8_remove,
 #ifdef CONFIG_PM
 	.suspend	= snd_sb8_suspend,
 	.resume		= snd_sb8_resume,
diff --git a/sound/isa/sc6000.c b/sound/isa/sc6000.c
index d97d0f3..5376ebf 100644
--- a/sound/isa/sc6000.c
+++ b/sound/isa/sc6000.c
@@ -121,7 +121,7 @@
 /*
  * sc6000_irq_to_softcfg - Decode irq number into cfg code.
  */
-static __devinit unsigned char sc6000_irq_to_softcfg(int irq)
+static unsigned char sc6000_irq_to_softcfg(int irq)
 {
 	unsigned char val = 0;
 
@@ -150,7 +150,7 @@
 /*
  * sc6000_dma_to_softcfg - Decode dma number into cfg code.
  */
-static __devinit unsigned char sc6000_dma_to_softcfg(int dma)
+static unsigned char sc6000_dma_to_softcfg(int dma)
 {
 	unsigned char val = 0;
 
@@ -173,7 +173,7 @@
 /*
  * sc6000_mpu_irq_to_softcfg - Decode MPU-401 irq number into cfg code.
  */
-static __devinit unsigned char sc6000_mpu_irq_to_softcfg(int mpu_irq)
+static unsigned char sc6000_mpu_irq_to_softcfg(int mpu_irq)
 {
 	unsigned char val = 0;
 
@@ -242,8 +242,8 @@
 	return -EIO;
 }
 
-static int __devinit sc6000_dsp_get_answer(char __iomem *vport, int command,
-					   char *data, int data_len)
+static int sc6000_dsp_get_answer(char __iomem *vport, int command,
+				 char *data, int data_len)
 {
 	int len = 0;
 
@@ -269,7 +269,7 @@
 	return len ? len : -EIO;
 }
 
-static int __devinit sc6000_dsp_reset(char __iomem *vport)
+static int sc6000_dsp_reset(char __iomem *vport)
 {
 	iowrite8(1, vport + DSP_RESET);
 	udelay(10);
@@ -281,7 +281,7 @@
 }
 
 /* detection and initialization */
-static int __devinit sc6000_hw_cfg_write(char __iomem *vport, const int *cfg)
+static int sc6000_hw_cfg_write(char __iomem *vport, const int *cfg)
 {
 	if (sc6000_write(vport, COMMAND_6C) < 0) {
 		snd_printk(KERN_WARNING "CMD 0x%x: failed!\n", COMMAND_6C);
@@ -345,8 +345,8 @@
 	return 0;
 }
 
-static int __devinit sc6000_init_mss(char __iomem *vport, int config,
-				     char __iomem *vmss_port, int mss_config)
+static int sc6000_init_mss(char __iomem *vport, int config,
+			   char __iomem *vmss_port, int mss_config)
 {
 	if (sc6000_write(vport, DSP_INIT_MSS)) {
 		snd_printk(KERN_ERR "sc6000_init_mss [0x%x]: failed!\n",
@@ -364,9 +364,9 @@
 	return 0;
 }
 
-static void __devinit sc6000_hw_cfg_encode(char __iomem *vport, int *cfg,
-					   long xport, long xmpu,
-					   long xmss_port, int joystick)
+static void sc6000_hw_cfg_encode(char __iomem *vport, int *cfg,
+				 long xport, long xmpu,
+				 long xmss_port, int joystick)
 {
 	cfg[0] = 0;
 	cfg[1] = 0;
@@ -386,8 +386,8 @@
 	snd_printd("hw cfg %x, %x\n", cfg[0], cfg[1]);
 }
 
-static int __devinit sc6000_init_board(char __iomem *vport,
-					char __iomem *vmss_port, int dev)
+static int sc6000_init_board(char __iomem *vport,
+			     char __iomem *vmss_port, int dev)
 {
 	char answer[15];
 	char version[2];
@@ -467,7 +467,7 @@
 	return 0;
 }
 
-static int __devinit snd_sc6000_mixer(struct snd_wss *chip)
+static int snd_sc6000_mixer(struct snd_wss *chip)
 {
 	struct snd_card *card = chip->card;
 	struct snd_ctl_elem_id id1, id2;
@@ -502,7 +502,7 @@
 	return 0;
 }
 
-static int __devinit snd_sc6000_match(struct device *devptr, unsigned int dev)
+static int snd_sc6000_match(struct device *devptr, unsigned int dev)
 {
 	if (!enable[dev])
 		return 0;
@@ -545,7 +545,7 @@
 	return 1;
 }
 
-static int __devinit snd_sc6000_probe(struct device *devptr, unsigned int dev)
+static int snd_sc6000_probe(struct device *devptr, unsigned int dev)
 {
 	static int possible_irqs[] = { 5, 7, 9, 10, 11, -1 };
 	static int possible_dmas[] = { 1, 3, 0, -1 };
@@ -687,7 +687,7 @@
 	return err;
 }
 
-static int __devexit snd_sc6000_remove(struct device *devptr, unsigned int dev)
+static int snd_sc6000_remove(struct device *devptr, unsigned int dev)
 {
 	struct snd_card *card = dev_get_drvdata(devptr);
 	char __iomem **vport = card->private_data;
@@ -706,7 +706,7 @@
 static struct isa_driver snd_sc6000_driver = {
 	.match		= snd_sc6000_match,
 	.probe		= snd_sc6000_probe,
-	.remove		= __devexit_p(snd_sc6000_remove),
+	.remove		= snd_sc6000_remove,
 	/* FIXME: suspend/resume */
 	.driver		= {
 		.name	= DRV_NAME,
diff --git a/sound/isa/sscape.c b/sound/isa/sscape.c
index 8490f59..42a0097 100644
--- a/sound/isa/sscape.c
+++ b/sound/isa/sscape.c
@@ -683,7 +683,7 @@
  * These IRQs are encoded as bit patterns so that they can be
  * written to the control registers.
  */
-static unsigned __devinit get_irq_config(int sscape_type, int irq)
+static unsigned get_irq_config(int sscape_type, int irq)
 {
 	static const int valid_irq[] = { 9, 5, 7, 10 };
 	static const int old_irq[] = { 9, 7, 5, 15 };
@@ -706,7 +706,7 @@
  * Perform certain arcane port-checks to see whether there
  * is a SoundScape board lurking behind the given ports.
  */
-static int __devinit detect_sscape(struct soundscape *s, long wss_io)
+static int detect_sscape(struct soundscape *s, long wss_io)
 {
 	unsigned long flags;
 	unsigned d;
@@ -817,8 +817,8 @@
 /*
  * Initialse an MPU-401 subdevice for MIDI support on the SoundScape.
  */
-static int __devinit create_mpu401(struct snd_card *card, int devnum,
-				   unsigned long port, int irq)
+static int create_mpu401(struct snd_card *card, int devnum,
+			 unsigned long port, int irq)
 {
 	struct soundscape *sscape = get_card_soundscape(card);
 	struct snd_rawmidi *rawmidi;
@@ -845,8 +845,8 @@
  * try to support at least some of the extra bits by overriding
  * some of the CS4231 callback.
  */
-static int __devinit create_ad1845(struct snd_card *card, unsigned port,
-				   int irq, int dma1, int dma2)
+static int create_ad1845(struct snd_card *card, unsigned port,
+			 int irq, int dma1, int dma2)
 {
 	register struct soundscape *sscape = get_card_soundscape(card);
 	struct snd_wss *chip;
@@ -937,7 +937,7 @@
  * Create an ALSA soundcard entry for the SoundScape, using
  * the given list of port, IRQ and DMA resources.
  */
-static int __devinit create_sscape(int dev, struct snd_card *card)
+static int create_sscape(int dev, struct snd_card *card)
 {
 	struct soundscape *sscape = get_card_soundscape(card);
 	unsigned dma_cfg;
@@ -1143,7 +1143,7 @@
 }
 
 
-static int __devinit snd_sscape_match(struct device *pdev, unsigned int i)
+static int snd_sscape_match(struct device *pdev, unsigned int i)
 {
 	/*
 	 * Make sure we were given ALL of the other parameters.
@@ -1163,7 +1163,7 @@
 	return 1;
 }
 
-static int __devinit snd_sscape_probe(struct device *pdev, unsigned int dev)
+static int snd_sscape_probe(struct device *pdev, unsigned int dev)
 {
 	struct snd_card *card;
 	struct soundscape *sscape;
@@ -1197,7 +1197,7 @@
 	return ret;
 }
 
-static int __devexit snd_sscape_remove(struct device *devptr, unsigned int dev)
+static int snd_sscape_remove(struct device *devptr, unsigned int dev)
 {
 	snd_card_free(dev_get_drvdata(devptr));
 	dev_set_drvdata(devptr, NULL);
@@ -1209,7 +1209,7 @@
 static struct isa_driver snd_sscape_driver = {
 	.match		= snd_sscape_match,
 	.probe		= snd_sscape_probe,
-	.remove		= __devexit_p(snd_sscape_remove),
+	.remove		= snd_sscape_remove,
 	/* FIXME: suspend/resume */
 	.driver		= {
 		.name	= DEV_NAME
@@ -1217,7 +1217,7 @@
 };
 
 #ifdef CONFIG_PNP
-static inline int __devinit get_next_autoindex(int i)
+static inline int get_next_autoindex(int i)
 {
 	while (i < SNDRV_CARDS && port[i] != SNDRV_AUTO_PORT)
 		++i;
@@ -1225,8 +1225,8 @@
 }
 
 
-static int __devinit sscape_pnp_detect(struct pnp_card_link *pcard,
-				       const struct pnp_card_device_id *pid)
+static int sscape_pnp_detect(struct pnp_card_link *pcard,
+			     const struct pnp_card_device_id *pid)
 {
 	static int idx = 0;
 	struct pnp_dev *dev;
@@ -1310,7 +1310,7 @@
 	return ret;
 }
 
-static void __devexit sscape_pnp_remove(struct pnp_card_link * pcard)
+static void sscape_pnp_remove(struct pnp_card_link *pcard)
 {
 	snd_card_free(pnp_get_card_drvdata(pcard));
 	pnp_set_card_drvdata(pcard, NULL);
@@ -1321,7 +1321,7 @@
 	.name = "sscape",
 	.id_table = sscape_pnpids,
 	.probe = sscape_pnp_detect,
-	.remove = __devexit_p(sscape_pnp_remove),
+	.remove = sscape_pnp_remove,
 };
 
 #endif /* CONFIG_PNP */
diff --git a/sound/isa/wavefront/wavefront.c b/sound/isa/wavefront/wavefront.c
index e0a7327..fe5dd98 100644
--- a/sound/isa/wavefront/wavefront.c
+++ b/sound/isa/wavefront/wavefront.c
@@ -98,7 +98,7 @@
 
 MODULE_DEVICE_TABLE(pnp_card, snd_wavefront_pnpids);
 
-static int __devinit
+static int
 snd_wavefront_pnp (int dev, snd_wavefront_card_t *acard, struct pnp_card_link *card,
 		   const struct pnp_card_device_id *id)
 {
@@ -231,10 +231,9 @@
 	return IRQ_HANDLED;
 }
 
-static struct snd_hwdep * __devinit
-snd_wavefront_new_synth (struct snd_card *card,
-			 int hw_dev,
-			 snd_wavefront_card_t *acard)
+static struct snd_hwdep *snd_wavefront_new_synth(struct snd_card *card,
+						 int hw_dev,
+						 snd_wavefront_card_t *acard)
 {
 	struct snd_hwdep *wavefront_synth;
 
@@ -257,11 +256,10 @@
 	return wavefront_synth;
 }
 
-static struct snd_hwdep * __devinit
-snd_wavefront_new_fx (struct snd_card *card,
-		      int hw_dev,
-		      snd_wavefront_card_t *acard,
-		      unsigned long port)
+static struct snd_hwdep *snd_wavefront_new_fx(struct snd_card *card,
+					      int hw_dev,
+					      snd_wavefront_card_t *acard,
+					      unsigned long port)
 
 {
 	struct snd_hwdep *fx_processor;
@@ -284,12 +282,11 @@
 static snd_wavefront_mpu_id internal_id = internal_mpu;
 static snd_wavefront_mpu_id external_id = external_mpu;
 
-static struct snd_rawmidi *__devinit
-snd_wavefront_new_midi (struct snd_card *card,
-			int midi_dev,
-			snd_wavefront_card_t *acard,
-			unsigned long port,
-			snd_wavefront_mpu_id mpu)
+static struct snd_rawmidi *snd_wavefront_new_midi(struct snd_card *card,
+						  int midi_dev,
+						  snd_wavefront_card_t *acard,
+						  unsigned long port,
+						  snd_wavefront_mpu_id mpu)
 
 {
 	struct snd_rawmidi *rmidi;
@@ -361,7 +358,7 @@
 	return 0;
 }
 
-static int __devinit
+static int
 snd_wavefront_probe (struct snd_card *card, int dev)
 {
 	snd_wavefront_card_t *acard = card->private_data;
@@ -541,8 +538,8 @@
 	return snd_card_register(card);
 }	
 
-static int __devinit snd_wavefront_isa_match(struct device *pdev,
-					     unsigned int dev)
+static int snd_wavefront_isa_match(struct device *pdev,
+				   unsigned int dev)
 {
 	if (!enable[dev])
 		return 0;
@@ -561,8 +558,8 @@
 	return 1;
 }
 
-static int __devinit snd_wavefront_isa_probe(struct device *pdev,
-					     unsigned int dev)
+static int snd_wavefront_isa_probe(struct device *pdev,
+				   unsigned int dev)
 {
 	struct snd_card *card;
 	int err;
@@ -580,8 +577,8 @@
 	return 0;
 }
 
-static int __devexit snd_wavefront_isa_remove(struct device *devptr,
-					      unsigned int dev)
+static int snd_wavefront_isa_remove(struct device *devptr,
+				    unsigned int dev)
 {
 	snd_card_free(dev_get_drvdata(devptr));
 	dev_set_drvdata(devptr, NULL);
@@ -593,7 +590,7 @@
 static struct isa_driver snd_wavefront_driver = {
 	.match		= snd_wavefront_isa_match,
 	.probe		= snd_wavefront_isa_probe,
-	.remove		= __devexit_p(snd_wavefront_isa_remove),
+	.remove		= snd_wavefront_isa_remove,
 	/* FIXME: suspend, resume */
 	.driver		= {
 		.name	= DEV_NAME
@@ -602,8 +599,8 @@
 
 
 #ifdef CONFIG_PNP
-static int __devinit snd_wavefront_pnp_detect(struct pnp_card_link *pcard,
-					const struct pnp_card_device_id *pid)
+static int snd_wavefront_pnp_detect(struct pnp_card_link *pcard,
+				    const struct pnp_card_device_id *pid)
 {
 	static int dev;
 	struct snd_card *card;
@@ -637,7 +634,7 @@
 	return 0;
 }
 
-static void __devexit snd_wavefront_pnp_remove(struct pnp_card_link * pcard)
+static void snd_wavefront_pnp_remove(struct pnp_card_link *pcard)
 {
 	snd_card_free(pnp_get_card_drvdata(pcard));
 	pnp_set_card_drvdata(pcard, NULL);
@@ -648,7 +645,7 @@
 	.name		= "wavefront",
 	.id_table	= snd_wavefront_pnpids,
 	.probe		= snd_wavefront_pnp_detect,
-	.remove		= __devexit_p(snd_wavefront_pnp_remove),
+	.remove		= snd_wavefront_pnp_remove,
 	/* FIXME: suspend,resume */
 };
 
diff --git a/sound/isa/wavefront/wavefront_fx.c b/sound/isa/wavefront/wavefront_fx.c
index e51e090..b77883c 100644
--- a/sound/isa/wavefront/wavefront_fx.c
+++ b/sound/isa/wavefront/wavefront_fx.c
@@ -240,7 +240,7 @@
    that outputs it.
 */
 
-int __devinit
+int
 snd_wavefront_fx_start (snd_wavefront_t *dev)
 {
 	unsigned int i;
diff --git a/sound/isa/wavefront/wavefront_midi.c b/sound/isa/wavefront/wavefront_midi.c
index 65329f3..7dc9916 100644
--- a/sound/isa/wavefront/wavefront_midi.c
+++ b/sound/isa/wavefront/wavefront_midi.c
@@ -481,7 +481,7 @@
 	spin_unlock_irqrestore (&card->wavefront.midi.virtual, flags);
 }
 
-int __devinit
+int
 snd_wavefront_midi_start (snd_wavefront_card_t *card)
 
 {
diff --git a/sound/isa/wavefront/wavefront_synth.c b/sound/isa/wavefront/wavefront_synth.c
index b1bf8d4..a2f87f9 100644
--- a/sound/isa/wavefront/wavefront_synth.c
+++ b/sound/isa/wavefront/wavefront_synth.c
@@ -1739,7 +1739,7 @@
 7 Unused
 */
 
-static int __devinit
+static int
 snd_wavefront_interrupt_bits (int irq)
 
 {
@@ -1767,7 +1767,7 @@
 	return bits;
 }
 
-static void __devinit
+static void
 wavefront_should_cause_interrupt (snd_wavefront_t *dev, 
 				  int val, int port, unsigned long timeout)
 
@@ -1786,7 +1786,7 @@
 	}
 }
 
-static int __devinit
+static int
 wavefront_reset_to_cleanliness (snd_wavefront_t *dev)
 
 {
@@ -1937,7 +1937,7 @@
 	return (1);
 }
 
-static int __devinit
+static int
 wavefront_download_firmware (snd_wavefront_t *dev, char *path)
 
 {
@@ -2010,7 +2010,7 @@
 }
 
 
-static int __devinit
+static int
 wavefront_do_reset (snd_wavefront_t *dev)
 
 {
@@ -2099,7 +2099,7 @@
 	return 1;
 }
 
-int __devinit
+int
 snd_wavefront_start (snd_wavefront_t *dev)
 
 {
@@ -2141,7 +2141,7 @@
 	return (0);
 }
 
-int __devinit
+int
 snd_wavefront_detect (snd_wavefront_card_t *card)
 
 {
diff --git a/sound/mips/au1x00.c b/sound/mips/au1x00.c
index 3f3ec0b..224f54b 100644
--- a/sound/mips/au1x00.c
+++ b/sound/mips/au1x00.c
@@ -439,7 +439,7 @@
 	.pointer		= snd_au1000_pointer,
 };
 
-static int __devinit
+static int
 snd_au1000_pcm_new(struct snd_au1000 *au1000)
 {
 	struct snd_pcm *pcm;
@@ -552,7 +552,7 @@
 	spin_unlock(&au1000->ac97_lock);
 }
 
-static int __devinit
+static int
 snd_au1000_ac97_new(struct snd_au1000 *au1000)
 {
 	int err;
diff --git a/sound/mips/hal2.c b/sound/mips/hal2.c
index 5f88d1f..7420c59 100644
--- a/sound/mips/hal2.c
+++ b/sound/mips/hal2.c
@@ -260,7 +260,7 @@
 	return old != new;
 }
 
-static struct snd_kcontrol_new hal2_ctrl_headphone __devinitdata = {
+static struct snd_kcontrol_new hal2_ctrl_headphone = {
 	.iface          = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name           = "Headphone Playback Volume",
 	.access         = SNDRV_CTL_ELEM_ACCESS_READWRITE,
@@ -270,7 +270,7 @@
 	.put            = hal2_gain_put,
 };
 
-static struct snd_kcontrol_new hal2_ctrl_mic __devinitdata = {
+static struct snd_kcontrol_new hal2_ctrl_mic = {
 	.iface          = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name           = "Mic Capture Volume",
 	.access         = SNDRV_CTL_ELEM_ACCESS_READWRITE,
@@ -280,7 +280,7 @@
 	.put            = hal2_gain_put,
 };
 
-static int __devinit hal2_mixer_create(struct snd_hal2 *hal2)
+static int hal2_mixer_create(struct snd_hal2 *hal2)
 {
 	int err;
 
@@ -733,7 +733,7 @@
 	.ack =         hal2_capture_ack,
 };
 
-static int __devinit hal2_pcm_create(struct snd_hal2 *hal2)
+static int hal2_pcm_create(struct snd_hal2 *hal2)
 {
 	struct snd_pcm *pcm;
 	int err;
@@ -874,7 +874,7 @@
 	return 0;
 }
 
-static int __devinit hal2_probe(struct platform_device *pdev)
+static int hal2_probe(struct platform_device *pdev)
 {
 	struct snd_card *card;
 	struct snd_hal2 *chip;
@@ -917,7 +917,7 @@
 	return 0;
 }
 
-static int __devexit hal2_remove(struct platform_device *pdev)
+static int hal2_remove(struct platform_device *pdev)
 {
 	struct snd_card *card = platform_get_drvdata(pdev);
 
@@ -928,7 +928,7 @@
 
 static struct platform_driver hal2_driver = {
 	.probe	= hal2_probe,
-	.remove	= __devexit_p(hal2_remove),
+	.remove	= hal2_remove,
 	.driver = {
 		.name	= "sgihal2",
 		.owner	= THIS_MODULE,
diff --git a/sound/mips/sgio2audio.c b/sound/mips/sgio2audio.c
index ceaa593..01a03ef 100644
--- a/sound/mips/sgio2audio.c
+++ b/sound/mips/sgio2audio.c
@@ -237,7 +237,7 @@
 }
 
 /* dac1/pcm0 mixer control */
-static struct snd_kcontrol_new sgio2audio_ctrl_pcm0 __devinitdata = {
+static struct snd_kcontrol_new sgio2audio_ctrl_pcm0 = {
 	.iface          = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name           = "PCM Playback Volume",
 	.index          = 0,
@@ -249,7 +249,7 @@
 };
 
 /* dac2/pcm1 mixer control */
-static struct snd_kcontrol_new sgio2audio_ctrl_pcm1 __devinitdata = {
+static struct snd_kcontrol_new sgio2audio_ctrl_pcm1 = {
 	.iface          = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name           = "PCM Playback Volume",
 	.index          = 1,
@@ -261,7 +261,7 @@
 };
 
 /* record level mixer control */
-static struct snd_kcontrol_new sgio2audio_ctrl_reclevel __devinitdata = {
+static struct snd_kcontrol_new sgio2audio_ctrl_reclevel = {
 	.iface          = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name           = "Capture Volume",
 	.access         = SNDRV_CTL_ELEM_ACCESS_READWRITE,
@@ -272,7 +272,7 @@
 };
 
 /* record level source control */
-static struct snd_kcontrol_new sgio2audio_ctrl_recsource __devinitdata = {
+static struct snd_kcontrol_new sgio2audio_ctrl_recsource = {
 	.iface          = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name           = "Capture Source",
 	.access         = SNDRV_CTL_ELEM_ACCESS_READWRITE,
@@ -282,7 +282,7 @@
 };
 
 /* line mixer control */
-static struct snd_kcontrol_new sgio2audio_ctrl_line __devinitdata = {
+static struct snd_kcontrol_new sgio2audio_ctrl_line = {
 	.iface          = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name           = "Line Playback Volume",
 	.index          = 0,
@@ -294,7 +294,7 @@
 };
 
 /* cd mixer control */
-static struct snd_kcontrol_new sgio2audio_ctrl_cd __devinitdata = {
+static struct snd_kcontrol_new sgio2audio_ctrl_cd = {
 	.iface          = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name           = "Line Playback Volume",
 	.index          = 1,
@@ -306,7 +306,7 @@
 };
 
 /* mic mixer control */
-static struct snd_kcontrol_new sgio2audio_ctrl_mic __devinitdata = {
+static struct snd_kcontrol_new sgio2audio_ctrl_mic = {
 	.iface          = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name           = "Mic Playback Volume",
 	.access         = SNDRV_CTL_ELEM_ACCESS_READWRITE,
@@ -317,7 +317,7 @@
 };
 
 
-static int __devinit snd_sgio2audio_new_mixer(struct snd_sgio2audio *chip)
+static int snd_sgio2audio_new_mixer(struct snd_sgio2audio *chip)
 {
 	int err;
 
@@ -726,7 +726,7 @@
  */
 
 /* create a pcm device */
-static int __devinit snd_sgio2audio_new_pcm(struct snd_sgio2audio *chip)
+static int snd_sgio2audio_new_pcm(struct snd_sgio2audio *chip)
 {
 	struct snd_pcm *pcm;
 	int err;
@@ -834,8 +834,8 @@
 	.dev_free = snd_sgio2audio_dev_free,
 };
 
-static int __devinit snd_sgio2audio_create(struct snd_card *card,
-					   struct snd_sgio2audio **rchip)
+static int snd_sgio2audio_create(struct snd_card *card,
+				 struct snd_sgio2audio **rchip)
 {
 	struct snd_sgio2audio *chip;
 	int i, err;
@@ -914,7 +914,7 @@
 	return 0;
 }
 
-static int __devinit snd_sgio2audio_probe(struct platform_device *pdev)
+static int snd_sgio2audio_probe(struct platform_device *pdev)
 {
 	struct snd_card *card;
 	struct snd_sgio2audio *chip;
@@ -958,7 +958,7 @@
 	return 0;
 }
 
-static int __devexit snd_sgio2audio_remove(struct platform_device *pdev)
+static int snd_sgio2audio_remove(struct platform_device *pdev)
 {
 	struct snd_card *card = platform_get_drvdata(pdev);
 
@@ -969,7 +969,7 @@
 
 static struct platform_driver sgio2audio_driver = {
 	.probe	= snd_sgio2audio_probe,
-	.remove	= __devexit_p(snd_sgio2audio_remove),
+	.remove	= snd_sgio2audio_remove,
 	.driver = {
 		.name	= "sgio2audio",
 		.owner	= THIS_MODULE,
diff --git a/sound/oss/ad1848.c b/sound/oss/ad1848.c
index 98d23bd..4918b71 100644
--- a/sound/oss/ad1848.c
+++ b/sound/oss/ad1848.c
@@ -2864,7 +2864,7 @@
 	{NULL}
 };
 
-static struct isapnp_device_id id_table[] __devinitdata = {
+static struct isapnp_device_id id_table[] = {
 	{	ISAPNP_VENDOR('C','M','I'), ISAPNP_DEVICE(0x0001),
 		ISAPNP_VENDOR('@','@','@'), ISAPNP_FUNCTION(0x0001), 0 },
         {       ISAPNP_ANY_ID, ISAPNP_ANY_ID,
diff --git a/sound/oss/kahlua.c b/sound/oss/kahlua.c
index 52d06a3..2a44cc1 100644
--- a/sound/oss/kahlua.c
+++ b/sound/oss/kahlua.c
@@ -43,7 +43,7 @@
  *	not real hardware.
  */
 
-static u8 __devinit mixer_read(unsigned long io, u8 reg)
+static u8 mixer_read(unsigned long io, u8 reg)
 {
 	outb(reg, io + 4);
 	udelay(20);
@@ -52,7 +52,7 @@
 	return reg;
 }
 
-static int __devinit probe_one(struct pci_dev *pdev, const struct pci_device_id *ent)
+static int probe_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
 	struct address_info *hw_config;
 	unsigned long base;
@@ -183,7 +183,7 @@
 	return 1;
 }
 
-static void __devexit remove_one(struct pci_dev *pdev)
+static void remove_one(struct pci_dev *pdev)
 {
 	struct address_info *hw_config = pci_get_drvdata(pdev);
 	sb_dsp_unload(hw_config, 0);
@@ -210,7 +210,7 @@
 	.name		= "kahlua",
 	.id_table	= id_tbl,
 	.probe		= probe_one,
-	.remove		= __devexit_p(remove_one),
+	.remove		= remove_one,
 };
 
 
@@ -220,7 +220,7 @@
 	return pci_register_driver(&kahlua_driver);
 }
 
-static void __devexit kahlua_cleanup_module(void)
+static void kahlua_cleanup_module(void)
 {
 	pci_unregister_driver(&kahlua_driver);
 }
diff --git a/sound/oss/sb_audio.c b/sound/oss/sb_audio.c
index b2b3c01..048439a 100644
--- a/sound/oss/sb_audio.c
+++ b/sound/oss/sb_audio.c
@@ -442,7 +442,7 @@
 {
 	sb_devc *devc = audio_devs[dev]->devc;
 	int tmp;
-	int s = speed * devc->channels;
+	int s;
 
 	if (speed > 0)
 	{
@@ -452,6 +452,7 @@
 			speed = 44100;
 		if (devc->opened & OPEN_READ && speed > 15000)
 			speed = 15000;
+		s = speed * devc->channels;
 		devc->tconst = (256 - ((1000000 + s / 2) / s)) & 0xff;
 		tmp = 256 - devc->tconst;
 		speed = ((1000000 + tmp / 2) / tmp) / devc->channels;
diff --git a/sound/parisc/harmony.c b/sound/parisc/harmony.c
index f47f9e2..0e66ba4 100644
--- a/sound/parisc/harmony.c
+++ b/sound/parisc/harmony.c
@@ -856,7 +856,7 @@
 		       HARMONY_GAIN_HE_SHIFT, 1, 0),
 };
 
-static void __devinit
+static void
 snd_harmony_mixer_reset(struct snd_harmony *h)
 {
 	harmony_mute(h);
@@ -865,7 +865,7 @@
 	harmony_unmute(h);
 }
 
-static int __devinit
+static int
 snd_harmony_mixer_init(struct snd_harmony *h)
 {
 	struct snd_card *card;
@@ -915,7 +915,7 @@
 	return snd_harmony_free(h);
 }
 
-static int __devinit
+static int
 snd_harmony_create(struct snd_card *card, 
 		   struct parisc_device *padev, 
 		   struct snd_harmony **rchip)
@@ -972,7 +972,7 @@
 	return err;
 }
 
-static int __devinit
+static int
 snd_harmony_probe(struct parisc_device *padev)
 {
 	int err;
@@ -1012,7 +1012,7 @@
 	return err;
 }
 
-static int __devexit
+static int
 snd_harmony_remove(struct parisc_device *padev)
 {
 	snd_card_free(parisc_get_drvdata(padev));
@@ -1024,7 +1024,7 @@
 	.name = "harmony",
 	.id_table = snd_harmony_devtable,
 	.probe = snd_harmony_probe,
-	.remove = __devexit_p(snd_harmony_remove),
+	.remove = snd_harmony_remove,
 };
 
 static int __init 
diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig
index f99fa25..947cfb4 100644
--- a/sound/pci/Kconfig
+++ b/sound/pci/Kconfig
@@ -572,6 +572,7 @@
 
 config SND_HDSP
 	tristate "RME Hammerfall DSP Audio"
+	select FW_LOADER
 	select SND_HWDEP
 	select SND_RAWMIDI
 	select SND_PCM
@@ -630,7 +631,7 @@
 	  AudioTrak Prodigy 192, 7.1 (HIFI/LT/XT), HD2; Hercules
 	  Fortissimo IV; ESI Juli@; Pontis MS300; EGO-SYS WaveTerminal
 	  192M; Albatron K8X800 Pro II; Chaintech ZNF3-150/250, 9CJS,
-	  AV-710; Shuttle SN25P.
+	  AV-710; Shuttle SN25P; Philips PSC724 Ultimate Edge.
 
 	  To compile this driver as a module, choose M here: the module
 	  will be called snd-ice1724.
@@ -707,6 +708,7 @@
 
 config SND_MIXART
 	tristate "Digigram miXart"
+	select FW_LOADER
 	select SND_HWDEP
 	select SND_PCM
 	help
@@ -727,6 +729,7 @@
 
 config SND_PCXHR
 	tristate "Digigram PCXHR"
+	select FW_LOADER
 	select SND_PCM
 	select SND_HWDEP
 	help
diff --git a/sound/pci/ad1889.c b/sound/pci/ad1889.c
index e672ff4..ad8a311 100644
--- a/sound/pci/ad1889.c
+++ b/sound/pci/ad1889.c
@@ -624,7 +624,7 @@
 	return IRQ_HANDLED;
 }
 
-static int __devinit
+static int
 snd_ad1889_pcm_init(struct snd_ad1889 *chip, int device, struct snd_pcm **rpcm)
 {
 	int err;
@@ -747,7 +747,7 @@
 	snd_iprintf(buffer, "Resampler samplerate: %u Hz\n", reg);
 }
 
-static void __devinit
+static void
 snd_ad1889_proc_init(struct snd_ad1889 *chip)
 {
 	struct snd_info_entry *entry;
@@ -767,7 +767,7 @@
 	{ } /* terminator */
 };
 
-static void __devinit
+static void
 snd_ad1889_ac97_xinit(struct snd_ad1889 *chip)
 {
 	u16 reg;
@@ -805,7 +805,7 @@
 	chip->ac97 = NULL;
 }
 
-static int __devinit
+static int
 snd_ad1889_ac97_init(struct snd_ad1889 *chip, const char *quirk_override)
 {
 	int err;
@@ -878,7 +878,7 @@
 	return snd_ad1889_free(chip);
 }
 
-static int __devinit
+static int
 snd_ad1889_init(struct snd_ad1889 *chip) 
 {
 	ad1889_writew(chip, AD_DS_CCS, AD_DS_CCS_CLKEN); /* turn on clock */
@@ -892,7 +892,7 @@
 	return 0;
 }
 
-static int __devinit
+static int
 snd_ad1889_create(struct snd_card *card,
 		  struct pci_dev *pci,
 		  struct snd_ad1889 **rchip)
@@ -978,7 +978,7 @@
 	return err;
 }
 
-static int __devinit
+static int
 snd_ad1889_probe(struct pci_dev *pci,
 		 const struct pci_device_id *pci_id)
 {
@@ -1042,7 +1042,7 @@
 	return err;
 }
 
-static void __devexit
+static void
 snd_ad1889_remove(struct pci_dev *pci)
 {
 	snd_card_free(pci_get_drvdata(pci));
@@ -1059,7 +1059,7 @@
 	.name = KBUILD_MODNAME,
 	.id_table = snd_ad1889_ids,
 	.probe = snd_ad1889_probe,
-	.remove = __devexit_p(snd_ad1889_remove),
+	.remove = snd_ad1889_remove,
 };
 
 module_pci_driver(ad1889_pci_driver);
diff --git a/sound/pci/ak4531_codec.c b/sound/pci/ak4531_codec.c
index cadf7b9..3bf0dc5 100644
--- a/sound/pci/ak4531_codec.c
+++ b/sound/pci/ak4531_codec.c
@@ -274,7 +274,7 @@
 static const DECLARE_TLV_DB_SCALE(db_scale_mono, -2800, 400, 0);
 static const DECLARE_TLV_DB_SCALE(db_scale_input, -5000, 200, 0);
 
-static struct snd_kcontrol_new snd_ak4531_controls[] __devinitdata = {
+static struct snd_kcontrol_new snd_ak4531_controls[] = {
 
 AK4531_DOUBLE_TLV("Master Playback Switch", 0,
 		  AK4531_LMASTER, AK4531_RMASTER, 7, 7, 1, 1,
@@ -383,9 +383,9 @@
 	0x01		/* 19: Mic Amp Setup */
 };
 
-int __devinit snd_ak4531_mixer(struct snd_card *card,
-			       struct snd_ak4531 *_ak4531,
-			       struct snd_ak4531 **rak4531)
+int snd_ak4531_mixer(struct snd_card *card,
+		     struct snd_ak4531 *_ak4531,
+		     struct snd_ak4531 **rak4531)
 {
 	unsigned int idx;
 	int err;
@@ -483,7 +483,7 @@
 		    ak4531->regs[AK4531_MIC_GAIN] & 1 ? "+30dB" : "+0dB");
 }
 
-static void __devinit
+static void
 snd_ak4531_proc_init(struct snd_card *card, struct snd_ak4531 *ak4531)
 {
 	struct snd_info_entry *entry;
diff --git a/sound/pci/ali5451/ali5451.c b/sound/pci/ali5451/ali5451.c
index c7e3c53..136a393 100644
--- a/sound/pci/ali5451/ali5451.c
+++ b/sound/pci/ali5451/ali5451.c
@@ -1678,8 +1678,8 @@
 }
 
 
-static int __devinit snd_ali_pcm(struct snd_ali * codec, int device,
-				 struct ali_pcm_description *desc)
+static int snd_ali_pcm(struct snd_ali *codec, int device,
+		       struct ali_pcm_description *desc)
 {
 	struct snd_pcm *pcm;
 	int err;
@@ -1727,7 +1727,7 @@
 	}
 };
 
-static int __devinit snd_ali_build_pcms(struct snd_ali *codec)
+static int snd_ali_build_pcms(struct snd_ali *codec)
 {
 	int i, err;
 	for (i = 0; i < codec->num_of_codecs && i < ARRAY_SIZE(ali_pcms); i++) {
@@ -1832,7 +1832,7 @@
 	return change;
 }
 
-static struct snd_kcontrol_new snd_ali5451_mixer_spdif[] __devinitdata = {
+static struct snd_kcontrol_new snd_ali5451_mixer_spdif[] = {
 	/* spdif aplayback switch */
 	/* FIXME: "IEC958 Playback Switch" may conflict with one on ac97_codec */
 	ALI5451_SPDIF(SNDRV_CTL_NAME_IEC958("Output ",NONE,SWITCH), 0, 0),
@@ -1842,7 +1842,7 @@
 	ALI5451_SPDIF(SNDRV_CTL_NAME_IEC958("",CAPTURE,SWITCH), 0, 2)
 };
 
-static int __devinit snd_ali_mixer(struct snd_ali * codec)
+static int snd_ali_mixer(struct snd_ali *codec)
 {
 	struct snd_ac97_template ac97;
 	unsigned int idx;
@@ -2079,14 +2079,14 @@
 		snd_iprintf(buf, "%02x: %08x\n", i, inl(ALI_REG(codec, i)));
 }
 
-static void __devinit snd_ali_proc_init(struct snd_ali *codec)
+static void snd_ali_proc_init(struct snd_ali *codec)
 {
 	struct snd_info_entry *entry;
 	if (!snd_card_proc_new(codec->card, "ali5451", &entry))
 		snd_info_set_text_ops(entry, codec, snd_ali_proc_read);
 }
 
-static int __devinit snd_ali_resources(struct snd_ali *codec)
+static int snd_ali_resources(struct snd_ali *codec)
 {
 	int err;
 
@@ -2112,11 +2112,11 @@
 	return 0;
 }
 
-static int __devinit snd_ali_create(struct snd_card *card,
-				    struct pci_dev *pci,
-				    int pcm_streams,
-				    int spdif_support,
-				    struct snd_ali ** r_ali)
+static int snd_ali_create(struct snd_card *card,
+			  struct pci_dev *pci,
+			  int pcm_streams,
+			  int spdif_support,
+			  struct snd_ali **r_ali)
 {
 	struct snd_ali *codec;
 	int i, err;
@@ -2246,8 +2246,8 @@
 	return 0;
 }
 
-static int __devinit snd_ali_probe(struct pci_dev *pci,
-				   const struct pci_device_id *pci_id)
+static int snd_ali_probe(struct pci_dev *pci,
+			 const struct pci_device_id *pci_id)
 {
 	struct snd_card *card;
 	struct snd_ali *codec;
@@ -2295,7 +2295,7 @@
 	return err;
 }
 
-static void __devexit snd_ali_remove(struct pci_dev *pci)
+static void snd_ali_remove(struct pci_dev *pci)
 {
 	snd_card_free(pci_get_drvdata(pci));
 	pci_set_drvdata(pci, NULL);
@@ -2305,7 +2305,7 @@
 	.name = KBUILD_MODNAME,
 	.id_table = snd_ali_ids,
 	.probe = snd_ali_probe,
-	.remove = __devexit_p(snd_ali_remove),
+	.remove = snd_ali_remove,
 	.driver = {
 		.pm = ALI_PM_OPS,
 	},
diff --git a/sound/pci/als300.c b/sound/pci/als300.c
index 5af3cb6..864c431 100644
--- a/sound/pci/als300.c
+++ b/sound/pci/als300.c
@@ -278,7 +278,7 @@
 	return IRQ_HANDLED;
 }
 
-static void __devexit snd_als300_remove(struct pci_dev *pci)
+static void snd_als300_remove(struct pci_dev *pci)
 {
 	snd_als300_dbgcallenter();
 	snd_card_free(pci_get_drvdata(pci));
@@ -622,7 +622,7 @@
 	.pointer =	snd_als300_pointer,
 };
 
-static int __devinit snd_als300_new_pcm(struct snd_als300 *chip)
+static int snd_als300_new_pcm(struct snd_als300 *chip)
 {
 	struct snd_pcm *pcm;
 	int err;
@@ -683,9 +683,9 @@
 	snd_als300_dbgcallleave();
 }
 
-static int __devinit snd_als300_create(struct snd_card *card,
-				       struct pci_dev *pci, int chip_type,
-				       struct snd_als300 **rchip)
+static int snd_als300_create(struct snd_card *card,
+			     struct pci_dev *pci, int chip_type,
+			     struct snd_als300 **rchip)
 {
 	struct snd_als300 *chip;
 	void *irq_handler;
@@ -815,7 +815,7 @@
 #define SND_ALS300_PM_OPS	NULL
 #endif
 
-static int __devinit snd_als300_probe(struct pci_dev *pci,
+static int snd_als300_probe(struct pci_dev *pci,
                              const struct pci_device_id *pci_id)
 {
 	static int dev;
@@ -867,7 +867,7 @@
 	.name = KBUILD_MODNAME,
 	.id_table = snd_als300_ids,
 	.probe = snd_als300_probe,
-	.remove = __devexit_p(snd_als300_remove),
+	.remove = snd_als300_remove,
 	.driver = {
 		.pm = SND_ALS300_PM_OPS,
 	},
diff --git a/sound/pci/als4000.c b/sound/pci/als4000.c
index feb2a14..61efda2 100644
--- a/sound/pci/als4000.c
+++ b/sound/pci/als4000.c
@@ -694,7 +694,7 @@
 	.pointer =	snd_als4000_capture_pointer
 };
 
-static int __devinit snd_als4000_pcm(struct snd_sb *chip, int device)
+static int snd_als4000_pcm(struct snd_sb *chip, int device)
 {
 	struct snd_pcm *pcm;
 	int err;
@@ -770,7 +770,7 @@
 }
 
 #ifdef SUPPORT_JOYSTICK
-static int __devinit snd_als4000_create_gameport(struct snd_card_als4000 *acard, int dev)
+static int snd_als4000_create_gameport(struct snd_card_als4000 *acard, int dev)
 {
 	struct gameport *gp;
 	struct resource *r;
@@ -847,8 +847,8 @@
 	pci_disable_device(acard->pci);
 }
 
-static int __devinit snd_card_als4000_probe(struct pci_dev *pci,
-					  const struct pci_device_id *pci_id)
+static int snd_card_als4000_probe(struct pci_dev *pci,
+				  const struct pci_device_id *pci_id)
 {
 	static int dev;
 	struct snd_card *card;
@@ -981,7 +981,7 @@
 	return err;
 }
 
-static void __devexit snd_card_als4000_remove(struct pci_dev *pci)
+static void snd_card_als4000_remove(struct pci_dev *pci)
 {
 	snd_card_free(pci_get_drvdata(pci));
 	pci_set_drvdata(pci, NULL);
@@ -1046,7 +1046,7 @@
 	.name = KBUILD_MODNAME,
 	.id_table = snd_als4000_ids,
 	.probe = snd_card_als4000_probe,
-	.remove = __devexit_p(snd_card_als4000_remove),
+	.remove = snd_card_als4000_remove,
 	.driver = {
 		.pm = SND_ALS4000_PM_OPS,
 	},
diff --git a/sound/pci/asihpi/asihpi.c b/sound/pci/asihpi/asihpi.c
index eedc017..3536b07 100644
--- a/sound/pci/asihpi/asihpi.c
+++ b/sound/pci/asihpi/asihpi.c
@@ -1235,8 +1235,7 @@
 	.pointer = snd_card_asihpi_capture_pointer,
 };
 
-static int __devinit snd_card_asihpi_pcm_new(
-		struct snd_card_asihpi *asihpi, int device)
+static int snd_card_asihpi_pcm_new(struct snd_card_asihpi *asihpi, int device)
 {
 	struct snd_pcm *pcm;
 	int err;
@@ -1497,8 +1496,8 @@
 	return change;
 }
 
-static int __devinit snd_asihpi_volume_add(struct snd_card_asihpi *asihpi,
-					struct hpi_control *hpi_ctl)
+static int snd_asihpi_volume_add(struct snd_card_asihpi *asihpi,
+				 struct hpi_control *hpi_ctl)
 {
 	struct snd_card *card = asihpi->card;
 	struct snd_kcontrol_new snd_control;
@@ -1593,8 +1592,8 @@
 
 static const DECLARE_TLV_DB_SCALE(db_scale_level, -1000, 100, 0);
 
-static int __devinit snd_asihpi_level_add(struct snd_card_asihpi *asihpi,
-					struct hpi_control *hpi_ctl)
+static int snd_asihpi_level_add(struct snd_card_asihpi *asihpi,
+				struct hpi_control *hpi_ctl)
 {
 	struct snd_card *card = asihpi->card;
 	struct snd_kcontrol_new snd_control;
@@ -1715,8 +1714,8 @@
 	return 0;
 }
 
-static int __devinit snd_asihpi_aesebu_rx_add(struct snd_card_asihpi *asihpi,
-					struct hpi_control *hpi_ctl)
+static int snd_asihpi_aesebu_rx_add(struct snd_card_asihpi *asihpi,
+				    struct hpi_control *hpi_ctl)
 {
 	struct snd_card *card = asihpi->card;
 	struct snd_kcontrol_new snd_control;
@@ -1753,8 +1752,8 @@
 }
 
 
-static int __devinit snd_asihpi_aesebu_tx_add(struct snd_card_asihpi *asihpi,
-					struct hpi_control *hpi_ctl)
+static int snd_asihpi_aesebu_tx_add(struct snd_card_asihpi *asihpi,
+				    struct hpi_control *hpi_ctl)
 {
 	struct snd_card *card = asihpi->card;
 	struct snd_kcontrol_new snd_control;
@@ -1996,8 +1995,8 @@
 }
 
 /* Tuner control group initializer  */
-static int __devinit snd_asihpi_tuner_add(struct snd_card_asihpi *asihpi,
-					struct hpi_control *hpi_ctl)
+static int snd_asihpi_tuner_add(struct snd_card_asihpi *asihpi,
+				struct hpi_control *hpi_ctl)
 {
 	struct snd_card *card = asihpi->card;
 	struct snd_kcontrol_new snd_control;
@@ -2100,8 +2099,8 @@
 	return 0;
 }
 
-static int __devinit snd_asihpi_meter_add(struct snd_card_asihpi *asihpi,
-					struct hpi_control *hpi_ctl, int subidx)
+static int snd_asihpi_meter_add(struct snd_card_asihpi *asihpi,
+				struct hpi_control *hpi_ctl, int subidx)
 {
 	struct snd_card *card = asihpi->card;
 	struct snd_kcontrol_new snd_control;
@@ -2214,8 +2213,8 @@
 }
 
 
-static int  __devinit snd_asihpi_mux_add(struct snd_card_asihpi *asihpi,
-					struct hpi_control *hpi_ctl)
+static int  snd_asihpi_mux_add(struct snd_card_asihpi *asihpi,
+			       struct hpi_control *hpi_ctl)
 {
 	struct snd_card *card = asihpi->card;
 	struct snd_kcontrol_new snd_control;
@@ -2303,8 +2302,8 @@
 }
 
 
-static int __devinit snd_asihpi_cmode_add(struct snd_card_asihpi *asihpi,
-					struct hpi_control *hpi_ctl)
+static int snd_asihpi_cmode_add(struct snd_card_asihpi *asihpi,
+				struct hpi_control *hpi_ctl)
 {
 	struct snd_card *card = asihpi->card;
 	struct snd_kcontrol_new snd_control;
@@ -2471,8 +2470,8 @@
 	return 0;
 }
 
-static int __devinit snd_asihpi_sampleclock_add(struct snd_card_asihpi *asihpi,
-					struct hpi_control *hpi_ctl)
+static int snd_asihpi_sampleclock_add(struct snd_card_asihpi *asihpi,
+				      struct hpi_control *hpi_ctl)
 {
 	struct snd_card *card = asihpi->card;
 	struct snd_kcontrol_new snd_control;
@@ -2548,7 +2547,7 @@
    Mixer
  ------------------------------------------------------------*/
 
-static int __devinit snd_card_asihpi_mixer_new(struct snd_card_asihpi *asihpi)
+static int snd_card_asihpi_mixer_new(struct snd_card_asihpi *asihpi)
 {
 	struct snd_card *card = asihpi->card;
 	unsigned int idx = 0;
@@ -2722,7 +2721,7 @@
 	}
 }
 
-static void __devinit snd_asihpi_proc_init(struct snd_card_asihpi *asihpi)
+static void snd_asihpi_proc_init(struct snd_card_asihpi *asihpi)
 {
 	struct snd_info_entry *entry;
 
@@ -2764,8 +2763,8 @@
 /* results in /dev/snd/hwC#D0 file for each card with index #
    also /proc/asound/hwdep will contain '#-00: asihpi (HPI) for each card'
 */
-static int __devinit snd_asihpi_hpi_new(struct snd_card_asihpi *asihpi,
-	int device, struct snd_hwdep **rhwdep)
+static int snd_asihpi_hpi_new(struct snd_card_asihpi *asihpi,
+			      int device, struct snd_hwdep **rhwdep)
 {
 	struct snd_hwdep *hw;
 	int err;
@@ -2789,8 +2788,8 @@
 /*------------------------------------------------------------
    CARD
  ------------------------------------------------------------*/
-static int __devinit snd_asihpi_probe(struct pci_dev *pci_dev,
-				       const struct pci_device_id *pci_id)
+static int snd_asihpi_probe(struct pci_dev *pci_dev,
+			    const struct pci_device_id *pci_id)
 {
 	int err;
 	struct hpi_adapter *hpi;
@@ -2944,7 +2943,7 @@
 
 }
 
-static void __devexit snd_asihpi_remove(struct pci_dev *pci_dev)
+static void snd_asihpi_remove(struct pci_dev *pci_dev)
 {
 	struct hpi_adapter *hpi = pci_get_drvdata(pci_dev);
 	snd_card_free(hpi->snd_card);
@@ -2967,7 +2966,7 @@
 	.name = KBUILD_MODNAME,
 	.id_table = asihpi_pci_tbl,
 	.probe = snd_asihpi_probe,
-	.remove = __devexit_p(snd_asihpi_remove),
+	.remove = snd_asihpi_remove,
 #ifdef CONFIG_PM_SLEEP
 /*	.suspend = snd_asihpi_suspend,
 	.resume = snd_asihpi_resume, */
diff --git a/sound/pci/asihpi/hpidspcd.c b/sound/pci/asihpi/hpidspcd.c
index 456a758..ac91637 100644
--- a/sound/pci/asihpi/hpidspcd.c
+++ b/sound/pci/asihpi/hpidspcd.c
@@ -49,14 +49,12 @@
 	err = request_firmware(&firmware, fw_name, &dev->dev);
 
 	if (err || !firmware) {
-		dev_printk(KERN_ERR, &dev->dev,
-			"%d, request_firmware failed for  %s\n", err,
-			fw_name);
+		dev_err(&dev->dev, "%d, request_firmware failed for %s\n",
+			err, fw_name);
 		goto error1;
 	}
 	if (firmware->size < sizeof(header)) {
-		dev_printk(KERN_ERR, &dev->dev, "Header size too small %s\n",
-			fw_name);
+		dev_err(&dev->dev, "Header size too small %s\n", fw_name);
 		goto error2;
 	}
 	memcpy(&header, firmware->data, sizeof(header));
@@ -64,7 +62,7 @@
 	if ((header.type != 0x45444F43) ||	/* "CODE" */
 		(header.adapter != adapter)
 		|| (header.size != firmware->size)) {
-		dev_printk(KERN_ERR, &dev->dev,
+		dev_err(&dev->dev,
 			"Invalid firmware header size %d != file %zd\n",
 			header.size, firmware->size);
 		goto error2;
@@ -72,17 +70,15 @@
 
 	if ((header.version >> 9) != (HPI_VER >> 9)) {
 		/* Consider even and subsequent odd minor versions to be compatible */
-		dev_printk(KERN_ERR, &dev->dev,
-			"Incompatible firmware version "
-			"DSP image %X != Driver %X\n", header.version,
-			HPI_VER);
+		dev_err(&dev->dev, "Incompatible firmware version DSP image %X != Driver %X\n",
+			header.version, HPI_VER);
 		goto error2;
 	}
 
 	if (header.version != HPI_VER) {
-		dev_printk(KERN_INFO, &dev->dev,
-			"Firmware: release version mismatch  DSP image %X != Driver %X\n",
-			header.version, HPI_VER);
+		dev_info(&dev->dev,
+			 "Firmware: release version mismatch  DSP image %X != Driver %X\n",
+			 header.version, HPI_VER);
 	}
 
 	HPI_DEBUG_LOG(DEBUG, "dsp code %s opened\n", fw_name);
diff --git a/sound/pci/asihpi/hpioctl.c b/sound/pci/asihpi/hpioctl.c
index 6091562..ef5019f 100644
--- a/sound/pci/asihpi/hpioctl.c
+++ b/sound/pci/asihpi/hpioctl.c
@@ -307,8 +307,8 @@
 	return err;
 }
 
-int __devinit asihpi_adapter_probe(struct pci_dev *pci_dev,
-	const struct pci_device_id *pci_id)
+int asihpi_adapter_probe(struct pci_dev *pci_dev,
+			 const struct pci_device_id *pci_id)
 {
 	int idx, nm;
 	int adapter_index;
@@ -326,7 +326,7 @@
 		pci_dev->subsystem_device, pci_dev->devfn);
 
 	if (pci_enable_device(pci_dev) < 0) {
-		dev_printk(KERN_ERR, &pci_dev->dev,
+		dev_err(&pci_dev->dev,
 			"pci_enable_device failed, disabling device\n");
 		return -EIO;
 	}
@@ -398,9 +398,8 @@
 	mutex_init(&adapters[adapter_index].mutex);
 	pci_set_drvdata(pci_dev, &adapters[adapter_index]);
 
-	dev_printk(KERN_INFO, &pci_dev->dev,
-		"probe succeeded for ASI%04X HPI index %d\n",
-		adapter.adapter->type, adapter_index);
+	dev_info(&pci_dev->dev, "probe succeeded for ASI%04X HPI index %d\n",
+		 adapter.adapter->type, adapter_index);
 
 	return 0;
 
@@ -421,7 +420,7 @@
 	return -ENODEV;
 }
 
-void __devexit asihpi_adapter_remove(struct pci_dev *pci_dev)
+void asihpi_adapter_remove(struct pci_dev *pci_dev)
 {
 	int idx;
 	struct hpi_message hm;
@@ -448,11 +447,11 @@
 
 	pci_set_drvdata(pci_dev, NULL);
 	if (1)
-		dev_printk(KERN_INFO, &pci_dev->dev,
-			"remove %04x:%04x,%04x:%04x,%04x," " HPI index %d.\n",
-			pci_dev->vendor, pci_dev->device,
-			pci_dev->subsystem_vendor, pci_dev->subsystem_device,
-			pci_dev->devfn, pa->adapter->index);
+		dev_info(&pci_dev->dev,
+			 "remove %04x:%04x,%04x:%04x,%04x, HPI index %d\n",
+			 pci_dev->vendor, pci_dev->device,
+			 pci_dev->subsystem_vendor, pci_dev->subsystem_device,
+			 pci_dev->devfn, pa->adapter->index);
 
 	memset(pa, 0, sizeof(*pa));
 }
diff --git a/sound/pci/asihpi/hpioctl.h b/sound/pci/asihpi/hpioctl.h
index 2614aff..0d767e1 100644
--- a/sound/pci/asihpi/hpioctl.h
+++ b/sound/pci/asihpi/hpioctl.h
@@ -19,9 +19,9 @@
 Linux HPI ioctl, and shared module init functions
 *******************************************************************************/
 
-int __devinit asihpi_adapter_probe(struct pci_dev *pci_dev,
-	const struct pci_device_id *pci_id);
-void __devexit asihpi_adapter_remove(struct pci_dev *pci_dev);
+int asihpi_adapter_probe(struct pci_dev *pci_dev,
+			 const struct pci_device_id *pci_id);
+void asihpi_adapter_remove(struct pci_dev *pci_dev);
 void __init asihpi_init(void);
 void __exit asihpi_exit(void);
 
diff --git a/sound/pci/atiixp.c b/sound/pci/atiixp.c
index 368df8b..a677431 100644
--- a/sound/pci/atiixp.c
+++ b/sound/pci/atiixp.c
@@ -296,7 +296,7 @@
 
 MODULE_DEVICE_TABLE(pci, snd_atiixp_ids);
 
-static struct snd_pci_quirk atiixp_quirks[] __devinitdata = {
+static struct snd_pci_quirk atiixp_quirks[] = {
 	SND_PCI_QUIRK(0x105b, 0x0c81, "Foxconn RC4107MA-RS2", 0),
 	SND_PCI_QUIRK(0x15bd, 0x3100, "DFI RS482", 0),
 	{ } /* terminator */
@@ -561,7 +561,7 @@
 	     ATI_REG_ISR_CODEC2_NOT_READY)
 #define CODEC_CHECK_BITS (ALL_CODEC_NOT_READY|ATI_REG_ISR_NEW_FRAME)
 
-static int __devinit ac97_probing_bugs(struct pci_dev *pci)
+static int ac97_probing_bugs(struct pci_dev *pci)
 {
 	const struct snd_pci_quirk *q;
 
@@ -575,7 +575,7 @@
 	return -1;
 }
 
-static int __devinit snd_atiixp_codec_detect(struct atiixp *chip)
+static int snd_atiixp_codec_detect(struct atiixp *chip)
 {
 	int timeout;
 
@@ -1183,7 +1183,7 @@
 	.pointer =	snd_atiixp_pcm_pointer,
 };
 
-static struct ac97_pcm atiixp_pcm_defs[] __devinitdata = {
+static struct ac97_pcm atiixp_pcm_defs[] = {
 	/* front PCM */
 	{
 		.exclusive = 1,
@@ -1247,7 +1247,7 @@
 };
 	
 
-static int __devinit snd_atiixp_pcm_new(struct atiixp *chip)
+static int snd_atiixp_pcm_new(struct atiixp *chip)
 {
 	struct snd_pcm *pcm;
 	struct snd_pcm_chmap *chmap;
@@ -1390,7 +1390,7 @@
  * ac97 mixer section
  */
 
-static struct ac97_quirk ac97_quirks[] __devinitdata = {
+static struct ac97_quirk ac97_quirks[] = {
 	{
 		.subvendor = 0x103c,
 		.subdevice = 0x006b,
@@ -1412,8 +1412,8 @@
 	{ } /* terminator */
 };
 
-static int __devinit snd_atiixp_mixer_new(struct atiixp *chip, int clock,
-					  const char *quirk_override)
+static int snd_atiixp_mixer_new(struct atiixp *chip, int clock,
+				const char *quirk_override)
 {
 	struct snd_ac97_bus *pbus;
 	struct snd_ac97_template ac97;
@@ -1560,7 +1560,7 @@
 		snd_iprintf(buffer, "%02x: %08x\n", i, readl(chip->remap_addr + i));
 }
 
-static void __devinit snd_atiixp_proc_init(struct atiixp *chip)
+static void snd_atiixp_proc_init(struct atiixp *chip)
 {
 	struct snd_info_entry *entry;
 
@@ -1602,9 +1602,9 @@
 /*
  * constructor for chip instance
  */
-static int __devinit snd_atiixp_create(struct snd_card *card,
-				      struct pci_dev *pci,
-				      struct atiixp **r_chip)
+static int snd_atiixp_create(struct snd_card *card,
+			     struct pci_dev *pci,
+			     struct atiixp **r_chip)
 {
 	static struct snd_device_ops ops = {
 		.dev_free =	snd_atiixp_dev_free,
@@ -1661,8 +1661,8 @@
 }
 
 
-static int __devinit snd_atiixp_probe(struct pci_dev *pci,
-				     const struct pci_device_id *pci_id)
+static int snd_atiixp_probe(struct pci_dev *pci,
+			    const struct pci_device_id *pci_id)
 {
 	struct snd_card *card;
 	struct atiixp *chip;
@@ -1710,7 +1710,7 @@
 	return err;
 }
 
-static void __devexit snd_atiixp_remove(struct pci_dev *pci)
+static void snd_atiixp_remove(struct pci_dev *pci)
 {
 	snd_card_free(pci_get_drvdata(pci));
 	pci_set_drvdata(pci, NULL);
@@ -1720,7 +1720,7 @@
 	.name = KBUILD_MODNAME,
 	.id_table = snd_atiixp_ids,
 	.probe = snd_atiixp_probe,
-	.remove = __devexit_p(snd_atiixp_remove),
+	.remove = snd_atiixp_remove,
 	.driver = {
 		.pm = SND_ATIIXP_PM_OPS,
 	},
diff --git a/sound/pci/atiixp_modem.c b/sound/pci/atiixp_modem.c
index 6fc03d9..d0bec7b 100644
--- a/sound/pci/atiixp_modem.c
+++ b/sound/pci/atiixp_modem.c
@@ -988,7 +988,7 @@
 	.flush_dma = atiixp_in_flush_dma,
 };
 
-static int __devinit snd_atiixp_pcm_new(struct atiixp_modem *chip)
+static int snd_atiixp_pcm_new(struct atiixp_modem *chip)
 {
 	struct snd_pcm *pcm;
 	int err;
@@ -1061,7 +1061,7 @@
  * ac97 mixer section
  */
 
-static int __devinit snd_atiixp_mixer_new(struct atiixp_modem *chip, int clock)
+static int snd_atiixp_mixer_new(struct atiixp_modem *chip, int clock)
 {
 	struct snd_ac97_bus *pbus;
 	struct snd_ac97_template ac97;
@@ -1186,7 +1186,7 @@
 		snd_iprintf(buffer, "%02x: %08x\n", i, readl(chip->remap_addr + i));
 }
 
-static void __devinit snd_atiixp_proc_init(struct atiixp_modem *chip)
+static void snd_atiixp_proc_init(struct atiixp_modem *chip)
 {
 	struct snd_info_entry *entry;
 
@@ -1228,9 +1228,9 @@
 /*
  * constructor for chip instance
  */
-static int __devinit snd_atiixp_create(struct snd_card *card,
-				       struct pci_dev *pci,
-				       struct atiixp_modem **r_chip)
+static int snd_atiixp_create(struct snd_card *card,
+			     struct pci_dev *pci,
+			     struct atiixp_modem **r_chip)
 {
 	static struct snd_device_ops ops = {
 		.dev_free =	snd_atiixp_dev_free,
@@ -1287,8 +1287,8 @@
 }
 
 
-static int __devinit snd_atiixp_probe(struct pci_dev *pci,
-				      const struct pci_device_id *pci_id)
+static int snd_atiixp_probe(struct pci_dev *pci,
+			    const struct pci_device_id *pci_id)
 {
 	struct snd_card *card;
 	struct atiixp_modem *chip;
@@ -1331,7 +1331,7 @@
 	return err;
 }
 
-static void __devexit snd_atiixp_remove(struct pci_dev *pci)
+static void snd_atiixp_remove(struct pci_dev *pci)
 {
 	snd_card_free(pci_get_drvdata(pci));
 	pci_set_drvdata(pci, NULL);
@@ -1341,7 +1341,7 @@
 	.name = KBUILD_MODNAME,
 	.id_table = snd_atiixp_ids,
 	.probe = snd_atiixp_probe,
-	.remove = __devexit_p(snd_atiixp_remove),
+	.remove = snd_atiixp_remove,
 	.driver = {
 		.pm = SND_ATIIXP_PM_OPS,
 	},
diff --git a/sound/pci/au88x0/au88x0.c b/sound/pci/au88x0/au88x0.c
index ffc376f..b157e1f 100644
--- a/sound/pci/au88x0/au88x0.c
+++ b/sound/pci/au88x0/au88x0.c
@@ -78,7 +78,7 @@
 	}
 }
 
-static void __devinit snd_vortex_workaround(struct pci_dev *vortex, int fix)
+static void snd_vortex_workaround(struct pci_dev *vortex, int fix)
 {
 	struct pci_dev *via = NULL;
 
@@ -137,7 +137,7 @@
 
 // chip-specific constructor
 // (see "Management of Cards and Components")
-static int __devinit
+static int
 snd_vortex_create(struct snd_card *card, struct pci_dev *pci, vortex_t ** rchip)
 {
 	vortex_t *chip;
@@ -234,7 +234,7 @@
 }
 
 // constructor -- see "Constructor" sub-section
-static int __devinit
+static int
 snd_vortex_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
 {
 	static int dev;
@@ -368,7 +368,7 @@
 }
 
 // destructor -- see "Destructor" sub-section
-static void __devexit snd_vortex_remove(struct pci_dev *pci)
+static void snd_vortex_remove(struct pci_dev *pci)
 {
 	snd_card_free(pci_get_drvdata(pci));
 	pci_set_drvdata(pci, NULL);
@@ -379,7 +379,7 @@
 	.name = KBUILD_MODNAME,
 	.id_table = snd_vortex_ids,
 	.probe = snd_vortex_probe,
-	.remove = __devexit_p(snd_vortex_remove),
+	.remove = snd_vortex_remove,
 };
 
 module_pci_driver(vortex_driver);
diff --git a/sound/pci/au88x0/au88x0_a3d.c b/sound/pci/au88x0/au88x0_a3d.c
index 9ae8b3b..aad831a 100644
--- a/sound/pci/au88x0/au88x0_a3d.c
+++ b/sound/pci/au88x0/au88x0_a3d.c
@@ -594,7 +594,7 @@
 static int vortex_a3d_register_controls(vortex_t * vortex);
 static void vortex_a3d_unregister_controls(vortex_t * vortex);
 /* A3D base support init/shudown */
-static void __devinit vortex_Vort3D_enable(vortex_t * v)
+static void vortex_Vort3D_enable(vortex_t *v)
 {
 	int i;
 
@@ -845,7 +845,7 @@
 	return changed;
 }
 
-static struct snd_kcontrol_new vortex_a3d_kcontrol __devinitdata = {
+static struct snd_kcontrol_new vortex_a3d_kcontrol = {
 	.iface = SNDRV_CTL_ELEM_IFACE_PCM,
 	.name = "Playback PCM advanced processing",
 	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
@@ -855,7 +855,7 @@
 };
 
 /* Control (un)registration. */
-static int __devinit vortex_a3d_register_controls(vortex_t * vortex)
+static int vortex_a3d_register_controls(vortex_t *vortex)
 {
 	struct snd_kcontrol *kcontrol;
 	int err, i;
diff --git a/sound/pci/au88x0/au88x0_core.c b/sound/pci/au88x0/au88x0_core.c
index 525f881..ae59dba 100644
--- a/sound/pci/au88x0/au88x0_core.c
+++ b/sound/pci/au88x0/au88x0_core.c
@@ -2461,7 +2461,12 @@
 #ifndef CHIP_AU8810
 		for (i = 0; i < NR_WT; i++) {
 			if (vortex->dma_wt[i].fifo_status == FIFO_START) {
-				if (vortex_wtdma_bufshift(vortex, i)) ;
+				/* FIXME: we ignore the return value from
+				 * vortex_wtdma_bufshift() below as the delta
+				 * calculation seems not working for wavetable
+				 * by some reason
+				 */
+				vortex_wtdma_bufshift(vortex, i);
 				spin_unlock(&vortex->lock);
 				snd_pcm_period_elapsed(vortex->dma_wt[i].
 						       substream);
@@ -2675,7 +2680,7 @@
 
 /* Initialization */
 
-static int __devinit vortex_core_init(vortex_t * vortex)
+static int vortex_core_init(vortex_t *vortex)
 {
 
 	printk(KERN_INFO "Vortex: init.... ");
diff --git a/sound/pci/au88x0/au88x0_eq.c b/sound/pci/au88x0/au88x0_eq.c
index 278ed81..e722053 100644
--- a/sound/pci/au88x0/au88x0_eq.c
+++ b/sound/pci/au88x0/au88x0_eq.c
@@ -757,7 +757,7 @@
 	return 1;		/* Allways changes */
 }
 
-static struct snd_kcontrol_new vortex_eqtoggle_kcontrol __devinitdata = {
+static struct snd_kcontrol_new vortex_eqtoggle_kcontrol = {
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name = "EQ Enable",
 	.index = 0,
@@ -815,7 +815,7 @@
 	return changed;
 }
 
-static struct snd_kcontrol_new vortex_eq_kcontrol __devinitdata = {
+static struct snd_kcontrol_new vortex_eq_kcontrol = {
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name = "                        .",
 	.index = 0,
@@ -854,7 +854,7 @@
 	return 0;
 }
 
-static struct snd_kcontrol_new vortex_levels_kcontrol __devinitdata = {
+static struct snd_kcontrol_new vortex_levels_kcontrol = {
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name = "EQ Peaks",
 	.access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
@@ -863,7 +863,7 @@
 };
 
 /* EQ band gain labels. */
-static char *EqBandLabels[10] __devinitdata = {
+static char *EqBandLabels[10] = {
 	"EQ0 31Hz\0",
 	"EQ1 63Hz\0",
 	"EQ2 125Hz\0",
@@ -877,7 +877,7 @@
 };
 
 /* ALSA driver entry points. Init and exit. */
-static int __devinit vortex_eq_init(vortex_t * vortex)
+static int vortex_eq_init(vortex_t *vortex)
 {
 	struct snd_kcontrol *kcontrol;
 	int err, i;
diff --git a/sound/pci/au88x0/au88x0_game.c b/sound/pci/au88x0/au88x0_game.c
index 30a4567..280f86d 100644
--- a/sound/pci/au88x0/au88x0_game.c
+++ b/sound/pci/au88x0/au88x0_game.c
@@ -92,7 +92,7 @@
 	return 0;
 }
 
-static int __devinit vortex_gameport_register(vortex_t * vortex)
+static int vortex_gameport_register(vortex_t *vortex)
 {
 	struct gameport *gp;
 
diff --git a/sound/pci/au88x0/au88x0_mixer.c b/sound/pci/au88x0/au88x0_mixer.c
index fa13efb..a58298c 100644
--- a/sound/pci/au88x0/au88x0_mixer.c
+++ b/sound/pci/au88x0/au88x0_mixer.c
@@ -19,7 +19,7 @@
 	return snd_ctl_remove_id(card, &id);
 }
 
-static int __devinit snd_vortex_mixer(vortex_t * vortex)
+static int snd_vortex_mixer(vortex_t *vortex)
 {
 	struct snd_ac97_bus *pbus;
 	struct snd_ac97_template ac97;
diff --git a/sound/pci/au88x0/au88x0_mpu401.c b/sound/pci/au88x0/au88x0_mpu401.c
index e6c6a0f..29e5945 100644
--- a/sound/pci/au88x0/au88x0_mpu401.c
+++ b/sound/pci/au88x0/au88x0_mpu401.c
@@ -41,7 +41,7 @@
 #define MPU401_ENTER_UART	0x3f
 #define MPU401_ACK		    0xfe
 
-static int __devinit snd_vortex_midi(vortex_t * vortex)
+static int snd_vortex_midi(vortex_t *vortex)
 {
 	struct snd_rawmidi *rmidi;
 	int temp, mode;
diff --git a/sound/pci/au88x0/au88x0_pcm.c b/sound/pci/au88x0/au88x0_pcm.c
index b240502..a4184bb 100644
--- a/sound/pci/au88x0/au88x0_pcm.c
+++ b/sound/pci/au88x0/au88x0_pcm.c
@@ -516,7 +516,7 @@
 }
 
 /* spdif controls */
-static struct snd_kcontrol_new snd_vortex_mixer_spdif[] __devinitdata = {
+static struct snd_kcontrol_new snd_vortex_mixer_spdif[] = {
 	{
 		.iface =	SNDRV_CTL_ELEM_IFACE_PCM,
 		.name =		SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
@@ -598,7 +598,7 @@
 
 static const DECLARE_TLV_DB_MINMAX(vortex_pcm_vol_db_scale, -9600, 2400);
 
-static struct snd_kcontrol_new snd_vortex_pcm_vol __devinitdata = {
+static struct snd_kcontrol_new snd_vortex_pcm_vol = {
 	.iface = SNDRV_CTL_ELEM_IFACE_PCM,
 	.name = "PCM Playback Volume",
 	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
@@ -611,7 +611,7 @@
 };
 
 /* create a pcm device */
-static int __devinit snd_vortex_new_pcm(vortex_t *chip, int idx, int nr)
+static int snd_vortex_new_pcm(vortex_t *chip, int idx, int nr)
 {
 	struct snd_pcm *pcm;
 	struct snd_kcontrol *kctl;
diff --git a/sound/pci/aw2/aw2-alsa.c b/sound/pci/aw2/aw2-alsa.c
index 0f80474..08e9a47 100644
--- a/sound/pci/aw2/aw2-alsa.c
+++ b/sound/pci/aw2/aw2-alsa.c
@@ -113,11 +113,11 @@
  * FUNCTION DECLARATIONS
  ********************************/
 static int snd_aw2_dev_free(struct snd_device *device);
-static int __devinit snd_aw2_create(struct snd_card *card,
-				    struct pci_dev *pci, struct aw2 **rchip);
-static int __devinit snd_aw2_probe(struct pci_dev *pci,
-				   const struct pci_device_id *pci_id);
-static void __devexit snd_aw2_remove(struct pci_dev *pci);
+static int snd_aw2_create(struct snd_card *card,
+			  struct pci_dev *pci, struct aw2 **rchip);
+static int snd_aw2_probe(struct pci_dev *pci,
+			 const struct pci_device_id *pci_id);
+static void snd_aw2_remove(struct pci_dev *pci);
 static int snd_aw2_pcm_playback_open(struct snd_pcm_substream *substream);
 static int snd_aw2_pcm_playback_close(struct snd_pcm_substream *substream);
 static int snd_aw2_pcm_capture_open(struct snd_pcm_substream *substream);
@@ -135,7 +135,7 @@
 						      *substream);
 static snd_pcm_uframes_t snd_aw2_pcm_pointer_capture(struct snd_pcm_substream
 						     *substream);
-static int __devinit snd_aw2_new_pcm(struct aw2 *chip);
+static int snd_aw2_new_pcm(struct aw2 *chip);
 
 static int snd_aw2_control_switch_capture_info(struct snd_kcontrol *kcontrol,
 					       struct snd_ctl_elem_info *uinfo);
@@ -173,7 +173,7 @@
 	.name = KBUILD_MODNAME,
 	.id_table = snd_aw2_ids,
 	.probe = snd_aw2_probe,
-	.remove = __devexit_p(snd_aw2_remove),
+	.remove = snd_aw2_remove,
 };
 
 module_pci_driver(aw2_driver);
@@ -202,7 +202,7 @@
 	.pointer = snd_aw2_pcm_pointer_capture,
 };
 
-static struct snd_kcontrol_new aw2_control __devinitdata = {
+static struct snd_kcontrol_new aw2_control = {
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name = "PCM Capture Route",
 	.index = 0,
@@ -242,8 +242,8 @@
 }
 
 /* chip-specific constructor */
-static int __devinit snd_aw2_create(struct snd_card *card,
-				    struct pci_dev *pci, struct aw2 **rchip)
+static int snd_aw2_create(struct snd_card *card,
+			  struct pci_dev *pci, struct aw2 **rchip)
 {
 	struct aw2 *chip;
 	int err;
@@ -332,8 +332,8 @@
 }
 
 /* constructor */
-static int __devinit snd_aw2_probe(struct pci_dev *pci,
-				   const struct pci_device_id *pci_id)
+static int snd_aw2_probe(struct pci_dev *pci,
+			 const struct pci_device_id *pci_id)
 {
 	static int dev;
 	struct snd_card *card;
@@ -389,7 +389,7 @@
 }
 
 /* destructor */
-static void __devexit snd_aw2_remove(struct pci_dev *pci)
+static void snd_aw2_remove(struct pci_dev *pci)
 {
 	snd_card_free(pci_get_drvdata(pci));
 	pci_set_drvdata(pci, NULL);
@@ -591,7 +591,7 @@
 }
 
 /* create a pcm device */
-static int __devinit snd_aw2_new_pcm(struct aw2 *chip)
+static int snd_aw2_new_pcm(struct aw2 *chip)
 {
 	struct snd_pcm *pcm_playback_ana;
 	struct snd_pcm *pcm_playback_num;
diff --git a/sound/pci/azt3328.c b/sound/pci/azt3328.c
index c03b66b..1204a0f 100644
--- a/sound/pci/azt3328.c
+++ b/sound/pci/azt3328.c
@@ -817,7 +817,7 @@
 		snd_azf3328_mixer_ac97_map_unsupported(reg_ac97, "write");
 }
 
-static int __devinit
+static int
 snd_azf3328_mixer_new(struct snd_azf3328 *chip)
 {
 	struct snd_ac97_bus *bus;
@@ -1171,7 +1171,7 @@
 	return (nreg != oreg);
 }
 
-static struct snd_kcontrol_new snd_azf3328_mixer_controls[] __devinitdata = {
+static struct snd_kcontrol_new snd_azf3328_mixer_controls[] = {
 	AZF3328_MIXER_SWITCH("Master Playback Switch", IDX_MIXER_PLAY_MASTER, 15, 1),
 	AZF3328_MIXER_VOL_STEREO("Master Playback Volume", IDX_MIXER_PLAY_MASTER, 0x1f, 1),
 	AZF3328_MIXER_SWITCH("PCM Playback Switch", IDX_MIXER_WAVEOUT, 15, 1),
@@ -1229,7 +1229,7 @@
 #endif
 };
 
-static u16 __devinitdata snd_azf3328_init_values[][2] = {
+static u16 snd_azf3328_init_values[][2] = {
         { IDX_MIXER_PLAY_MASTER,	MIXER_MUTE_MASK|0x1f1f },
         { IDX_MIXER_MODEMOUT,		MIXER_MUTE_MASK|0x1f1f },
 	{ IDX_MIXER_BASSTREBLE,		0x0000 },
@@ -1245,7 +1245,7 @@
         { IDX_MIXER_REC_VOLUME,		MIXER_MUTE_MASK|0x0707 },
 };
 
-static int __devinit
+static int
 snd_azf3328_mixer_new(struct snd_azf3328 *chip)
 {
 	struct snd_card *card;
@@ -1899,7 +1899,7 @@
 	return 0;
 }
 
-static int __devinit
+static int
 snd_azf3328_gameport(struct snd_azf3328 *chip, int dev)
 {
 	struct gameport *gp;
@@ -2212,7 +2212,7 @@
 	.pointer =	snd_azf3328_pcm_pointer
 };
 
-static int __devinit
+static int
 snd_azf3328_pcm(struct snd_azf3328 *chip)
 {
 enum { AZF_PCMDEV_STD, AZF_PCMDEV_I2S_OUT, NUM_AZF_PCMDEVS }; /* pcm devices */
@@ -2344,7 +2344,7 @@
 	.precise_resolution = snd_azf3328_timer_precise_resolution,
 };
 
-static int __devinit
+static int
 snd_azf3328_timer(struct snd_azf3328 *chip, int device)
 {
 	struct snd_timer *timer = NULL;
@@ -2489,7 +2489,7 @@
 #endif /* DEBUG_MISC */
 }
 
-static int __devinit
+static int
 snd_azf3328_create(struct snd_card *card,
 		   struct pci_dev *pci,
 		   unsigned long device_type,
@@ -2615,7 +2615,7 @@
 	return err;
 }
 
-static int __devinit
+static int
 snd_azf3328_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
 {
 	static int dev;
@@ -2720,7 +2720,7 @@
 	return err;
 }
 
-static void __devexit
+static void
 snd_azf3328_remove(struct pci_dev *pci)
 {
 	snd_azf3328_dbgcallenter();
@@ -2872,7 +2872,7 @@
 	.name = KBUILD_MODNAME,
 	.id_table = snd_azf3328_ids,
 	.probe = snd_azf3328_probe,
-	.remove = __devexit_p(snd_azf3328_remove),
+	.remove = snd_azf3328_remove,
 	.driver = {
 		.pm = SND_AZF3328_PM_OPS,
 	},
diff --git a/sound/pci/bt87x.c b/sound/pci/bt87x.c
index b6a95ee..cdd100d 100644
--- a/sound/pci/bt87x.c
+++ b/sound/pci/bt87x.c
@@ -164,7 +164,7 @@
 	unsigned no_digital:1;	/* No digital input */
 };
 
-static __devinitdata struct snd_bt87x_board snd_bt87x_boards[] = {
+static struct snd_bt87x_board snd_bt87x_boards[] = {
 	[SND_BT87X_BOARD_UNKNOWN] = {
 		.dig_rate = 32000, /* just a guess */
 	},
@@ -696,7 +696,7 @@
 	return snd_bt87x_free(chip);
 }
 
-static int __devinit snd_bt87x_pcm(struct snd_bt87x *chip, int device, char *name)
+static int snd_bt87x_pcm(struct snd_bt87x *chip, int device, char *name)
 {
 	int err;
 	struct snd_pcm *pcm;
@@ -714,9 +714,9 @@
 							ALIGN(255 * 4092, 1024));
 }
 
-static int __devinit snd_bt87x_create(struct snd_card *card,
-				      struct pci_dev *pci,
-				      struct snd_bt87x **rchip)
+static int snd_bt87x_create(struct snd_card *card,
+			    struct pci_dev *pci,
+			    struct snd_bt87x **rchip)
 {
 	struct snd_bt87x *chip;
 	int err;
@@ -822,7 +822,7 @@
  * (DVB cards use the audio function to transfer MPEG data) */
 static struct {
 	unsigned short subvendor, subdevice;
-} blacklist[] __devinitdata = {
+} blacklist[] = {
 	{0x0071, 0x0101}, /* Nebula Electronics DigiTV */
 	{0x11bd, 0x001c}, /* Pinnacle PCTV Sat */
 	{0x11bd, 0x0026}, /* Pinnacle PCTV SAT CI */
@@ -837,7 +837,7 @@
 };
 
 /* return the id of the card, or a negative value if it's blacklisted */
-static int __devinit snd_bt87x_detect_card(struct pci_dev *pci)
+static int snd_bt87x_detect_card(struct pci_dev *pci)
 {
 	int i;
 	const struct pci_device_id *supported;
@@ -862,8 +862,8 @@
 	return SND_BT87X_BOARD_UNKNOWN;
 }
 
-static int __devinit snd_bt87x_probe(struct pci_dev *pci,
-				     const struct pci_device_id *pci_id)
+static int snd_bt87x_probe(struct pci_dev *pci,
+			   const struct pci_device_id *pci_id)
 {
 	static int dev;
 	struct snd_card *card;
@@ -948,7 +948,7 @@
 	return err;
 }
 
-static void __devexit snd_bt87x_remove(struct pci_dev *pci)
+static void snd_bt87x_remove(struct pci_dev *pci)
 {
 	snd_card_free(pci_get_drvdata(pci));
 	pci_set_drvdata(pci, NULL);
@@ -966,7 +966,7 @@
 	.name = KBUILD_MODNAME,
 	.id_table = snd_bt87x_ids,
 	.probe = snd_bt87x_probe,
-	.remove = __devexit_p(snd_bt87x_remove),
+	.remove = snd_bt87x_remove,
 };
 
 module_pci_driver(bt87x_driver);
diff --git a/sound/pci/ca0106/ca0106_main.c b/sound/pci/ca0106/ca0106_main.c
index 65c5591..1610a57 100644
--- a/sound/pci/ca0106/ca0106_main.c
+++ b/sound/pci/ca0106/ca0106_main.c
@@ -1352,7 +1352,7 @@
 	{ }
 };
 
-static int __devinit snd_ca0106_pcm(struct snd_ca0106 *emu, int device)
+static int snd_ca0106_pcm(struct snd_ca0106 *emu, int device)
 {
 	struct snd_pcm *pcm;
 	struct snd_pcm_substream *substream;
@@ -1650,7 +1650,7 @@
 	 */
 }
 
-static int __devinit snd_ca0106_create(int dev, struct snd_card *card,
+static int snd_ca0106_create(int dev, struct snd_card *card,
 					 struct pci_dev *pci,
 					 struct snd_ca0106 **rchip)
 {
@@ -1777,7 +1777,7 @@
 	return ((struct snd_ca0106 *)dev_id)->port;
 }
 
-static int __devinit snd_ca0106_midi(struct snd_ca0106 *chip, unsigned int channel)
+static int snd_ca0106_midi(struct snd_ca0106 *chip, unsigned int channel)
 {
 	struct snd_ca_midi *midi;
 	char *name;
@@ -1828,7 +1828,7 @@
 }
 
 
-static int __devinit snd_ca0106_probe(struct pci_dev *pci,
+static int snd_ca0106_probe(struct pci_dev *pci,
 					const struct pci_device_id *pci_id)
 {
 	static int dev;
@@ -1893,7 +1893,7 @@
 	return err;
 }
 
-static void __devexit snd_ca0106_remove(struct pci_dev *pci)
+static void snd_ca0106_remove(struct pci_dev *pci)
 {
 	snd_card_free(pci_get_drvdata(pci));
 	pci_set_drvdata(pci, NULL);
@@ -1971,7 +1971,7 @@
 	.name = KBUILD_MODNAME,
 	.id_table = snd_ca0106_ids,
 	.probe = snd_ca0106_probe,
-	.remove = __devexit_p(snd_ca0106_remove),
+	.remove = snd_ca0106_remove,
 	.driver = {
 		.pm = SND_CA0106_PM_OPS,
 	},
diff --git a/sound/pci/ca0106/ca0106_mixer.c b/sound/pci/ca0106/ca0106_mixer.c
index 68eacf7..27de0de 100644
--- a/sound/pci/ca0106/ca0106_mixer.c
+++ b/sound/pci/ca0106/ca0106_mixer.c
@@ -325,7 +325,7 @@
         return change;
 }
 
-static struct snd_kcontrol_new snd_ca0106_capture_mic_line_in __devinitdata =
+static struct snd_kcontrol_new snd_ca0106_capture_mic_line_in =
 {
 	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name =		"Shared Mic/Line in Capture Switch",
@@ -334,7 +334,7 @@
 	.put =		snd_ca0106_capture_mic_line_in_put
 };
 
-static struct snd_kcontrol_new snd_ca0106_capture_line_in_side_out __devinitdata =
+static struct snd_kcontrol_new snd_ca0106_capture_line_in_side_out =
 {
 	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name =		"Shared Line in/Side out Capture Switch",
@@ -588,7 +588,7 @@
 	.private_value = ((chid) << 8) | (reg)			\
 }
 
-static struct snd_kcontrol_new snd_ca0106_volume_ctls[] __devinitdata = {
+static struct snd_kcontrol_new snd_ca0106_volume_ctls[] = {
 	CA_VOLUME("Analog Front Playback Volume",
 		  CONTROL_FRONT_CHANNEL, PLAYBACK_VOLUME2),
         CA_VOLUME("Analog Rear Playback Volume",
@@ -669,7 +669,7 @@
 	.private_value = chid					\
 }
 
-static struct snd_kcontrol_new snd_ca0106_volume_i2c_adc_ctls[] __devinitdata = {
+static struct snd_kcontrol_new snd_ca0106_volume_i2c_adc_ctls[] = {
         I2C_VOLUME("Phone Capture Volume", 0),
         I2C_VOLUME("Mic Capture Volume", 1),
         I2C_VOLUME("Line in Capture Volume", 2),
@@ -691,7 +691,7 @@
 	SPI_DMUTE4_BIT,
 };
 
-static struct snd_kcontrol_new __devinit
+static struct snd_kcontrol_new
 snd_ca0106_volume_spi_dac_ctl(struct snd_ca0106_details *details,
 			      int channel_id)
 {
@@ -735,7 +735,7 @@
 	return spi_switch;
 }
 
-static int __devinit remove_ctl(struct snd_card *card, const char *name)
+static int remove_ctl(struct snd_card *card, const char *name)
 {
 	struct snd_ctl_elem_id id;
 	memset(&id, 0, sizeof(id));
@@ -744,7 +744,7 @@
 	return snd_ctl_remove_id(card, &id);
 }
 
-static struct snd_kcontrol __devinit *ctl_find(struct snd_card *card, const char *name)
+static struct snd_kcontrol *ctl_find(struct snd_card *card, const char *name)
 {
 	struct snd_ctl_elem_id sid;
 	memset(&sid, 0, sizeof(sid));
@@ -754,7 +754,7 @@
 	return snd_ctl_find_id(card, &sid);
 }
 
-static int __devinit rename_ctl(struct snd_card *card, const char *src, const char *dst)
+static int rename_ctl(struct snd_card *card, const char *src, const char *dst)
 {
 	struct snd_kcontrol *kctl = ctl_find(card, src);
 	if (kctl) {
@@ -774,10 +774,10 @@
 		}							\
 	} while (0)
 
-static __devinitdata
+static
 DECLARE_TLV_DB_SCALE(snd_ca0106_master_db_scale, -6375, 25, 1);
 
-static char *slave_vols[] __devinitdata = {
+static char *slave_vols[] = {
 	"Analog Front Playback Volume",
         "Analog Rear Playback Volume",
 	"Analog Center/LFE Playback Volume",
@@ -790,7 +790,7 @@
 	NULL
 };
 
-static char *slave_sws[] __devinitdata = {
+static char *slave_sws[] = {
 	"Analog Front Playback Switch",
 	"Analog Rear Playback Switch",
 	"Analog Center/LFE Playback Switch",
@@ -799,7 +799,7 @@
 	NULL
 };
 
-static void __devinit add_slaves(struct snd_card *card,
+static void add_slaves(struct snd_card *card,
 				 struct snd_kcontrol *master, char **list)
 {
 	for (; *list; list++) {
@@ -809,7 +809,7 @@
 	}
 }
 
-int __devinit snd_ca0106_mixer(struct snd_ca0106 *emu)
+int snd_ca0106_mixer(struct snd_ca0106 *emu)
 {
 	int err;
         struct snd_card *card = emu->card;
diff --git a/sound/pci/ca0106/ca0106_proc.c b/sound/pci/ca0106/ca0106_proc.c
index c694464b..4f9c282 100644
--- a/sound/pci/ca0106/ca0106_proc.c
+++ b/sound/pci/ca0106/ca0106_proc.c
@@ -424,7 +424,7 @@
         }
 }
 
-int __devinit snd_ca0106_proc_init(struct snd_ca0106 * emu)
+int snd_ca0106_proc_init(struct snd_ca0106 *emu)
 {
 	struct snd_info_entry *entry;
 	
diff --git a/sound/pci/ca0106/ca_midi.c b/sound/pci/ca0106/ca_midi.c
index c788511..8bbdf26 100644
--- a/sound/pci/ca0106/ca_midi.c
+++ b/sound/pci/ca0106/ca_midi.c
@@ -286,7 +286,7 @@
 	ca_midi_free(rmidi->private_data);
 }
 
-int __devinit ca_midi_init(void *dev_id, struct snd_ca_midi *midi, int device, char *name)
+int ca_midi_init(void *dev_id, struct snd_ca_midi *midi, int device, char *name)
 {
 	struct snd_rawmidi *rmidi;
 	int err;
diff --git a/sound/pci/cmipci.c b/sound/pci/cmipci.c
index 22122ff..c617435 100644
--- a/sound/pci/cmipci.c
+++ b/sound/pci/cmipci.c
@@ -1045,7 +1045,7 @@
 	return change;
 }
 
-static struct snd_kcontrol_new snd_cmipci_spdif_default __devinitdata =
+static struct snd_kcontrol_new snd_cmipci_spdif_default =
 {
 	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,
 	.name =		SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
@@ -1072,7 +1072,7 @@
 	return 0;
 }
 
-static struct snd_kcontrol_new snd_cmipci_spdif_mask __devinitdata =
+static struct snd_kcontrol_new snd_cmipci_spdif_mask =
 {
 	.access =	SNDRV_CTL_ELEM_ACCESS_READ,
 	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,
@@ -1119,7 +1119,7 @@
 	return change;
 }
 
-static struct snd_kcontrol_new snd_cmipci_spdif_stream __devinitdata =
+static struct snd_kcontrol_new snd_cmipci_spdif_stream =
 {
 	.access =	SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
 	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,
@@ -1897,7 +1897,7 @@
 /*
  */
 
-static int __devinit snd_cmipci_pcm_new(struct cmipci *cm, int device)
+static int snd_cmipci_pcm_new(struct cmipci *cm, int device)
 {
 	struct snd_pcm *pcm;
 	int err;
@@ -1920,7 +1920,7 @@
 	return 0;
 }
 
-static int __devinit snd_cmipci_pcm2_new(struct cmipci *cm, int device)
+static int snd_cmipci_pcm2_new(struct cmipci *cm, int device)
 {
 	struct snd_pcm *pcm;
 	int err;
@@ -1942,7 +1942,7 @@
 	return 0;
 }
 
-static int __devinit snd_cmipci_pcm_spdif_new(struct cmipci *cm, int device)
+static int snd_cmipci_pcm_spdif_new(struct cmipci *cm, int device)
 {
 	struct snd_pcm *pcm;
 	int err;
@@ -2290,7 +2290,7 @@
 }
 
 
-static struct snd_kcontrol_new snd_cmipci_mixers[] __devinitdata = {
+static struct snd_kcontrol_new snd_cmipci_mixers[] = {
 	CMIPCI_SB_VOL_STEREO("Master Playback Volume", SB_DSP4_MASTER_DEV, 3, 31),
 	CMIPCI_MIXER_SW_MONO("3D Control - Switch", CM_REG_MIXER1, CM_X3DEN_SHIFT, 0),
 	CMIPCI_SB_VOL_STEREO("PCM Playback Volume", SB_DSP4_PCM_DEV, 3, 31),
@@ -2601,7 +2601,7 @@
 }
 
 /* both for CM8338/8738 */
-static struct snd_kcontrol_new snd_cmipci_mixer_switches[] __devinitdata = {
+static struct snd_kcontrol_new snd_cmipci_mixer_switches[] = {
 	DEFINE_MIXER_SWITCH("Four Channel Mode", fourch),
 	{
 		.name = "Line-In Mode",
@@ -2613,11 +2613,11 @@
 };
 
 /* for non-multichannel chips */
-static struct snd_kcontrol_new snd_cmipci_nomulti_switch __devinitdata =
+static struct snd_kcontrol_new snd_cmipci_nomulti_switch =
 DEFINE_MIXER_SWITCH("Exchange DAC", exchange_dac);
 
 /* only for CM8738 */
-static struct snd_kcontrol_new snd_cmipci_8738_mixer_switches[] __devinitdata = {
+static struct snd_kcontrol_new snd_cmipci_8738_mixer_switches[] = {
 #if 0 /* controlled in pcm device */
 	DEFINE_MIXER_SWITCH("IEC958 In Record", spdif_in),
 	DEFINE_MIXER_SWITCH("IEC958 Out", spdif_out),
@@ -2639,14 +2639,14 @@
 };
 
 /* only for model 033/037 */
-static struct snd_kcontrol_new snd_cmipci_old_mixer_switches[] __devinitdata = {
+static struct snd_kcontrol_new snd_cmipci_old_mixer_switches[] = {
 	DEFINE_MIXER_SWITCH("IEC958 Mix Analog", spdif_dac_out),
 	DEFINE_MIXER_SWITCH("IEC958 In Phase Inverse", spdi_phase),
 	DEFINE_MIXER_SWITCH("IEC958 In Select", spdif_in_sel1),
 };
 
 /* only for model 039 or later */
-static struct snd_kcontrol_new snd_cmipci_extra_mixer_switches[] __devinitdata = {
+static struct snd_kcontrol_new snd_cmipci_extra_mixer_switches[] = {
 	DEFINE_MIXER_SWITCH("IEC958 In Select", spdif_in_sel2),
 	DEFINE_MIXER_SWITCH("IEC958 In Phase Inverse", spdi_phase2),
 	{
@@ -2659,11 +2659,11 @@
 };
 
 /* card control switches */
-static struct snd_kcontrol_new snd_cmipci_modem_switch __devinitdata =
+static struct snd_kcontrol_new snd_cmipci_modem_switch =
 DEFINE_CARD_SWITCH("Modem", modem);
 
 
-static int __devinit snd_cmipci_mixer_new(struct cmipci *cm, int pcm_spdif_device)
+static int snd_cmipci_mixer_new(struct cmipci *cm, int pcm_spdif_device)
 {
 	struct snd_card *card;
 	struct snd_kcontrol_new *sw;
@@ -2791,7 +2791,7 @@
 	snd_iprintf(buffer, "\n");
 }
 
-static void __devinit snd_cmipci_proc_init(struct cmipci *cm)
+static void snd_cmipci_proc_init(struct cmipci *cm)
 {
 	struct snd_info_entry *entry;
 
@@ -2817,7 +2817,7 @@
  * check chip version and capabilities
  * driver name is modified according to the chip model
  */
-static void __devinit query_chip(struct cmipci *cm)
+static void query_chip(struct cmipci *cm)
 {
 	unsigned int detect;
 
@@ -2866,7 +2866,7 @@
 }
 
 #ifdef SUPPORT_JOYSTICK
-static int __devinit snd_cmipci_create_gameport(struct cmipci *cm, int dev)
+static int snd_cmipci_create_gameport(struct cmipci *cm, int dev)
 {
 	static int ports[] = { 0x201, 0x200, 0 }; /* FIXME: majority is 0x201? */
 	struct gameport *gp;
@@ -2959,7 +2959,7 @@
 	return snd_cmipci_free(cm);
 }
 
-static int __devinit snd_cmipci_create_fm(struct cmipci *cm, long fm_port)
+static int snd_cmipci_create_fm(struct cmipci *cm, long fm_port)
 {
 	long iosynth;
 	unsigned int val;
@@ -3012,8 +3012,8 @@
 	return 0;
 }
 
-static int __devinit snd_cmipci_create(struct snd_card *card, struct pci_dev *pci,
-				       int dev, struct cmipci **rcmipci)
+static int snd_cmipci_create(struct snd_card *card, struct pci_dev *pci,
+			     int dev, struct cmipci **rcmipci)
 {
 	struct cmipci *cm;
 	int err;
@@ -3265,8 +3265,8 @@
 
 MODULE_DEVICE_TABLE(pci, snd_cmipci_ids);
 
-static int __devinit snd_cmipci_probe(struct pci_dev *pci,
-				      const struct pci_device_id *pci_id)
+static int snd_cmipci_probe(struct pci_dev *pci,
+			    const struct pci_device_id *pci_id)
 {
 	static int dev;
 	struct snd_card *card;
@@ -3314,7 +3314,7 @@
 
 }
 
-static void __devexit snd_cmipci_remove(struct pci_dev *pci)
+static void snd_cmipci_remove(struct pci_dev *pci)
 {
 	snd_card_free(pci_get_drvdata(pci));
 	pci_set_drvdata(pci, NULL);
@@ -3415,7 +3415,7 @@
 	.name = KBUILD_MODNAME,
 	.id_table = snd_cmipci_ids,
 	.probe = snd_cmipci_probe,
-	.remove = __devexit_p(snd_cmipci_remove),
+	.remove = snd_cmipci_remove,
 	.driver = {
 		.pm = SND_CMIPCI_PM_OPS,
 	},
diff --git a/sound/pci/cs4281.c b/sound/pci/cs4281.c
index 8e86ec0..6a86950 100644
--- a/sound/pci/cs4281.c
+++ b/sound/pci/cs4281.c
@@ -969,8 +969,8 @@
 	.pointer =	snd_cs4281_pointer,
 };
 
-static int __devinit snd_cs4281_pcm(struct cs4281 * chip, int device,
-				    struct snd_pcm ** rpcm)
+static int snd_cs4281_pcm(struct cs4281 *chip, int device,
+			  struct snd_pcm **rpcm)
 {
 	struct snd_pcm *pcm;
 	int err;
@@ -1093,7 +1093,7 @@
 		chip->ac97 = NULL;
 }
 
-static int __devinit snd_cs4281_mixer(struct cs4281 * chip)
+static int snd_cs4281_mixer(struct cs4281 *chip)
 {
 	struct snd_card *card = chip->card;
 	struct snd_ac97_template ac97;
@@ -1171,7 +1171,7 @@
 	.read = snd_cs4281_BA1_read,
 };
 
-static void __devinit snd_cs4281_proc_init(struct cs4281 * chip)
+static void snd_cs4281_proc_init(struct cs4281 *chip)
 {
 	struct snd_info_entry *entry;
 
@@ -1259,7 +1259,7 @@
 	return 0;
 }
 
-static int __devinit snd_cs4281_create_gameport(struct cs4281 *chip)
+static int snd_cs4281_create_gameport(struct cs4281 *chip)
 {
 	struct gameport *gp;
 
@@ -1335,10 +1335,10 @@
 
 static int snd_cs4281_chip_init(struct cs4281 *chip); /* defined below */
 
-static int __devinit snd_cs4281_create(struct snd_card *card,
-				       struct pci_dev *pci,
-				       struct cs4281 ** rchip,
-				       int dual_codec)
+static int snd_cs4281_create(struct snd_card *card,
+			     struct pci_dev *pci,
+			     struct cs4281 **rchip,
+			     int dual_codec)
 {
 	struct cs4281 *chip;
 	unsigned int tmp;
@@ -1779,8 +1779,8 @@
 	.trigger =	snd_cs4281_midi_input_trigger,
 };
 
-static int __devinit snd_cs4281_midi(struct cs4281 * chip, int device,
-				     struct snd_rawmidi **rrawmidi)
+static int snd_cs4281_midi(struct cs4281 *chip, int device,
+			   struct snd_rawmidi **rrawmidi)
 {
 	struct snd_rawmidi *rmidi;
 	int err;
@@ -1901,8 +1901,8 @@
 	spin_unlock_irqrestore(&opl3->reg_lock, flags);
 }
 
-static int __devinit snd_cs4281_probe(struct pci_dev *pci,
-				      const struct pci_device_id *pci_id)
+static int snd_cs4281_probe(struct pci_dev *pci,
+			    const struct pci_device_id *pci_id)
 {
 	static int dev;
 	struct snd_card *card;
@@ -1968,7 +1968,7 @@
 	return 0;
 }
 
-static void __devexit snd_cs4281_remove(struct pci_dev *pci)
+static void snd_cs4281_remove(struct pci_dev *pci)
 {
 	snd_card_free(pci_get_drvdata(pci));
 	pci_set_drvdata(pci, NULL);
@@ -2095,7 +2095,7 @@
 	.name = KBUILD_MODNAME,
 	.id_table = snd_cs4281_ids,
 	.probe = snd_cs4281_probe,
-	.remove = __devexit_p(snd_cs4281_remove),
+	.remove = snd_cs4281_remove,
 	.driver = {
 		.pm = CS4281_PM_OPS,
 	},
diff --git a/sound/pci/cs46xx/cs46xx.c b/sound/pci/cs46xx/cs46xx.c
index 575bed0..6b0d8b5 100644
--- a/sound/pci/cs46xx/cs46xx.c
+++ b/sound/pci/cs46xx/cs46xx.c
@@ -73,8 +73,8 @@
 
 MODULE_DEVICE_TABLE(pci, snd_cs46xx_ids);
 
-static int __devinit snd_card_cs46xx_probe(struct pci_dev *pci,
-					   const struct pci_device_id *pci_id)
+static int snd_card_cs46xx_probe(struct pci_dev *pci,
+				 const struct pci_device_id *pci_id)
 {
 	static int dev;
 	struct snd_card *card;
@@ -155,7 +155,7 @@
 	return 0;
 }
 
-static void __devexit snd_card_cs46xx_remove(struct pci_dev *pci)
+static void snd_card_cs46xx_remove(struct pci_dev *pci)
 {
 	snd_card_free(pci_get_drvdata(pci));
 	pci_set_drvdata(pci, NULL);
@@ -165,7 +165,7 @@
 	.name = KBUILD_MODNAME,
 	.id_table = snd_cs46xx_ids,
 	.probe = snd_card_cs46xx_probe,
-	.remove = __devexit_p(snd_card_cs46xx_remove),
+	.remove = snd_card_cs46xx_remove,
 #ifdef CONFIG_PM_SLEEP
 	.driver = {
 		.pm = &snd_cs46xx_pm,
diff --git a/sound/pci/cs46xx/cs46xx_lib.c b/sound/pci/cs46xx/cs46xx_lib.c
index a2bb8c9..1b66efd 100644
--- a/sound/pci/cs46xx/cs46xx_lib.c
+++ b/sound/pci/cs46xx/cs46xx_lib.c
@@ -1590,7 +1590,7 @@
 #define MAX_PLAYBACK_CHANNELS	1
 #endif
 
-int __devinit snd_cs46xx_pcm(struct snd_cs46xx *chip, int device, struct snd_pcm ** rpcm)
+int snd_cs46xx_pcm(struct snd_cs46xx *chip, int device, struct snd_pcm **rpcm)
 {
 	struct snd_pcm *pcm;
 	int err;
@@ -1621,7 +1621,8 @@
 
 
 #ifdef CONFIG_SND_CS46XX_NEW_DSP
-int __devinit snd_cs46xx_pcm_rear(struct snd_cs46xx *chip, int device, struct snd_pcm ** rpcm)
+int snd_cs46xx_pcm_rear(struct snd_cs46xx *chip, int device,
+			struct snd_pcm **rpcm)
 {
 	struct snd_pcm *pcm;
 	int err;
@@ -1650,7 +1651,8 @@
 	return 0;
 }
 
-int __devinit snd_cs46xx_pcm_center_lfe(struct snd_cs46xx *chip, int device, struct snd_pcm ** rpcm)
+int snd_cs46xx_pcm_center_lfe(struct snd_cs46xx *chip, int device,
+			      struct snd_pcm **rpcm)
 {
 	struct snd_pcm *pcm;
 	int err;
@@ -1679,7 +1681,8 @@
 	return 0;
 }
 
-int __devinit snd_cs46xx_pcm_iec958(struct snd_cs46xx *chip, int device, struct snd_pcm ** rpcm)
+int snd_cs46xx_pcm_iec958(struct snd_cs46xx *chip, int device,
+			  struct snd_pcm **rpcm)
 {
 	struct snd_pcm *pcm;
 	int err;
@@ -2092,7 +2095,7 @@
 #endif /* CONFIG_SND_CS46XX_NEW_DSP */
 
 
-static struct snd_kcontrol_new snd_cs46xx_controls[] __devinitdata = {
+static struct snd_kcontrol_new snd_cs46xx_controls[] = {
 {
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name = "DAC Volume",
@@ -2278,7 +2281,7 @@
 }
 #endif
 
-static int __devinit cs46xx_detect_codec(struct snd_cs46xx *chip, int codec)
+static int cs46xx_detect_codec(struct snd_cs46xx *chip, int codec)
 {
 	int idx, err;
 	struct snd_ac97_template ac97;
@@ -2311,7 +2314,7 @@
 	return -ENXIO;
 }
 
-int __devinit snd_cs46xx_mixer(struct snd_cs46xx *chip, int spdif_device)
+int snd_cs46xx_mixer(struct snd_cs46xx *chip, int spdif_device)
 {
 	struct snd_card *card = chip->card;
 	struct snd_ctl_elem_id id;
@@ -2531,7 +2534,7 @@
 	.trigger =	snd_cs46xx_midi_input_trigger,
 };
 
-int __devinit snd_cs46xx_midi(struct snd_cs46xx *chip, int device, struct snd_rawmidi **rrawmidi)
+int snd_cs46xx_midi(struct snd_cs46xx *chip, int device, struct snd_rawmidi **rrawmidi)
 {
 	struct snd_rawmidi *rmidi;
 	int err;
@@ -2613,7 +2616,7 @@
 	return 0;
 }
 
-int __devinit snd_cs46xx_gameport(struct snd_cs46xx *chip)
+int snd_cs46xx_gameport(struct snd_cs46xx *chip)
 {
 	struct gameport *gp;
 
@@ -2649,7 +2652,7 @@
 	}
 }
 #else
-int __devinit snd_cs46xx_gameport(struct snd_cs46xx *chip) { return -ENOSYS; }
+int snd_cs46xx_gameport(struct snd_cs46xx *chip) { return -ENOSYS; }
 static inline void snd_cs46xx_remove_gameport(struct snd_cs46xx *chip) { }
 #endif /* CONFIG_GAMEPORT */
 
@@ -2674,7 +2677,7 @@
 	.read = snd_cs46xx_io_read,
 };
 
-static int __devinit snd_cs46xx_proc_init(struct snd_card *card, struct snd_cs46xx *chip)
+static int snd_cs46xx_proc_init(struct snd_card *card, struct snd_cs46xx *chip)
 {
 	struct snd_info_entry *entry;
 	int idx;
@@ -3061,7 +3064,7 @@
 	snd_cs46xx_poke(chip, BA1_CIE, tmp);	/* capture interrupt enable */
 }
 
-int __devinit snd_cs46xx_start_dsp(struct snd_cs46xx *chip)
+int snd_cs46xx_start_dsp(struct snd_cs46xx *chip)
 {	
 	unsigned int tmp;
 	/*
@@ -3477,7 +3480,7 @@
 	void (*mixer_init)(struct snd_cs46xx *);
 };
 
-static struct cs_card_type __devinitdata cards[] = {
+static struct cs_card_type cards[] = {
 	{
 		.vendor = 0x1489,
 		.id = 0x7001,
@@ -3717,10 +3720,10 @@
 /*
  */
 
-int __devinit snd_cs46xx_create(struct snd_card *card,
-		      struct pci_dev * pci,
+int snd_cs46xx_create(struct snd_card *card,
+		      struct pci_dev *pci,
 		      int external_amp, int thinkpad,
-		      struct snd_cs46xx ** rchip)
+		      struct snd_cs46xx **rchip)
 {
 	struct snd_cs46xx *chip;
 	int err, idx;
diff --git a/sound/pci/cs5530.c b/sound/pci/cs5530.c
index d1cca28..dace827 100644
--- a/sound/pci/cs5530.c
+++ b/sound/pci/cs5530.c
@@ -88,13 +88,13 @@
 	return snd_cs5530_free(chip);
 }
 
-static void __devexit snd_cs5530_remove(struct pci_dev *pci)
+static void snd_cs5530_remove(struct pci_dev *pci)
 {
 	snd_card_free(pci_get_drvdata(pci));
 	pci_set_drvdata(pci, NULL);
 }
 
-static u8 __devinit snd_cs5530_mixer_read(unsigned long io, u8 reg)
+static u8 snd_cs5530_mixer_read(unsigned long io, u8 reg)
 {
 	outb(reg, io + 4);
 	udelay(20);
@@ -103,9 +103,9 @@
 	return reg;
 }
 
-static int __devinit snd_cs5530_create(struct snd_card *card,
-				       struct pci_dev *pci,
-				       struct snd_cs5530 **rchip)
+static int snd_cs5530_create(struct snd_card *card,
+			     struct pci_dev *pci,
+			     struct snd_cs5530 **rchip)
 {
 	struct snd_cs5530 *chip;
 	unsigned long sb_base;
@@ -250,8 +250,8 @@
 	return 0;
 }
 
-static int __devinit snd_cs5530_probe(struct pci_dev *pci,
-					const struct pci_device_id *pci_id)
+static int snd_cs5530_probe(struct pci_dev *pci,
+			    const struct pci_device_id *pci_id)
 {
 	static int dev;
 	struct snd_card *card;
@@ -294,7 +294,7 @@
 	.name = KBUILD_MODNAME,
 	.id_table = snd_cs5530_ids,
 	.probe = snd_cs5530_probe,
-	.remove = __devexit_p(snd_cs5530_remove),
+	.remove = snd_cs5530_remove,
 };
 
 module_pci_driver(cs5530_driver);
diff --git a/sound/pci/cs5535audio/cs5535audio.c b/sound/pci/cs5535audio/cs5535audio.c
index 4915efa..7e4b13e 100644
--- a/sound/pci/cs5535audio/cs5535audio.c
+++ b/sound/pci/cs5535audio/cs5535audio.c
@@ -43,7 +43,7 @@
 module_param(ac97_quirk, charp, 0444);
 MODULE_PARM_DESC(ac97_quirk, "AC'97 board specific workarounds.");
 
-static struct ac97_quirk ac97_quirks[] __devinitdata = {
+static struct ac97_quirk ac97_quirks[] = {
 #if 0 /* Not yet confirmed if all 5536 boards are HP only */
 	{
 		.subvendor = PCI_VENDOR_ID_AMD, 
@@ -144,7 +144,7 @@
 	return snd_cs5535audio_codec_read(cs5535au, reg);
 }
 
-static int __devinit snd_cs5535audio_mixer(struct cs5535audio *cs5535au)
+static int snd_cs5535audio_mixer(struct cs5535audio *cs5535au)
 {
 	struct snd_card *card = cs5535au->card;
 	struct snd_ac97_bus *pbus;
@@ -270,9 +270,9 @@
 	return snd_cs5535audio_free(cs5535au);
 }
 
-static int __devinit snd_cs5535audio_create(struct snd_card *card,
-					    struct pci_dev *pci,
-					    struct cs5535audio **rcs5535au)
+static int snd_cs5535audio_create(struct snd_card *card,
+				  struct pci_dev *pci,
+				  struct cs5535audio **rcs5535au)
 {
 	struct cs5535audio *cs5535au;
 
@@ -338,8 +338,8 @@
 	return err;
 }
 
-static int __devinit snd_cs5535audio_probe(struct pci_dev *pci,
-					   const struct pci_device_id *pci_id)
+static int snd_cs5535audio_probe(struct pci_dev *pci,
+				 const struct pci_device_id *pci_id)
 {
 	static int dev;
 	struct snd_card *card;
@@ -387,7 +387,7 @@
 	return err;
 }
 
-static void __devexit snd_cs5535audio_remove(struct pci_dev *pci)
+static void snd_cs5535audio_remove(struct pci_dev *pci)
 {
 	olpc_quirks_cleanup();
 	snd_card_free(pci_get_drvdata(pci));
@@ -398,7 +398,7 @@
 	.name = KBUILD_MODNAME,
 	.id_table = snd_cs5535audio_ids,
 	.probe = snd_cs5535audio_probe,
-	.remove = __devexit_p(snd_cs5535audio_remove),
+	.remove = snd_cs5535audio_remove,
 #ifdef CONFIG_PM_SLEEP
 	.driver = {
 		.pm = &snd_cs5535audio_pm,
diff --git a/sound/pci/cs5535audio/cs5535audio.h b/sound/pci/cs5535audio/cs5535audio.h
index bb3cc64..0579daa 100644
--- a/sound/pci/cs5535audio/cs5535audio.h
+++ b/sound/pci/cs5535audio/cs5535audio.h
@@ -97,10 +97,10 @@
 extern const struct dev_pm_ops snd_cs5535audio_pm;
 
 #ifdef CONFIG_OLPC
-void __devinit olpc_prequirks(struct snd_card *card,
-		struct snd_ac97_template *ac97);
-int __devinit olpc_quirks(struct snd_card *card, struct snd_ac97 *ac97);
-void __devexit olpc_quirks_cleanup(void);
+void olpc_prequirks(struct snd_card *card,
+		    struct snd_ac97_template *ac97);
+int olpc_quirks(struct snd_card *card, struct snd_ac97 *ac97);
+void olpc_quirks_cleanup(void);
 void olpc_analog_input(struct snd_ac97 *ac97, int on);
 void olpc_mic_bias(struct snd_ac97 *ac97, int on);
 
@@ -133,7 +133,7 @@
 static inline void olpc_capture_close(struct snd_ac97 *ac97) { }
 #endif
 
-int __devinit snd_cs5535audio_pcm(struct cs5535audio *cs5535audio);
+int snd_cs5535audio_pcm(struct cs5535audio *cs5535audio);
 
 #endif /* __SOUND_CS5535AUDIO_H */
 
diff --git a/sound/pci/cs5535audio/cs5535audio_olpc.c b/sound/pci/cs5535audio/cs5535audio_olpc.c
index 50da49b..da1cb9c 100644
--- a/sound/pci/cs5535audio/cs5535audio_olpc.c
+++ b/sound/pci/cs5535audio/cs5535audio_olpc.c
@@ -114,7 +114,7 @@
 	return 1;
 }
 
-static struct snd_kcontrol_new olpc_cs5535audio_ctls[] __devinitdata = {
+static struct snd_kcontrol_new olpc_cs5535audio_ctls[] = {
 {
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name = "DC Mode Enable",
@@ -133,8 +133,8 @@
 },
 };
 
-void __devinit olpc_prequirks(struct snd_card *card,
-		struct snd_ac97_template *ac97)
+void olpc_prequirks(struct snd_card *card,
+		    struct snd_ac97_template *ac97)
 {
 	if (!machine_is_olpc())
 		return;
@@ -144,7 +144,7 @@
 		ac97->scaps |= AC97_SCAP_INV_EAPD;
 }
 
-int __devinit olpc_quirks(struct snd_card *card, struct snd_ac97 *ac97)
+int olpc_quirks(struct snd_card *card, struct snd_ac97 *ac97)
 {
 	struct snd_ctl_elem_id elem;
 	int i, err;
@@ -185,7 +185,7 @@
 	return 0;
 }
 
-void __devexit olpc_quirks_cleanup(void)
+void olpc_quirks_cleanup(void)
 {
 	gpio_free(OLPC_GPIO_MIC_AC);
 }
diff --git a/sound/pci/cs5535audio/cs5535audio_pcm.c b/sound/pci/cs5535audio/cs5535audio_pcm.c
index dbf94b1..9ab01a7 100644
--- a/sound/pci/cs5535audio/cs5535audio_pcm.c
+++ b/sound/pci/cs5535audio/cs5535audio_pcm.c
@@ -422,7 +422,7 @@
         .read_dma_pntr = cs5535audio_capture_read_dma_pntr,
 };
 
-int __devinit snd_cs5535audio_pcm(struct cs5535audio *cs5535au)
+int snd_cs5535audio_pcm(struct cs5535audio *cs5535au)
 {
 	struct snd_pcm *pcm;
 	int err;
diff --git a/sound/pci/ctxfi/ctatc.c b/sound/pci/ctxfi/ctatc.c
index a2f997a..b5fa583 100644
--- a/sound/pci/ctxfi/ctatc.c
+++ b/sound/pci/ctxfi/ctatc.c
@@ -38,7 +38,7 @@
 			    | (0x10 << 16) \
 			    | ((IEC958_AES3_CON_FS_48000) << 24))
 
-static struct snd_pci_quirk __devinitdata subsys_20k1_list[] = {
+static struct snd_pci_quirk subsys_20k1_list[] = {
 	SND_PCI_QUIRK(PCI_VENDOR_ID_CREATIVE, 0x0022, "SB055x", CTSB055X),
 	SND_PCI_QUIRK(PCI_VENDOR_ID_CREATIVE, 0x002f, "SB055x", CTSB055X),
 	SND_PCI_QUIRK(PCI_VENDOR_ID_CREATIVE, 0x0029, "SB073x", CTSB073X),
@@ -48,7 +48,7 @@
 	{ } /* terminator */
 };
 
-static struct snd_pci_quirk __devinitdata subsys_20k2_list[] = {
+static struct snd_pci_quirk subsys_20k2_list[] = {
 	SND_PCI_QUIRK(PCI_VENDOR_ID_CREATIVE, PCI_SUBDEVICE_ID_CREATIVE_SB0760,
 		      "SB0760", CTSB0760),
 	SND_PCI_QUIRK(PCI_VENDOR_ID_CREATIVE, PCI_SUBDEVICE_ID_CREATIVE_SB1270,
@@ -1249,7 +1249,7 @@
 	return ct_atc_destroy(atc);
 }
 
-static int __devinit atc_identify_card(struct ct_atc *atc, unsigned int ssid)
+static int atc_identify_card(struct ct_atc *atc, unsigned int ssid)
 {
 	const struct snd_pci_quirk *p;
 	const struct snd_pci_quirk *list;
@@ -1296,7 +1296,7 @@
 	return 0;
 }
 
-int __devinit ct_atc_create_alsa_devs(struct ct_atc *atc)
+int ct_atc_create_alsa_devs(struct ct_atc *atc)
 {
 	enum CTALSADEVS i;
 	int err;
@@ -1319,7 +1319,7 @@
 	return 0;
 }
 
-static int __devinit atc_create_hw_devs(struct ct_atc *atc)
+static int atc_create_hw_devs(struct ct_atc *atc)
 {
 	struct hw *hw;
 	struct card_conf info = {0};
@@ -1614,7 +1614,7 @@
 }
 #endif
 
-static struct ct_atc atc_preset __devinitdata = {
+static struct ct_atc atc_preset = {
 	.map_audio_buffer = ct_map_audio_buffer,
 	.unmap_audio_buffer = ct_unmap_audio_buffer,
 	.pcm_playback_prepare = atc_pcm_playback_prepare,
@@ -1665,10 +1665,10 @@
  *  Returns 0 if succeeds, or negative error code if fails.
  */
 
-int __devinit ct_atc_create(struct snd_card *card, struct pci_dev *pci,
-			    unsigned int rsr, unsigned int msr,
-			    int chip_type, unsigned int ssid,
-			    struct ct_atc **ratc)
+int ct_atc_create(struct snd_card *card, struct pci_dev *pci,
+		  unsigned int rsr, unsigned int msr,
+		  int chip_type, unsigned int ssid,
+		  struct ct_atc **ratc)
 {
 	struct ct_atc *atc;
 	static struct snd_device_ops ops = {
diff --git a/sound/pci/ctxfi/ctatc.h b/sound/pci/ctxfi/ctatc.h
index 69b51f9..5f11ca2 100644
--- a/sound/pci/ctxfi/ctatc.h
+++ b/sound/pci/ctxfi/ctatc.h
@@ -152,9 +152,9 @@
 };
 
 
-int __devinit ct_atc_create(struct snd_card *card, struct pci_dev *pci,
-			    unsigned int rsr, unsigned int msr, int chip_type,
-			    unsigned int subsysid, struct ct_atc **ratc);
-int __devinit ct_atc_create_alsa_devs(struct ct_atc *atc);
+int ct_atc_create(struct snd_card *card, struct pci_dev *pci,
+		  unsigned int rsr, unsigned int msr, int chip_type,
+		  unsigned int subsysid, struct ct_atc **ratc);
+int ct_atc_create_alsa_devs(struct ct_atc *atc);
 
 #endif /* CTATC_H */
diff --git a/sound/pci/ctxfi/cthardware.c b/sound/pci/ctxfi/cthardware.c
index 8e64f48..110b8ac 100644
--- a/sound/pci/ctxfi/cthardware.c
+++ b/sound/pci/ctxfi/cthardware.c
@@ -20,8 +20,8 @@
 #include "cthw20k2.h"
 #include <linux/bug.h>
 
-int __devinit create_hw_obj(struct pci_dev *pci, enum CHIPTYP chip_type,
-			    enum CTCARDS model, struct hw **rhw)
+int create_hw_obj(struct pci_dev *pci, enum CHIPTYP chip_type,
+		  enum CTCARDS model, struct hw **rhw)
 {
 	int err;
 
diff --git a/sound/pci/ctxfi/cthw20k1.c b/sound/pci/ctxfi/cthw20k1.c
index 4507f70..6ac40be 100644
--- a/sound/pci/ctxfi/cthw20k1.c
+++ b/sound/pci/ctxfi/cthw20k1.c
@@ -2171,7 +2171,7 @@
 		&container_of(hw, struct hw20k1, hw)->reg_pci_lock, flags);
 }
 
-static struct hw ct20k1_preset __devinitdata = {
+static struct hw ct20k1_preset = {
 	.irq = -1,
 
 	.card_init = hw_card_init,
@@ -2275,7 +2275,7 @@
 	.get_wc = get_wc,
 };
 
-int __devinit create_20k1_hw_obj(struct hw **rhw)
+int create_20k1_hw_obj(struct hw **rhw)
 {
 	struct hw20k1 *hw20k1;
 
diff --git a/sound/pci/ctxfi/cthw20k2.c b/sound/pci/ctxfi/cthw20k2.c
index b9c9349..b143886 100644
--- a/sound/pci/ctxfi/cthw20k2.c
+++ b/sound/pci/ctxfi/cthw20k2.c
@@ -2237,7 +2237,7 @@
 	writel(data, (void *)(hw->mem_base + reg));
 }
 
-static struct hw ct20k2_preset __devinitdata = {
+static struct hw ct20k2_preset = {
 	.irq = -1,
 
 	.card_init = hw_card_init,
@@ -2345,7 +2345,7 @@
 	.get_wc = get_wc,
 };
 
-int __devinit create_20k2_hw_obj(struct hw **rhw)
+int create_20k2_hw_obj(struct hw **rhw)
 {
 	struct hw20k2 *hw20k2;
 
diff --git a/sound/pci/ctxfi/xfi.c b/sound/pci/ctxfi/xfi.c
index 07c07d7..d01ffcb 100644
--- a/sound/pci/ctxfi/xfi.c
+++ b/sound/pci/ctxfi/xfi.c
@@ -56,7 +56,7 @@
 };
 MODULE_DEVICE_TABLE(pci, ct_pci_dev_ids);
 
-static int __devinit
+static int
 ct_card_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
 {
 	static int dev;
@@ -119,7 +119,7 @@
 	return err;
 }
 
-static void __devexit ct_card_remove(struct pci_dev *pci)
+static void ct_card_remove(struct pci_dev *pci)
 {
 	snd_card_free(pci_get_drvdata(pci));
 	pci_set_drvdata(pci, NULL);
@@ -152,7 +152,7 @@
 	.name = KBUILD_MODNAME,
 	.id_table = ct_pci_dev_ids,
 	.probe = ct_card_probe,
-	.remove = __devexit_p(ct_card_remove),
+	.remove = ct_card_remove,
 	.driver = {
 		.pm = CT_CARD_PM_OPS,
 	},
diff --git a/sound/pci/echoaudio/echoaudio.c b/sound/pci/echoaudio/echoaudio.c
index abb0b86..760cbff 100644
--- a/sound/pci/echoaudio/echoaudio.c
+++ b/sound/pci/echoaudio/echoaudio.c
@@ -907,7 +907,7 @@
 
 
 /*<--snd_echo_probe() */
-static int __devinit snd_echo_new_pcm(struct echoaudio *chip)
+static int snd_echo_new_pcm(struct echoaudio *chip)
 {
 	struct snd_pcm *pcm;
 	int err;
@@ -1050,7 +1050,7 @@
 
 #ifdef ECHOCARD_HAS_LINE_OUT_GAIN
 /* On the Mia this one controls the line-out volume */
-static struct snd_kcontrol_new snd_echo_line_output_gain __devinitdata = {
+static struct snd_kcontrol_new snd_echo_line_output_gain = {
 	.name = "Line Playback Volume",
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
@@ -1061,7 +1061,7 @@
 	.tlv = {.p = db_scale_output_gain},
 };
 #else
-static struct snd_kcontrol_new snd_echo_pcm_output_gain __devinitdata = {
+static struct snd_kcontrol_new snd_echo_pcm_output_gain = {
 	.name = "PCM Playback Volume",
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ,
@@ -1131,7 +1131,7 @@
 
 static const DECLARE_TLV_DB_SCALE(db_scale_input_gain, -2500, 50, 0);
 
-static struct snd_kcontrol_new snd_echo_line_input_gain __devinitdata = {
+static struct snd_kcontrol_new snd_echo_line_input_gain = {
 	.name = "Line Capture Volume",
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ,
@@ -1195,7 +1195,7 @@
 	return changed;
 }
 
-static struct snd_kcontrol_new snd_echo_output_nominal_level __devinitdata = {
+static struct snd_kcontrol_new snd_echo_output_nominal_level = {
 	.name = "Line Playback Switch (-10dBV)",
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.info = snd_echo_output_nominal_info,
@@ -1261,7 +1261,7 @@
 	return changed;
 }
 
-static struct snd_kcontrol_new snd_echo_intput_nominal_level __devinitdata = {
+static struct snd_kcontrol_new snd_echo_intput_nominal_level = {
 	.name = "Line Capture Switch (-10dBV)",
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.info = snd_echo_input_nominal_info,
@@ -1327,7 +1327,7 @@
 	return changed;
 }
 
-static struct snd_kcontrol_new snd_echo_monitor_mixer __devinitdata = {
+static struct snd_kcontrol_new snd_echo_monitor_mixer = {
 	.name = "Monitor Mixer Volume",
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ,
@@ -1395,7 +1395,7 @@
 	return changed;
 }
 
-static struct snd_kcontrol_new snd_echo_vmixer __devinitdata = {
+static struct snd_kcontrol_new snd_echo_vmixer = {
 	.name = "VMixer Volume",
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ,
@@ -1490,7 +1490,7 @@
 	return changed;
 }
 
-static struct snd_kcontrol_new snd_echo_digital_mode_switch __devinitdata = {
+static struct snd_kcontrol_new snd_echo_digital_mode_switch = {
 	.name = "Digital mode Switch",
 	.iface = SNDRV_CTL_ELEM_IFACE_CARD,
 	.info = snd_echo_digital_mode_info,
@@ -1547,7 +1547,7 @@
 	return 0;
 }
 
-static struct snd_kcontrol_new snd_echo_spdif_mode_switch __devinitdata = {
+static struct snd_kcontrol_new snd_echo_spdif_mode_switch = {
 	.name = "S/PDIF mode Switch",
 	.iface = SNDRV_CTL_ELEM_IFACE_CARD,
 	.info = snd_echo_spdif_mode_info,
@@ -1626,7 +1626,7 @@
 	return changed;
 }
 
-static struct snd_kcontrol_new snd_echo_clock_source_switch __devinitdata = {
+static struct snd_kcontrol_new snd_echo_clock_source_switch = {
 	.name = "Sample Clock Source",
 	.iface = SNDRV_CTL_ELEM_IFACE_PCM,
 	.info = snd_echo_clock_source_info,
@@ -1669,7 +1669,7 @@
 	return changed;
 }
 
-static struct snd_kcontrol_new snd_echo_phantom_power_switch __devinitdata = {
+static struct snd_kcontrol_new snd_echo_phantom_power_switch = {
 	.name = "Phantom power Switch",
 	.iface = SNDRV_CTL_ELEM_IFACE_CARD,
 	.info = snd_echo_phantom_power_info,
@@ -1712,7 +1712,7 @@
 	return changed;
 }
 
-static struct snd_kcontrol_new snd_echo_automute_switch __devinitdata = {
+static struct snd_kcontrol_new snd_echo_automute_switch = {
 	.name = "Digital Capture Switch (automute)",
 	.iface = SNDRV_CTL_ELEM_IFACE_CARD,
 	.info = snd_echo_automute_info,
@@ -1739,7 +1739,7 @@
 	return 1;
 }
 
-static struct snd_kcontrol_new snd_echo_vumeters_switch __devinitdata = {
+static struct snd_kcontrol_new snd_echo_vumeters_switch = {
 	.name = "VU-meters Switch",
 	.iface = SNDRV_CTL_ELEM_IFACE_CARD,
 	.access = SNDRV_CTL_ELEM_ACCESS_WRITE,
@@ -1780,7 +1780,7 @@
 	return 0;
 }
 
-static struct snd_kcontrol_new snd_echo_vumeters __devinitdata = {
+static struct snd_kcontrol_new snd_echo_vumeters = {
 	.name = "VU-meters",
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.access = SNDRV_CTL_ELEM_ACCESS_READ |
@@ -1836,7 +1836,7 @@
 	return 0;
 }
 
-static struct snd_kcontrol_new snd_echo_channels_info __devinitdata = {
+static struct snd_kcontrol_new snd_echo_channels_info = {
 	.name = "Channels info",
 	.iface = SNDRV_CTL_ELEM_IFACE_HWDEP,
 	.access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
@@ -1940,9 +1940,9 @@
 
 
 /* <--snd_echo_probe() */
-static __devinit int snd_echo_create(struct snd_card *card,
-				     struct pci_dev *pci,
-				     struct echoaudio **rchip)
+static int snd_echo_create(struct snd_card *card,
+			   struct pci_dev *pci,
+			   struct echoaudio **rchip)
 {
 	struct echoaudio *chip;
 	int err;
@@ -2040,8 +2040,8 @@
 
 
 /* constructor */
-static int __devinit snd_echo_probe(struct pci_dev *pci,
-				    const struct pci_device_id *pci_id)
+static int snd_echo_probe(struct pci_dev *pci,
+			  const struct pci_device_id *pci_id)
 {
 	static int dev;
 	struct snd_card *card;
@@ -2316,7 +2316,7 @@
 #endif /* CONFIG_PM_SLEEP */
 
 
-static void __devexit snd_echo_remove(struct pci_dev *pci)
+static void snd_echo_remove(struct pci_dev *pci)
 {
 	struct echoaudio *chip;
 
@@ -2337,7 +2337,7 @@
 	.name = KBUILD_MODNAME,
 	.id_table = snd_echo_ids,
 	.probe = snd_echo_probe,
-	.remove = __devexit_p(snd_echo_remove),
+	.remove = snd_echo_remove,
 	.driver = {
 		.pm = SND_ECHO_PM_OPS,
 	},
diff --git a/sound/pci/echoaudio/echoaudio.h b/sound/pci/echoaudio/echoaudio.h
index e158369..b86b88d 100644
--- a/sound/pci/echoaudio/echoaudio.h
+++ b/sound/pci/echoaudio/echoaudio.h
@@ -475,8 +475,8 @@
 static void snd_echo_midi_output_trigger(
 			struct snd_rawmidi_substream *substream, int up);
 static int midi_service_irq(struct echoaudio *chip);
-static int __devinit snd_echo_midi_create(struct snd_card *card,
-					  struct echoaudio *chip);
+static int snd_echo_midi_create(struct snd_card *card,
+				struct echoaudio *chip);
 #endif
 
 
diff --git a/sound/pci/echoaudio/midi.c b/sound/pci/echoaudio/midi.c
index a953d14..abfd51c 100644
--- a/sound/pci/echoaudio/midi.c
+++ b/sound/pci/echoaudio/midi.c
@@ -307,8 +307,8 @@
 
 
 /* <--snd_echo_probe() */
-static int __devinit snd_echo_midi_create(struct snd_card *card,
-					  struct echoaudio *chip)
+static int snd_echo_midi_create(struct snd_card *card,
+				struct echoaudio *chip)
 {
 	int err;
 
diff --git a/sound/pci/emu10k1/emu10k1.c b/sound/pci/emu10k1/emu10k1.c
index b7c1875..8c5010f 100644
--- a/sound/pci/emu10k1/emu10k1.c
+++ b/sound/pci/emu10k1/emu10k1.c
@@ -99,8 +99,8 @@
 
 MODULE_DEVICE_TABLE(pci, snd_emu10k1_ids);
 
-static int __devinit snd_card_emu10k1_probe(struct pci_dev *pci,
-					    const struct pci_device_id *pci_id)
+static int snd_card_emu10k1_probe(struct pci_dev *pci,
+				  const struct pci_device_id *pci_id)
 {
 	static int dev;
 	struct snd_card *card;
@@ -199,7 +199,7 @@
 	return err;
 }
 
-static void __devexit snd_card_emu10k1_remove(struct pci_dev *pci)
+static void snd_card_emu10k1_remove(struct pci_dev *pci)
 {
 	snd_card_free(pci_get_drvdata(pci));
 	pci_set_drvdata(pci, NULL);
@@ -215,6 +215,8 @@
 
 	snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
 
+	emu->suspend = 1;
+
 	snd_pcm_suspend_all(emu->pcm);
 	snd_pcm_suspend_all(emu->pcm_mic);
 	snd_pcm_suspend_all(emu->pcm_efx);
@@ -260,6 +262,8 @@
 	if (emu->card_capabilities->ca0151_chip)
 		snd_p16v_resume(emu);
 
+	emu->suspend = 0;
+
 	snd_power_change_state(card, SNDRV_CTL_POWER_D0);
 	return 0;
 }
@@ -274,7 +278,7 @@
 	.name = KBUILD_MODNAME,
 	.id_table = snd_emu10k1_ids,
 	.probe = snd_card_emu10k1_probe,
-	.remove = __devexit_p(snd_card_emu10k1_remove),
+	.remove = snd_card_emu10k1_remove,
 	.driver = {
 		.pm = SND_EMU10K1_PM_OPS,
 	},
diff --git a/sound/pci/emu10k1/emu10k1_main.c b/sound/pci/emu10k1/emu10k1_main.c
index c21adb6..a7c296a 100644
--- a/sound/pci/emu10k1/emu10k1_main.c
+++ b/sound/pci/emu10k1/emu10k1_main.c
@@ -657,22 +657,17 @@
 	return 0;
 }
 
-static int snd_emu1010_load_firmware(struct snd_emu10k1 *emu, const char *filename)
+static int snd_emu1010_load_firmware(struct snd_emu10k1 *emu)
 {
-	int err;
 	int n, i;
 	int reg;
 	int value;
 	unsigned int write_post;
 	unsigned long flags;
-	const struct firmware *fw_entry;
+	const struct firmware *fw_entry = emu->firmware;
 
-	err = request_firmware(&fw_entry, filename, &emu->pci->dev);
-	if (err != 0) {
-		snd_printk(KERN_ERR "firmware: %s not found. Err = %d\n", filename, err);
-		return err;
-	}
-	snd_printk(KERN_INFO "firmware size = 0x%zx\n", fw_entry->size);
+	if (!fw_entry)
+		return -EIO;
 
 	/* The FPGA is a Xilinx Spartan IIE XC2S50E */
 	/* GPIO7 -> FPGA PGMN
@@ -705,7 +700,6 @@
 	write_post = inl(emu->port + A_IOCFG);
 	spin_unlock_irqrestore(&emu->emu_lock, flags);
 
-	release_firmware(fw_entry);
 	return 0;
 }
 
@@ -720,6 +714,10 @@
 		msleep_interruptible(1000);
 		if (kthread_should_stop())
 			break;
+#ifdef CONFIG_PM_SLEEP
+		if (emu->suspend)
+			continue;
+#endif
 		snd_emu1010_fpga_read(emu, EMU_HANA_IRQ_STATUS, &tmp); /* IRQ Status */
 		snd_emu1010_fpga_read(emu, EMU_HANA_OPTION_CARDS, &reg); /* OPTIONS: Which cards are attached to the EMU */
 		if (reg & EMU_HANA_OPTION_DOCK_OFFLINE) {
@@ -727,22 +725,9 @@
 			/* Return to Audio Dock programming mode */
 			snd_printk(KERN_INFO "emu1010: Loading Audio Dock Firmware\n");
 			snd_emu1010_fpga_write(emu, EMU_HANA_FPGA_CONFIG, EMU_HANA_FPGA_CONFIG_AUDIODOCK);
-			if (emu->card_capabilities->emu_model ==
-			    EMU_MODEL_EMU1010) {
-				err = snd_emu1010_load_firmware(emu, DOCK_FILENAME);
-				if (err != 0)
-					continue;
-			} else if (emu->card_capabilities->emu_model ==
-				   EMU_MODEL_EMU1010B) {
-				err = snd_emu1010_load_firmware(emu, MICRO_DOCK_FILENAME);
-				if (err != 0)
-					continue;
-			} else if (emu->card_capabilities->emu_model ==
-				   EMU_MODEL_EMU1616) {
-				err = snd_emu1010_load_firmware(emu, MICRO_DOCK_FILENAME);
-				if (err != 0)
-					continue;
-			}
+			err = snd_emu1010_load_firmware(emu);
+			if (err != 0)
+				continue;
 
 			snd_emu1010_fpga_write(emu, EMU_HANA_FPGA_CONFIG, 0);
 			snd_emu1010_fpga_read(emu, EMU_HANA_IRQ_STATUS, &reg);
@@ -807,7 +792,6 @@
 	unsigned int i;
 	u32 tmp, tmp2, reg;
 	int err;
-	const char *filename = NULL;
 
 	snd_printk(KERN_INFO "emu1010: Special config.\n");
 	/* AC97 2.1, Any 16Meg of 4Gig address, Auto-Mute, EMU32 Slave,
@@ -849,31 +833,33 @@
 		return -ENODEV;
 	}
 	snd_printk(KERN_INFO "emu1010: EMU_HANA_ID = 0x%x\n", reg);
-	switch (emu->card_capabilities->emu_model) {
-	case EMU_MODEL_EMU1010:
-		filename = HANA_FILENAME;
-		break;
-	case EMU_MODEL_EMU1010B:
-		filename = EMU1010B_FILENAME;
-		break;
-	case EMU_MODEL_EMU1616:
-		filename = EMU1010_NOTEBOOK_FILENAME;
-		break;
-	case EMU_MODEL_EMU0404:
-		filename = EMU0404_FILENAME;
-		break;
-	default:
-		filename = NULL;
-		return -ENODEV;
-		break;
-	}
-	snd_printk(KERN_INFO "emu1010: filename %s testing\n", filename);
-	err = snd_emu1010_load_firmware(emu, filename);
-	if (err != 0) {
-		snd_printk(
-			KERN_INFO "emu1010: Loading Firmware file %s failed\n",
-			filename);
-		return err;
+
+	if (!emu->firmware) {
+		const char *filename;
+		switch (emu->card_capabilities->emu_model) {
+		case EMU_MODEL_EMU1010:
+			filename = HANA_FILENAME;
+			break;
+		case EMU_MODEL_EMU1010B:
+			filename = EMU1010B_FILENAME;
+			break;
+		case EMU_MODEL_EMU1616:
+			filename = EMU1010_NOTEBOOK_FILENAME;
+			break;
+		case EMU_MODEL_EMU0404:
+			filename = EMU0404_FILENAME;
+			break;
+		default:
+			return -ENODEV;
+		}
+
+		err = request_firmware(&emu->firmware, filename, &emu->pci->dev);
+		if (err != 0) {
+			snd_printk(KERN_ERR "emu1010: firmware: %s not found. Err = %d\n", filename, err);
+			return err;
+		}
+		snd_printk(KERN_INFO "emu1010: firmware file = %s, size = 0x%zx\n",
+			   filename, emu->firmware->size);
 	}
 
 	/* ID, should read & 0x7f = 0x55 when FPGA programmed. */
@@ -1259,6 +1245,8 @@
 	}
 	if (emu->emu1010.firmware_thread)
 		kthread_stop(emu->emu1010.firmware_thread);
+	if (emu->firmware)
+		release_firmware(emu->firmware);
 	if (emu->irq >= 0)
 		free_irq(emu->irq, emu);
 	/* remove reserved page */
@@ -1738,7 +1726,7 @@
 	{ } /* terminator */
 };
 
-int __devinit snd_emu10k1_create(struct snd_card *card,
+int snd_emu10k1_create(struct snd_card *card,
 		       struct pci_dev *pci,
 		       unsigned short extin_mask,
 		       unsigned short extout_mask,
@@ -2025,7 +2013,7 @@
 	0xff /* end */
 };
 
-static int __devinit alloc_pm_buffer(struct snd_emu10k1 *emu)
+static int alloc_pm_buffer(struct snd_emu10k1 *emu)
 {
 	int size;
 
diff --git a/sound/pci/emu10k1/emu10k1_patch.c b/sound/pci/emu10k1/emu10k1_patch.c
index e10f027..662a458 100644
--- a/sound/pci/emu10k1/emu10k1_patch.c
+++ b/sound/pci/emu10k1/emu10k1_patch.c
@@ -123,7 +123,7 @@
 	offset += size;
 	data += size;
 
-#if 0 /* not suppported yet */
+#if 0 /* not supported yet */
 	/* handle reverse (or bidirectional) loop */
 	if (sp->v.mode_flags & (SNDRV_SFNT_SAMPLE_BIDIR_LOOP|SNDRV_SFNT_SAMPLE_REVERSE_LOOP)) {
 		/* copy loop in reverse */
diff --git a/sound/pci/emu10k1/emu10k1x.c b/sound/pci/emu10k1/emu10k1x.c
index 556fd6f..cdff11d 100644
--- a/sound/pci/emu10k1/emu10k1x.c
+++ b/sound/pci/emu10k1/emu10k1x.c
@@ -842,7 +842,7 @@
 	{ }
 };
 
-static int __devinit snd_emu10k1x_pcm(struct emu10k1x *emu, int device, struct snd_pcm **rpcm)
+static int snd_emu10k1x_pcm(struct emu10k1x *emu, int device, struct snd_pcm **rpcm)
 {
 	struct snd_pcm *pcm;
 	const struct snd_pcm_chmap_elem *map = NULL;
@@ -902,9 +902,9 @@
 	return 0;
 }
 
-static int __devinit snd_emu10k1x_create(struct snd_card *card,
-					 struct pci_dev *pci,
-					 struct emu10k1x **rchip)
+static int snd_emu10k1x_create(struct snd_card *card,
+			       struct pci_dev *pci,
+			       struct emu10k1x **rchip)
 {
 	struct emu10k1x *chip;
 	int err;
@@ -1066,7 +1066,7 @@
 	}
 }
 
-static int __devinit snd_emu10k1x_proc_init(struct emu10k1x * emu)
+static int snd_emu10k1x_proc_init(struct emu10k1x *emu)
 {
 	struct snd_info_entry *entry;
 	
@@ -1115,7 +1115,7 @@
 	return change;
 }
 
-static struct snd_kcontrol_new snd_emu10k1x_shared_spdif __devinitdata =
+static struct snd_kcontrol_new snd_emu10k1x_shared_spdif =
 {
 	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name =		"Analog/Digital Output Jack",
@@ -1194,7 +1194,7 @@
 	.put =          snd_emu10k1x_spdif_put
 };
 
-static int __devinit snd_emu10k1x_mixer(struct emu10k1x *emu)
+static int snd_emu10k1x_mixer(struct emu10k1x *emu)
 {
 	int err;
 	struct snd_kcontrol *kctl;
@@ -1507,8 +1507,9 @@
 	midi->rmidi = NULL;
 }
 
-static int __devinit emu10k1x_midi_init(struct emu10k1x *emu,
-					struct emu10k1x_midi *midi, int device, char *name)
+static int emu10k1x_midi_init(struct emu10k1x *emu,
+			      struct emu10k1x_midi *midi, int device,
+			      char *name)
 {
 	struct snd_rawmidi *rmidi;
 	int err;
@@ -1531,7 +1532,7 @@
 	return 0;
 }
 
-static int __devinit snd_emu10k1x_midi(struct emu10k1x *emu)
+static int snd_emu10k1x_midi(struct emu10k1x *emu)
 {
 	struct emu10k1x_midi *midi = &emu->midi;
 	int err;
@@ -1548,8 +1549,8 @@
 	return 0;
 }
 
-static int __devinit snd_emu10k1x_probe(struct pci_dev *pci,
-					const struct pci_device_id *pci_id)
+static int snd_emu10k1x_probe(struct pci_dev *pci,
+			      const struct pci_device_id *pci_id)
 {
 	static int dev;
 	struct snd_card *card;
@@ -1619,7 +1620,7 @@
 	return 0;
 }
 
-static void __devexit snd_emu10k1x_remove(struct pci_dev *pci)
+static void snd_emu10k1x_remove(struct pci_dev *pci)
 {
 	snd_card_free(pci_get_drvdata(pci));
 	pci_set_drvdata(pci, NULL);
@@ -1637,7 +1638,7 @@
 	.name = KBUILD_MODNAME,
 	.id_table = snd_emu10k1x_ids,
 	.probe = snd_emu10k1x_probe,
-	.remove = __devexit_p(snd_emu10k1x_remove),
+	.remove = snd_emu10k1x_remove,
 };
 
 module_pci_driver(emu10k1x_driver);
diff --git a/sound/pci/emu10k1/emufx.c b/sound/pci/emu10k1/emufx.c
index 5241995..0275209 100644
--- a/sound/pci/emu10k1/emufx.c
+++ b/sound/pci/emu10k1/emufx.c
@@ -1073,7 +1073,7 @@
 #define SND_EMU10K1_PLAYBACK_CHANNELS	8
 #define SND_EMU10K1_CAPTURE_CHANNELS	4
 
-static void __devinit
+static void
 snd_emu10k1_init_mono_control(struct snd_emu10k1_fx8010_control_gpr *ctl,
 			      const char *name, int gpr, int defval)
 {
@@ -1094,7 +1094,7 @@
 	}
 }
 
-static void __devinit
+static void
 snd_emu10k1_init_stereo_control(struct snd_emu10k1_fx8010_control_gpr *ctl,
 				const char *name, int gpr, int defval)
 {
@@ -1116,7 +1116,7 @@
 	}
 }
 
-static void __devinit
+static void
 snd_emu10k1_init_mono_onoff_control(struct snd_emu10k1_fx8010_control_gpr *ctl,
 				    const char *name, int gpr, int defval)
 {
@@ -1129,7 +1129,7 @@
 	ctl->translation = EMU10K1_GPR_TRANSLATION_ONOFF;
 }
 
-static void __devinit
+static void
 snd_emu10k1_init_stereo_onoff_control(struct snd_emu10k1_fx8010_control_gpr *ctl,
 				      const char *name, int gpr, int defval)
 {
@@ -1168,7 +1168,7 @@
  * initial DSP configuration for Audigy
  */
 
-static int __devinit _snd_emu10k1_audigy_init_efx(struct snd_emu10k1 *emu)
+static int _snd_emu10k1_audigy_init_efx(struct snd_emu10k1 *emu)
 {
 	int err, i, z, gpr, nctl;
 	int bit_shifter16;
@@ -1757,14 +1757,14 @@
 
 /* when volume = max, then copy only to avoid volume modification */
 /* with iMAC0 (negative values) */
-static void __devinit _volume(struct snd_emu10k1_fx8010_code *icode, u32 *ptr, u32 dst, u32 src, u32 vol)
+static void _volume(struct snd_emu10k1_fx8010_code *icode, u32 *ptr, u32 dst, u32 src, u32 vol)
 {
 	OP(icode, ptr, iMAC0, dst, C_00000000, src, vol);
 	OP(icode, ptr, iANDXOR, C_00000000, vol, C_ffffffff, C_7fffffff);
 	OP(icode, ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000001);
 	OP(icode, ptr, iACC3, dst, src, C_00000000, C_00000000);
 }
-static void __devinit _volume_add(struct snd_emu10k1_fx8010_code *icode, u32 *ptr, u32 dst, u32 src, u32 vol)
+static void _volume_add(struct snd_emu10k1_fx8010_code *icode, u32 *ptr, u32 dst, u32 src, u32 vol)
 {
 	OP(icode, ptr, iANDXOR, C_00000000, vol, C_ffffffff, C_7fffffff);
 	OP(icode, ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000002);
@@ -1772,7 +1772,7 @@
 	OP(icode, ptr, iSKIP, C_00000000, C_7fffffff, C_7fffffff, C_00000001);
 	OP(icode, ptr, iMAC0, dst, dst, src, vol);
 }
-static void __devinit _volume_out(struct snd_emu10k1_fx8010_code *icode, u32 *ptr, u32 dst, u32 src, u32 vol)
+static void _volume_out(struct snd_emu10k1_fx8010_code *icode, u32 *ptr, u32 dst, u32 src, u32 vol)
 {
 	OP(icode, ptr, iANDXOR, C_00000000, vol, C_ffffffff, C_7fffffff);
 	OP(icode, ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000002);
@@ -1803,7 +1803,7 @@
 		_SWITCH_NEG(icode, ptr, GPR(dst), GPR(src))
 
 
-static int __devinit _snd_emu10k1_init_efx(struct snd_emu10k1 *emu)
+static int _snd_emu10k1_init_efx(struct snd_emu10k1 *emu)
 {
 	int err, i, z, gpr, tmp, playback, capture;
 	u32 ptr;
@@ -2373,7 +2373,7 @@
 	return err;
 }
 
-int __devinit snd_emu10k1_init_efx(struct snd_emu10k1 *emu)
+int snd_emu10k1_init_efx(struct snd_emu10k1 *emu)
 {
 	spin_lock_init(&emu->fx8010.irq_lock);
 	INIT_LIST_HEAD(&emu->fx8010.gpr_ctl);
@@ -2626,7 +2626,8 @@
 	return 0;
 }
 
-int __devinit snd_emu10k1_fx8010_new(struct snd_emu10k1 *emu, int device, struct snd_hwdep ** rhwdep)
+int snd_emu10k1_fx8010_new(struct snd_emu10k1 *emu, int device,
+			   struct snd_hwdep **rhwdep)
 {
 	struct snd_hwdep *hw;
 	int err;
@@ -2647,7 +2648,7 @@
 }
 
 #ifdef CONFIG_PM_SLEEP
-int __devinit snd_emu10k1_efx_alloc_pm_buffer(struct snd_emu10k1 *emu)
+int snd_emu10k1_efx_alloc_pm_buffer(struct snd_emu10k1 *emu)
 {
 	int len;
 
diff --git a/sound/pci/emu10k1/emumixer.c b/sound/pci/emu10k1/emumixer.c
index 9d890a5..f6c3da0 100644
--- a/sound/pci/emu10k1/emumixer.c
+++ b/sound/pci/emu10k1/emumixer.c
@@ -510,7 +510,7 @@
 	.private_value = chid					\
 }
 
-static struct snd_kcontrol_new snd_emu1010_output_enum_ctls[] __devinitdata = {
+static struct snd_kcontrol_new snd_emu1010_output_enum_ctls[] = {
 	EMU1010_SOURCE_OUTPUT("Dock DAC1 Left Playback Enum", 0),
 	EMU1010_SOURCE_OUTPUT("Dock DAC1 Right Playback Enum", 1),
 	EMU1010_SOURCE_OUTPUT("Dock DAC2 Left Playback Enum", 2),
@@ -539,7 +539,7 @@
 
 
 /* 1616(m) cardbus */
-static struct snd_kcontrol_new snd_emu1616_output_enum_ctls[] __devinitdata = {
+static struct snd_kcontrol_new snd_emu1616_output_enum_ctls[] = {
 	EMU1010_SOURCE_OUTPUT("Dock DAC1 Left Playback Enum", 0),
 	EMU1010_SOURCE_OUTPUT("Dock DAC1 Right Playback Enum", 1),
 	EMU1010_SOURCE_OUTPUT("Dock DAC2 Left Playback Enum", 2),
@@ -571,7 +571,7 @@
 	.private_value = chid					\
 }
 
-static struct snd_kcontrol_new snd_emu1010_input_enum_ctls[] __devinitdata = {
+static struct snd_kcontrol_new snd_emu1010_input_enum_ctls[] = {
 	EMU1010_SOURCE_INPUT("DSP 0 Capture Enum", 0),
 	EMU1010_SOURCE_INPUT("DSP 1 Capture Enum", 1),
 	EMU1010_SOURCE_INPUT("DSP 2 Capture Enum", 2),
@@ -639,7 +639,7 @@
 	.private_value = chid					\
 }
 
-static struct snd_kcontrol_new snd_emu1010_adc_pads[] __devinitdata = {
+static struct snd_kcontrol_new snd_emu1010_adc_pads[] = {
 	EMU1010_ADC_PADS("ADC1 14dB PAD Audio Dock Capture Switch", EMU_HANA_DOCK_ADC_PAD1),
 	EMU1010_ADC_PADS("ADC2 14dB PAD Audio Dock Capture Switch", EMU_HANA_DOCK_ADC_PAD2),
 	EMU1010_ADC_PADS("ADC3 14dB PAD Audio Dock Capture Switch", EMU_HANA_DOCK_ADC_PAD3),
@@ -687,7 +687,7 @@
 	.private_value = chid					\
 }
 
-static struct snd_kcontrol_new snd_emu1010_dac_pads[] __devinitdata = {
+static struct snd_kcontrol_new snd_emu1010_dac_pads[] = {
 	EMU1010_DAC_PADS("DAC1 Audio Dock 14dB PAD Playback Switch", EMU_HANA_DOCK_DAC_PAD1),
 	EMU1010_DAC_PADS("DAC2 Audio Dock 14dB PAD Playback Switch", EMU_HANA_DOCK_DAC_PAD2),
 	EMU1010_DAC_PADS("DAC3 Audio Dock 14dB PAD Playback Switch", EMU_HANA_DOCK_DAC_PAD3),
@@ -989,7 +989,7 @@
 }
 
 
-static struct snd_kcontrol_new snd_audigy_i2c_volume_ctls[] __devinitdata = {
+static struct snd_kcontrol_new snd_audigy_i2c_volume_ctls[] = {
 	I2C_VOLUME("Mic Capture Volume", 0),
 	I2C_VOLUME("Line Capture Volume", 0)
 };
@@ -1621,7 +1621,7 @@
 	return change;
 }
 
-static struct snd_kcontrol_new snd_emu10k1_shared_spdif __devinitdata =
+static struct snd_kcontrol_new snd_emu10k1_shared_spdif =
 {
 	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name =		"SB Live Analog/Digital Output Jack",
@@ -1630,7 +1630,7 @@
 	.put =		snd_emu10k1_shared_spdif_put
 };
 
-static struct snd_kcontrol_new snd_audigy_shared_spdif __devinitdata =
+static struct snd_kcontrol_new snd_audigy_shared_spdif =
 {
 	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name =		"Audigy Analog/Digital Output Jack",
@@ -1668,7 +1668,7 @@
 	return snd_ac97_update(emu->ac97, AC97_REC_GAIN, val);
 }
 
-static struct snd_kcontrol_new snd_audigy_capture_boost __devinitdata =
+static struct snd_kcontrol_new snd_audigy_capture_boost =
 {
 	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name =		"Analog Capture Boost",
@@ -1716,8 +1716,8 @@
 	return -ENOENT;
 }
 
-int __devinit snd_emu10k1_mixer(struct snd_emu10k1 *emu,
-				int pcm_device, int multi_device)
+int snd_emu10k1_mixer(struct snd_emu10k1 *emu,
+		      int pcm_device, int multi_device)
 {
 	int err, pcm;
 	struct snd_kcontrol *kctl;
diff --git a/sound/pci/emu10k1/emumpu401.c b/sound/pci/emu10k1/emumpu401.c
index bab5648..1ec9124 100644
--- a/sound/pci/emu10k1/emumpu401.c
+++ b/sound/pci/emu10k1/emumpu401.c
@@ -326,7 +326,7 @@
 	midi->rmidi = NULL;
 }
 
-static int __devinit emu10k1_midi_init(struct snd_emu10k1 *emu, struct snd_emu10k1_midi *midi, int device, char *name)
+static int emu10k1_midi_init(struct snd_emu10k1 *emu, struct snd_emu10k1_midi *midi, int device, char *name)
 {
 	struct snd_rawmidi *rmidi;
 	int err;
@@ -349,7 +349,7 @@
 	return 0;
 }
 
-int __devinit snd_emu10k1_midi(struct snd_emu10k1 *emu)
+int snd_emu10k1_midi(struct snd_emu10k1 *emu)
 {
 	struct snd_emu10k1_midi *midi = &emu->midi;
 	int err;
@@ -366,7 +366,7 @@
 	return 0;
 }
 
-int __devinit snd_emu10k1_audigy_midi(struct snd_emu10k1 *emu)
+int snd_emu10k1_audigy_midi(struct snd_emu10k1 *emu)
 {
 	struct snd_emu10k1_midi *midi;
 	int err;
diff --git a/sound/pci/emu10k1/emupcm.c b/sound/pci/emu10k1/emupcm.c
index 0e6664f..748a286 100644
--- a/sound/pci/emu10k1/emupcm.c
+++ b/sound/pci/emu10k1/emupcm.c
@@ -1391,7 +1391,7 @@
 	.page =			snd_pcm_sgbuf_ops_page,
 };
 
-int __devinit snd_emu10k1_pcm(struct snd_emu10k1 * emu, int device, struct snd_pcm ** rpcm)
+int snd_emu10k1_pcm(struct snd_emu10k1 *emu, int device, struct snd_pcm **rpcm)
 {
 	struct snd_pcm *pcm;
 	struct snd_pcm_substream *substream;
@@ -1426,7 +1426,8 @@
 	return 0;
 }
 
-int __devinit snd_emu10k1_pcm_multi(struct snd_emu10k1 * emu, int device, struct snd_pcm ** rpcm)
+int snd_emu10k1_pcm_multi(struct snd_emu10k1 *emu, int device,
+			  struct snd_pcm **rpcm)
 {
 	struct snd_pcm *pcm;
 	struct snd_pcm_substream *substream;
@@ -1469,7 +1470,8 @@
 	.pointer =		snd_emu10k1_capture_pointer,
 };
 
-int __devinit snd_emu10k1_pcm_mic(struct snd_emu10k1 * emu, int device, struct snd_pcm ** rpcm)
+int snd_emu10k1_pcm_mic(struct snd_emu10k1 *emu, int device,
+			struct snd_pcm **rpcm)
 {
 	struct snd_pcm *pcm;
 	int err;
@@ -1810,7 +1812,8 @@
 	.ack =			snd_emu10k1_fx8010_playback_transfer,
 };
 
-int __devinit snd_emu10k1_pcm_efx(struct snd_emu10k1 * emu, int device, struct snd_pcm ** rpcm)
+int snd_emu10k1_pcm_efx(struct snd_emu10k1 *emu, int device,
+			struct snd_pcm **rpcm)
 {
 	struct snd_pcm *pcm;
 	struct snd_kcontrol *kctl;
diff --git a/sound/pci/emu10k1/emuproc.c b/sound/pci/emu10k1/emuproc.c
index bc38dd4..2ca9f2e 100644
--- a/sound/pci/emu10k1/emuproc.c
+++ b/sound/pci/emu10k1/emuproc.c
@@ -577,7 +577,7 @@
 	.read = snd_emu10k1_fx8010_read,
 };
 
-int __devinit snd_emu10k1_proc_init(struct snd_emu10k1 * emu)
+int snd_emu10k1_proc_init(struct snd_emu10k1 *emu)
 {
 	struct snd_info_entry *entry;
 #ifdef CONFIG_SND_DEBUG
diff --git a/sound/pci/emu10k1/p16v.c b/sound/pci/emu10k1/p16v.c
index 88cec6b..7e2025c 100644
--- a/sound/pci/emu10k1/p16v.c
+++ b/sound/pci/emu10k1/p16v.c
@@ -637,7 +637,7 @@
 	return 0;
 }
 
-int __devinit snd_p16v_pcm(struct snd_emu10k1 *emu, int device, struct snd_pcm **rpcm)
+int snd_p16v_pcm(struct snd_emu10k1 *emu, int device, struct snd_pcm **rpcm)
 {
 	struct snd_pcm *pcm;
 	struct snd_pcm_substream *substream;
@@ -854,7 +854,7 @@
 	.private_value = ((xreg) | ((xhl) << 8)) \
 }
 
-static struct snd_kcontrol_new p16v_mixer_controls[] __devinitdata = {
+static struct snd_kcontrol_new p16v_mixer_controls[] = {
 	P16V_VOL("HD Analog Front Playback Volume", PLAYBACK_VOLUME_MIXER9, 0),
 	P16V_VOL("HD Analog Rear Playback Volume", PLAYBACK_VOLUME_MIXER10, 1),
 	P16V_VOL("HD Analog Center/LFE Playback Volume", PLAYBACK_VOLUME_MIXER9, 1),
@@ -880,7 +880,7 @@
 };
 
 
-int __devinit snd_p16v_mixer(struct snd_emu10k1 *emu)
+int snd_p16v_mixer(struct snd_emu10k1 *emu)
 {
 	int i, err;
         struct snd_card *card = emu->card;
@@ -897,7 +897,7 @@
 
 #define NUM_CHS	1	/* up to 4, but only first channel is used */
 
-int __devinit snd_p16v_alloc_pm_buffer(struct snd_emu10k1 *emu)
+int snd_p16v_alloc_pm_buffer(struct snd_emu10k1 *emu)
 {
 	emu->p16v_saved = vmalloc(NUM_CHS * 4 * 0x80);
 	if (! emu->p16v_saved)
diff --git a/sound/pci/emu10k1/timer.c b/sound/pci/emu10k1/timer.c
index 72321e9..b69a7f8 100644
--- a/sound/pci/emu10k1/timer.c
+++ b/sound/pci/emu10k1/timer.c
@@ -75,7 +75,7 @@
 	.precise_resolution = snd_emu10k1_timer_precise_resolution,
 };
 
-int __devinit snd_emu10k1_timer(struct snd_emu10k1 *emu, int device)
+int snd_emu10k1_timer(struct snd_emu10k1 *emu, int device)
 {
 	struct snd_timer *timer = NULL;
 	struct snd_timer_id tid;
diff --git a/sound/pci/ens1370.c b/sound/pci/ens1370.c
index 5674cc3..db2dc83 100644
--- a/sound/pci/ens1370.c
+++ b/sound/pci/ens1370.c
@@ -1268,8 +1268,8 @@
 	{ }
 };
 
-static int __devinit snd_ensoniq_pcm(struct ensoniq * ensoniq, int device,
-				     struct snd_pcm ** rpcm)
+static int snd_ensoniq_pcm(struct ensoniq *ensoniq, int device,
+			   struct snd_pcm **rpcm)
 {
 	struct snd_pcm *pcm;
 	int err;
@@ -1310,8 +1310,8 @@
 	return 0;
 }
 
-static int __devinit snd_ensoniq_pcm2(struct ensoniq * ensoniq, int device,
-				      struct snd_pcm ** rpcm)
+static int snd_ensoniq_pcm2(struct ensoniq *ensoniq, int device,
+			    struct snd_pcm **rpcm)
 {
 	struct snd_pcm *pcm;
 	int err;
@@ -1484,7 +1484,7 @@
 
 
 /* spdif controls */
-static struct snd_kcontrol_new snd_es1371_mixer_spdif[] __devinitdata = {
+static struct snd_kcontrol_new snd_es1371_mixer_spdif[] = {
 	ES1371_SPDIF(SNDRV_CTL_NAME_IEC958("",PLAYBACK,SWITCH)),
 	{
 		.iface =	SNDRV_CTL_ELEM_IFACE_PCM,
@@ -1546,7 +1546,7 @@
 	return change;
 }
 
-static struct snd_kcontrol_new snd_ens1373_rear __devinitdata =
+static struct snd_kcontrol_new snd_ens1373_rear =
 {
 	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name =		"AC97 2ch->4ch Copy Switch",
@@ -1591,7 +1591,7 @@
 	return changed;
 }
 
-static struct snd_kcontrol_new snd_ens1373_line __devinitdata =
+static struct snd_kcontrol_new snd_ens1373_line =
 {
 	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name =		"Line In->Rear Out Switch",
@@ -1625,7 +1625,7 @@
 	return 0;
 }
 
-static struct es1371_quirk es1371_spdif_present[] __devinitdata = {
+static struct es1371_quirk es1371_spdif_present[] = {
 	{ .vid = PCI_VENDOR_ID_ENSONIQ, .did = PCI_DEVICE_ID_ENSONIQ_CT5880, .rev = CT5880REV_CT5880_C },
 	{ .vid = PCI_VENDOR_ID_ENSONIQ, .did = PCI_DEVICE_ID_ENSONIQ_CT5880, .rev = CT5880REV_CT5880_D },
 	{ .vid = PCI_VENDOR_ID_ENSONIQ, .did = PCI_DEVICE_ID_ENSONIQ_CT5880, .rev = CT5880REV_CT5880_E },
@@ -1634,14 +1634,14 @@
 	{ .vid = PCI_ANY_ID, .did = PCI_ANY_ID }
 };
 
-static struct snd_pci_quirk ens1373_line_quirk[] __devinitdata = {
+static struct snd_pci_quirk ens1373_line_quirk[] = {
 	SND_PCI_QUIRK_ID(0x1274, 0x2000), /* GA-7DXR */
 	SND_PCI_QUIRK_ID(0x1458, 0xa000), /* GA-8IEXP */
 	{ } /* end */
 };
 
-static int __devinit snd_ensoniq_1371_mixer(struct ensoniq *ensoniq,
-					    int has_spdif, int has_line)
+static int snd_ensoniq_1371_mixer(struct ensoniq *ensoniq,
+				  int has_spdif, int has_line)
 {
 	struct snd_card *card = ensoniq->card;
 	struct snd_ac97_bus *pbus;
@@ -1749,7 +1749,7 @@
  * ENS1370 mixer
  */
 
-static struct snd_kcontrol_new snd_es1370_controls[2] __devinitdata = {
+static struct snd_kcontrol_new snd_es1370_controls[2] = {
 ENSONIQ_CONTROL("PCM 0 Output also on Line-In Jack", ES_1370_XCTL0),
 ENSONIQ_CONTROL("Mic +5V bias", ES_1370_XCTL1)
 };
@@ -1762,7 +1762,7 @@
 	ensoniq->u.es1370.ak4531 = NULL;
 }
 
-static int __devinit snd_ensoniq_1370_mixer(struct ensoniq * ensoniq)
+static int snd_ensoniq_1370_mixer(struct ensoniq *ensoniq)
 {
 	struct snd_card *card = ensoniq->card;
 	struct snd_ak4531 ak4531;
@@ -1796,7 +1796,7 @@
 #ifdef SUPPORT_JOYSTICK
 
 #ifdef CHIP1371
-static int __devinit snd_ensoniq_get_joystick_port(int dev)
+static int snd_ensoniq_get_joystick_port(int dev)
 {
 	switch (joystick_port[dev]) {
 	case 0: /* disabled */
@@ -1819,7 +1819,7 @@
 }
 #endif
 
-static int __devinit snd_ensoniq_create_gameport(struct ensoniq *ensoniq, int dev)
+static int snd_ensoniq_create_gameport(struct ensoniq *ensoniq, int dev)
 {
 	struct gameport *gp;
 	int io_port;
@@ -1913,7 +1913,7 @@
 #endif
 }
 
-static void __devinit snd_ensoniq_proc_init(struct ensoniq * ensoniq)
+static void snd_ensoniq_proc_init(struct ensoniq *ensoniq)
 {
 	struct snd_info_entry *entry;
 
@@ -1960,7 +1960,7 @@
 }
 
 #ifdef CHIP1371
-static struct snd_pci_quirk es1371_amplifier_hack[] __devinitdata = {
+static struct snd_pci_quirk es1371_amplifier_hack[] = {
 	SND_PCI_QUIRK_ID(0x107b, 0x2150),	/* Gateway Solo 2150 */
 	SND_PCI_QUIRK_ID(0x13bd, 0x100c),	/* EV1938 on Mebius PC-MJ100V */
 	SND_PCI_QUIRK_ID(0x1102, 0x5938),	/* Targa Xtender300 */
@@ -2106,9 +2106,9 @@
 #define SND_ENSONIQ_PM_OPS	NULL
 #endif /* CONFIG_PM_SLEEP */
 
-static int __devinit snd_ensoniq_create(struct snd_card *card,
-				     struct pci_dev *pci,
-				     struct ensoniq ** rensoniq)
+static int snd_ensoniq_create(struct snd_card *card,
+			      struct pci_dev *pci,
+			      struct ensoniq **rensoniq)
 {
 	struct ensoniq *ensoniq;
 	int err;
@@ -2361,8 +2361,8 @@
 	.trigger =	snd_ensoniq_midi_input_trigger,
 };
 
-static int __devinit snd_ensoniq_midi(struct ensoniq * ensoniq, int device,
-				      struct snd_rawmidi **rrawmidi)
+static int snd_ensoniq_midi(struct ensoniq *ensoniq, int device,
+			    struct snd_rawmidi **rrawmidi)
 {
 	struct snd_rawmidi *rmidi;
 	int err;
@@ -2422,8 +2422,8 @@
 	return IRQ_HANDLED;
 }
 
-static int __devinit snd_audiopci_probe(struct pci_dev *pci,
-					const struct pci_device_id *pci_id)
+static int snd_audiopci_probe(struct pci_dev *pci,
+			      const struct pci_device_id *pci_id)
 {
 	static int dev;
 	struct snd_card *card;
@@ -2494,7 +2494,7 @@
 	return 0;
 }
 
-static void __devexit snd_audiopci_remove(struct pci_dev *pci)
+static void snd_audiopci_remove(struct pci_dev *pci)
 {
 	snd_card_free(pci_get_drvdata(pci));
 	pci_set_drvdata(pci, NULL);
@@ -2504,7 +2504,7 @@
 	.name = KBUILD_MODNAME,
 	.id_table = snd_audiopci_ids,
 	.probe = snd_audiopci_probe,
-	.remove = __devexit_p(snd_audiopci_remove),
+	.remove = snd_audiopci_remove,
 	.driver = {
 		.pm = SND_ENSONIQ_PM_OPS,
 	},
diff --git a/sound/pci/es1938.c b/sound/pci/es1938.c
index 394c5d4..8423403 100644
--- a/sound/pci/es1938.c
+++ b/sound/pci/es1938.c
@@ -1027,7 +1027,7 @@
 	.copy =		snd_es1938_capture_copy,
 };
 
-static int __devinit snd_es1938_new_pcm(struct es1938 *chip, int device)
+static int snd_es1938_new_pcm(struct es1938 *chip, int device)
 {
 	struct snd_pcm *pcm;
 	int err;
@@ -1539,7 +1539,7 @@
 #endif /* CONFIG_PM_SLEEP */
 
 #ifdef SUPPORT_JOYSTICK
-static int __devinit snd_es1938_create_gameport(struct es1938 *chip)
+static int snd_es1938_create_gameport(struct es1938 *chip)
 {
 	struct gameport *gp;
 
@@ -1594,9 +1594,9 @@
 	return snd_es1938_free(chip);
 }
 
-static int __devinit snd_es1938_create(struct snd_card *card,
-				    struct pci_dev * pci,
-				    struct es1938 ** rchip)
+static int snd_es1938_create(struct snd_card *card,
+			     struct pci_dev *pci,
+			     struct es1938 **rchip)
 {
 	struct es1938 *chip;
 	int err;
@@ -1754,7 +1754,7 @@
 
 #define ES1938_DMA_SIZE 64
 
-static int __devinit snd_es1938_mixer(struct es1938 *chip)
+static int snd_es1938_mixer(struct es1938 *chip)
 {
 	struct snd_card *card;
 	unsigned int idx;
@@ -1792,8 +1792,8 @@
 }
        
 
-static int __devinit snd_es1938_probe(struct pci_dev *pci,
-				      const struct pci_device_id *pci_id)
+static int snd_es1938_probe(struct pci_dev *pci,
+			    const struct pci_device_id *pci_id)
 {
 	static int dev;
 	struct snd_card *card;
@@ -1878,7 +1878,7 @@
 	return 0;
 }
 
-static void __devexit snd_es1938_remove(struct pci_dev *pci)
+static void snd_es1938_remove(struct pci_dev *pci)
 {
 	snd_card_free(pci_get_drvdata(pci));
 	pci_set_drvdata(pci, NULL);
@@ -1888,7 +1888,7 @@
 	.name = KBUILD_MODNAME,
 	.id_table = snd_es1938_ids,
 	.probe = snd_es1938_probe,
-	.remove = __devexit_p(snd_es1938_remove),
+	.remove = snd_es1938_remove,
 	.driver = {
 		.pm = ES1938_PM_OPS,
 	},
diff --git a/sound/pci/es1968.c b/sound/pci/es1968.c
index 7266020..a1f32b5 100644
--- a/sound/pci/es1968.c
+++ b/sound/pci/es1968.c
@@ -1429,7 +1429,7 @@
 	}
 }
 
-static int __devinit
+static int
 snd_es1968_init_dmabuf(struct es1968 *chip)
 {
 	int err;
@@ -1704,7 +1704,7 @@
  */
 #define CLOCK_MEASURE_BUFSIZE	16768	/* enough large for a single shot */
 
-static void __devinit es1968_measure_clock(struct es1968 *chip)
+static void es1968_measure_clock(struct es1968 *chip)
 {
 	int i, apu;
 	unsigned int pa, offset, t;
@@ -1806,7 +1806,7 @@
 	esm->pcm = NULL;
 }
 
-static int __devinit
+static int
 snd_es1968_pcm(struct es1968 *chip, int device)
 {
 	struct snd_pcm *pcm;
@@ -2016,7 +2016,7 @@
  *  Mixer stuff
  */
 
-static int __devinit
+static int
 snd_es1968_mixer(struct es1968 *chip)
 {
 	struct snd_ac97_bus *pbus;
@@ -2291,7 +2291,7 @@
 	outb(0x88, iobase+0x1f);
 
 	/* it appears some maestros (dell 7500) only work if these are set,
-	   regardless of wether we use the assp or not. */
+	   regardless of whether we use the assp or not. */
 
 	outb(0, iobase + ASSP_CONTROL_B);
 	outb(3, iobase + ASSP_CONTROL_A);	/* M: Reserved bits... */
@@ -2465,7 +2465,7 @@
 
 #ifdef SUPPORT_JOYSTICK
 #define JOYSTICK_ADDR	0x200
-static int __devinit snd_es1968_create_gameport(struct es1968 *chip, int dev)
+static int snd_es1968_create_gameport(struct es1968 *chip, int dev)
 {
 	struct gameport *gp;
 	struct resource *r;
@@ -2516,7 +2516,7 @@
 #endif
 
 #ifdef CONFIG_SND_ES1968_INPUT
-static int __devinit snd_es1968_input_register(struct es1968 *chip)
+static int snd_es1968_input_register(struct es1968 *chip)
 {
 	struct input_dev *input_dev;
 	int err;
@@ -2653,7 +2653,7 @@
 	unsigned short vendor;	/* subsystem vendor id */
 };
 
-static struct ess_device_list pm_whitelist[] __devinitdata = {
+static struct ess_device_list pm_whitelist[] = {
 	{ TYPE_MAESTRO2E, 0x0e11 },	/* Compaq Armada */
 	{ TYPE_MAESTRO2E, 0x1028 },
 	{ TYPE_MAESTRO2E, 0x103c },
@@ -2664,19 +2664,19 @@
 	{ TYPE_MAESTRO2, 0x125d },	/* a PCI card, e.g. SF64-PCE2 */
 };
 
-static struct ess_device_list mpu_blacklist[] __devinitdata = {
+static struct ess_device_list mpu_blacklist[] = {
 	{ TYPE_MAESTRO2, 0x125d },
 };
 
-static int __devinit snd_es1968_create(struct snd_card *card,
-				       struct pci_dev *pci,
-				       int total_bufsize,
-				       int play_streams,
-				       int capt_streams,
-				       int chip_type,
-				       int do_pm,
-				       int radio_nr,
-				       struct es1968 **chip_ret)
+static int snd_es1968_create(struct snd_card *card,
+			     struct pci_dev *pci,
+			     int total_bufsize,
+			     int play_streams,
+			     int capt_streams,
+			     int chip_type,
+			     int do_pm,
+			     int radio_nr,
+			     struct es1968 **chip_ret)
 {
 	static struct snd_device_ops ops = {
 		.dev_free =	snd_es1968_dev_free,
@@ -2795,8 +2795,8 @@
 
 /*
  */
-static int __devinit snd_es1968_probe(struct pci_dev *pci,
-				      const struct pci_device_id *pci_id)
+static int snd_es1968_probe(struct pci_dev *pci,
+			    const struct pci_device_id *pci_id)
 {
 	static int dev;
 	struct snd_card *card;
@@ -2906,7 +2906,7 @@
 	return 0;
 }
 
-static void __devexit snd_es1968_remove(struct pci_dev *pci)
+static void snd_es1968_remove(struct pci_dev *pci)
 {
 	snd_card_free(pci_get_drvdata(pci));
 	pci_set_drvdata(pci, NULL);
@@ -2916,7 +2916,7 @@
 	.name = KBUILD_MODNAME,
 	.id_table = snd_es1968_ids,
 	.probe = snd_es1968_probe,
-	.remove = __devexit_p(snd_es1968_remove),
+	.remove = snd_es1968_remove,
 	.driver = {
 		.pm = ES1968_PM_OPS,
 	},
diff --git a/sound/pci/fm801.c b/sound/pci/fm801.c
index c5806f8..4f07fda 100644
--- a/sound/pci/fm801.c
+++ b/sound/pci/fm801.c
@@ -689,7 +689,7 @@
 	.pointer =	snd_fm801_capture_pointer,
 };
 
-static int __devinit snd_fm801_pcm(struct fm801 *chip, int device, struct snd_pcm ** rpcm)
+static int snd_fm801_pcm(struct fm801 *chip, int device, struct snd_pcm **rpcm)
 {
 	struct snd_pcm *pcm;
 	int err;
@@ -984,7 +984,7 @@
 
 #define FM801_CONTROLS ARRAY_SIZE(snd_fm801_controls)
 
-static struct snd_kcontrol_new snd_fm801_controls[] __devinitdata = {
+static struct snd_kcontrol_new snd_fm801_controls[] = {
 FM801_DOUBLE_TLV("Wave Playback Volume", FM801_PCM_VOL, 0, 8, 31, 1,
 		 db_scale_dsp),
 FM801_SINGLE("Wave Playback Switch", FM801_PCM_VOL, 15, 1, 1),
@@ -1005,7 +1005,7 @@
 
 #define FM801_CONTROLS_MULTI ARRAY_SIZE(snd_fm801_controls_multi)
 
-static struct snd_kcontrol_new snd_fm801_controls_multi[] __devinitdata = {
+static struct snd_kcontrol_new snd_fm801_controls_multi[] = {
 FM801_SINGLE("AC97 2ch->4ch Copy Switch", FM801_CODEC_CTRL, 7, 1, 0),
 FM801_SINGLE("AC97 18-bit Switch", FM801_CODEC_CTRL, 10, 1, 0),
 FM801_SINGLE(SNDRV_CTL_NAME_IEC958("",CAPTURE,SWITCH), FM801_I2S_MODE, 8, 1, 0),
@@ -1030,7 +1030,7 @@
 	}
 }
 
-static int __devinit snd_fm801_mixer(struct fm801 *chip)
+static int snd_fm801_mixer(struct fm801 *chip)
 {
 	struct snd_ac97_template ac97;
 	unsigned int i;
@@ -1191,11 +1191,11 @@
 	return snd_fm801_free(chip);
 }
 
-static int __devinit snd_fm801_create(struct snd_card *card,
-				      struct pci_dev * pci,
-				      int tea575x_tuner,
-				      int radio_nr,
-				      struct fm801 ** rchip)
+static int snd_fm801_create(struct snd_card *card,
+			    struct pci_dev *pci,
+			    int tea575x_tuner,
+			    int radio_nr,
+			    struct fm801 **rchip)
 {
 	struct fm801 *chip;
 	int err;
@@ -1296,8 +1296,8 @@
 	return 0;
 }
 
-static int __devinit snd_card_fm801_probe(struct pci_dev *pci,
-					  const struct pci_device_id *pci_id)
+static int snd_card_fm801_probe(struct pci_dev *pci,
+				const struct pci_device_id *pci_id)
 {
 	static int dev;
 	struct snd_card *card;
@@ -1367,7 +1367,7 @@
 	return 0;
 }
 
-static void __devexit snd_card_fm801_remove(struct pci_dev *pci)
+static void snd_card_fm801_remove(struct pci_dev *pci)
 {
 	snd_card_free(pci_get_drvdata(pci));
 	pci_set_drvdata(pci, NULL);
@@ -1439,7 +1439,7 @@
 	.name = KBUILD_MODNAME,
 	.id_table = snd_fm801_ids,
 	.probe = snd_card_fm801_probe,
-	.remove = __devexit_p(snd_card_fm801_remove),
+	.remove = snd_card_fm801_remove,
 	.driver = {
 		.pm = SND_FM801_PM_OPS,
 	},
diff --git a/sound/pci/hda/Kconfig b/sound/pci/hda/Kconfig
index 7105c3d..6eeb889 100644
--- a/sound/pci/hda/Kconfig
+++ b/sound/pci/hda/Kconfig
@@ -37,8 +37,8 @@
 	  with codecs for debugging purposes.
 
 config SND_HDA_RECONFIG
-	bool "Allow dynamic codec reconfiguration (EXPERIMENTAL)"
-	depends on SND_HDA_HWDEP && EXPERIMENTAL
+	bool "Allow dynamic codec reconfiguration"
+	depends on SND_HDA_HWDEP
 	help
 	  Say Y here to enable the HD-audio codec re-configuration feature.
 	  This adds the sysfs interfaces to allow user to clear the whole
@@ -72,7 +72,6 @@
 
 config SND_HDA_PATCH_LOADER
 	bool "Support initialization patch loading for HD-audio"
-	depends on EXPERIMENTAL
 	select FW_LOADER
 	select SND_HDA_HWDEP
 	select SND_HDA_RECONFIG
diff --git a/sound/pci/hda/Makefile b/sound/pci/hda/Makefile
index bd4149f..24a2514 100644
--- a/sound/pci/hda/Makefile
+++ b/sound/pci/hda/Makefile
@@ -8,6 +8,7 @@
 
 # for trace-points
 CFLAGS_hda_codec.o := -I$(src)
+CFLAGS_hda_intel.o := -I$(src)
 
 snd-hda-codec-realtek-objs :=	patch_realtek.o
 snd-hda-codec-cmedia-objs :=	patch_cmedia.o
diff --git a/sound/pci/hda/hda_auto_parser.c b/sound/pci/hda/hda_auto_parser.c
index 4ec6dc8..7da883a 100644
--- a/sound/pci/hda/hda_auto_parser.c
+++ b/sound/pci/hda/hda_auto_parser.c
@@ -11,6 +11,7 @@
 
 #include <linux/slab.h>
 #include <linux/export.h>
+#include <linux/sort.h>
 #include <sound/core.h>
 #include "hda_codec.h"
 #include "hda_local.h"
@@ -30,29 +31,30 @@
 	return 0;
 }
 
+/* a pair of input pin and its sequence */
+struct auto_out_pin {
+	hda_nid_t pin;
+	short seq;
+};
+
+static int compare_seq(const void *ap, const void *bp)
+{
+	const struct auto_out_pin *a = ap;
+	const struct auto_out_pin *b = bp;
+	return (int)(a->seq - b->seq);
+}
 
 /*
  * Sort an associated group of pins according to their sequence numbers.
+ * then store it to a pin array.
  */
-static void sort_pins_by_sequence(hda_nid_t *pins, short *sequences,
+static void sort_pins_by_sequence(hda_nid_t *pins, struct auto_out_pin *list,
 				  int num_pins)
 {
-	int i, j;
-	short seq;
-	hda_nid_t nid;
-
-	for (i = 0; i < num_pins; i++) {
-		for (j = i + 1; j < num_pins; j++) {
-			if (sequences[i] > sequences[j]) {
-				seq = sequences[i];
-				sequences[i] = sequences[j];
-				sequences[j] = seq;
-				nid = pins[i];
-				pins[i] = pins[j];
-				pins[j] = nid;
-			}
-		}
-	}
+	int i;
+	sort(list, num_pins, sizeof(list[0]), compare_seq, NULL);
+	for (i = 0; i < num_pins; i++)
+		pins[i] = list[i].pin;
 }
 
 
@@ -67,21 +69,11 @@
 	}
 }
 
-/* sort inputs in the order of AUTO_PIN_* type */
-static void sort_autocfg_input_pins(struct auto_pin_cfg *cfg)
+static int compare_input_type(const void *ap, const void *bp)
 {
-	int i, j;
-
-	for (i = 0; i < cfg->num_inputs; i++) {
-		for (j = i + 1; j < cfg->num_inputs; j++) {
-			if (cfg->inputs[i].type > cfg->inputs[j].type) {
-				struct auto_pin_cfg_item tmp;
-				tmp = cfg->inputs[i];
-				cfg->inputs[i] = cfg->inputs[j];
-				cfg->inputs[j] = tmp;
-			}
-		}
-	}
+	const struct auto_pin_cfg_item *a = ap;
+	const struct auto_pin_cfg_item *b = bp;
+	return (int)(a->type - b->type);
 }
 
 /* Reorder the surround channels
@@ -129,16 +121,16 @@
 {
 	hda_nid_t nid, end_nid;
 	short seq, assoc_line_out;
-	short sequences_line_out[ARRAY_SIZE(cfg->line_out_pins)];
-	short sequences_speaker[ARRAY_SIZE(cfg->speaker_pins)];
-	short sequences_hp[ARRAY_SIZE(cfg->hp_pins)];
+	struct auto_out_pin line_out[ARRAY_SIZE(cfg->line_out_pins)];
+	struct auto_out_pin speaker_out[ARRAY_SIZE(cfg->speaker_pins)];
+	struct auto_out_pin hp_out[ARRAY_SIZE(cfg->hp_pins)];
 	int i;
 
 	memset(cfg, 0, sizeof(*cfg));
 
-	memset(sequences_line_out, 0, sizeof(sequences_line_out));
-	memset(sequences_speaker, 0, sizeof(sequences_speaker));
-	memset(sequences_hp, 0, sizeof(sequences_hp));
+	memset(line_out, 0, sizeof(line_out));
+	memset(speaker_out, 0, sizeof(speaker_out));
+	memset(hp_out, 0, sizeof(hp_out));
 	assoc_line_out = 0;
 
 	end_nid = codec->start_nid + codec->num_nodes;
@@ -184,8 +176,8 @@
 				continue;
 			if (cfg->line_outs >= ARRAY_SIZE(cfg->line_out_pins))
 				continue;
-			cfg->line_out_pins[cfg->line_outs] = nid;
-			sequences_line_out[cfg->line_outs] = seq;
+			line_out[cfg->line_outs].pin = nid;
+			line_out[cfg->line_outs].seq = seq;
 			cfg->line_outs++;
 			break;
 		case AC_JACK_SPEAKER:
@@ -193,8 +185,8 @@
 			assoc = get_defcfg_association(def_conf);
 			if (cfg->speaker_outs >= ARRAY_SIZE(cfg->speaker_pins))
 				continue;
-			cfg->speaker_pins[cfg->speaker_outs] = nid;
-			sequences_speaker[cfg->speaker_outs] = (assoc << 4) | seq;
+			speaker_out[cfg->speaker_outs].pin = nid;
+			speaker_out[cfg->speaker_outs].seq = (assoc << 4) | seq;
 			cfg->speaker_outs++;
 			break;
 		case AC_JACK_HP_OUT:
@@ -202,8 +194,8 @@
 			assoc = get_defcfg_association(def_conf);
 			if (cfg->hp_outs >= ARRAY_SIZE(cfg->hp_pins))
 				continue;
-			cfg->hp_pins[cfg->hp_outs] = nid;
-			sequences_hp[cfg->hp_outs] = (assoc << 4) | seq;
+			hp_out[cfg->hp_outs].pin = nid;
+			hp_out[cfg->hp_outs].seq = (assoc << 4) | seq;
 			cfg->hp_outs++;
 			break;
 		case AC_JACK_MIC_IN:
@@ -248,34 +240,28 @@
 		int i = 0;
 		while (i < cfg->hp_outs) {
 			/* The real HPs should have the sequence 0x0f */
-			if ((sequences_hp[i] & 0x0f) == 0x0f) {
+			if ((hp_out[i].seq & 0x0f) == 0x0f) {
 				i++;
 				continue;
 			}
 			/* Move it to the line-out table */
-			cfg->line_out_pins[cfg->line_outs] = cfg->hp_pins[i];
-			sequences_line_out[cfg->line_outs] = sequences_hp[i];
-			cfg->line_outs++;
+			line_out[cfg->line_outs++] = hp_out[i];
 			cfg->hp_outs--;
-			memmove(cfg->hp_pins + i, cfg->hp_pins + i + 1,
-				sizeof(cfg->hp_pins[0]) * (cfg->hp_outs - i));
-			memmove(sequences_hp + i, sequences_hp + i + 1,
-				sizeof(sequences_hp[0]) * (cfg->hp_outs - i));
+			memmove(hp_out + i, hp_out + i + 1,
+				sizeof(hp_out[0]) * (cfg->hp_outs - i));
 		}
-		memset(cfg->hp_pins + cfg->hp_outs, 0,
-		       sizeof(hda_nid_t) * (AUTO_CFG_MAX_OUTS - cfg->hp_outs));
+		memset(hp_out + cfg->hp_outs, 0,
+		       sizeof(hp_out[0]) * (AUTO_CFG_MAX_OUTS - cfg->hp_outs));
 		if (!cfg->hp_outs)
 			cfg->line_out_type = AUTO_PIN_HP_OUT;
 
 	}
 
 	/* sort by sequence */
-	sort_pins_by_sequence(cfg->line_out_pins, sequences_line_out,
-			      cfg->line_outs);
-	sort_pins_by_sequence(cfg->speaker_pins, sequences_speaker,
+	sort_pins_by_sequence(cfg->line_out_pins, line_out, cfg->line_outs);
+	sort_pins_by_sequence(cfg->speaker_pins, speaker_out,
 			      cfg->speaker_outs);
-	sort_pins_by_sequence(cfg->hp_pins, sequences_hp,
-			      cfg->hp_outs);
+	sort_pins_by_sequence(cfg->hp_pins, hp_out, cfg->hp_outs);
 
 	/*
 	 * FIX-UP: if no line-outs are detected, try to use speaker or HP pin
@@ -304,7 +290,9 @@
 	reorder_outputs(cfg->hp_outs, cfg->hp_pins);
 	reorder_outputs(cfg->speaker_outs, cfg->speaker_pins);
 
-	sort_autocfg_input_pins(cfg);
+	/* sort inputs in the order of AUTO_PIN_* type */
+	sort(cfg->inputs, cfg->num_inputs, sizeof(cfg->inputs[0]),
+	     compare_input_type, NULL);
 
 	/*
 	 * debug prints of the parsed results
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index d010de1..8353c77 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -738,7 +738,7 @@
  *
  * Returns 0 if successful, or a negative error code.
  */
-int /*__devinit*/ snd_hda_bus_new(struct snd_card *card,
+int snd_hda_bus_new(struct snd_card *card,
 			      const struct hda_bus_template *temp,
 			      struct hda_bus **busp)
 {
@@ -908,7 +908,7 @@
 /*
  * look for an AFG and MFG nodes
  */
-static void /*__devinit*/ setup_fg_nodes(struct hda_codec *codec)
+static void setup_fg_nodes(struct hda_codec *codec)
 {
 	int i, total_nodes, function_id;
 	hda_nid_t nid;
@@ -993,19 +993,6 @@
 	return NULL;
 }
 
-/* write a config value for the given NID */
-static void set_pincfg(struct hda_codec *codec, hda_nid_t nid,
-		       unsigned int cfg)
-{
-	int i;
-	for (i = 0; i < 4; i++) {
-		snd_hda_codec_write(codec, nid, 0,
-				    AC_VERB_SET_CONFIG_DEFAULT_BYTES_0 + i,
-				    cfg & 0xff);
-		cfg >>= 8;
-	}
-}
-
 /* set the current pin config value for the given NID.
  * the value is cached, and read via snd_hda_codec_get_pincfg()
  */
@@ -1013,12 +1000,10 @@
 		       hda_nid_t nid, unsigned int cfg)
 {
 	struct hda_pincfg *pin;
-	unsigned int oldcfg;
 
 	if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN)
 		return -EINVAL;
 
-	oldcfg = snd_hda_codec_get_pincfg(codec, nid);
 	pin = look_up_pincfg(codec, list, nid);
 	if (!pin) {
 		pin = snd_array_new(list);
@@ -1027,13 +1012,6 @@
 		pin->nid = nid;
 	}
 	pin->cfg = cfg;
-
-	/* change only when needed; e.g. if the pincfg is already present
-	 * in user_pins[], don't write it
-	 */
-	cfg = snd_hda_codec_get_pincfg(codec, nid);
-	if (oldcfg != cfg)
-		set_pincfg(codec, nid, cfg);
 	return 0;
 }
 
@@ -1082,17 +1060,6 @@
 }
 EXPORT_SYMBOL_HDA(snd_hda_codec_get_pincfg);
 
-/* restore all current pin configs */
-static void restore_pincfgs(struct hda_codec *codec)
-{
-	int i;
-	for (i = 0; i < codec->init_pins.used; i++) {
-		struct hda_pincfg *pin = snd_array_elem(&codec->init_pins, i);
-		set_pincfg(codec, pin->nid,
-			   snd_hda_codec_get_pincfg(codec, pin->nid));
-	}
-}
-
 /**
  * snd_hda_shutup_pins - Shut up all pins
  * @codec: the HDA codec
@@ -1137,21 +1104,30 @@
 }
 #endif
 
+static void hda_jackpoll_work(struct work_struct *work)
+{
+	struct hda_codec *codec =
+		container_of(work, struct hda_codec, jackpoll_work.work);
+	if (!codec->jackpoll_interval)
+		return;
+
+	snd_hda_jack_set_dirty_all(codec);
+	snd_hda_jack_poll_all(codec);
+	queue_delayed_work(codec->bus->workq, &codec->jackpoll_work,
+			   codec->jackpoll_interval);
+}
+
 static void init_hda_cache(struct hda_cache_rec *cache,
 			   unsigned int record_size);
 static void free_hda_cache(struct hda_cache_rec *cache);
 
-/* restore the initial pin cfgs and release all pincfg lists */
-static void restore_init_pincfgs(struct hda_codec *codec)
+/* release all pincfg lists */
+static void free_init_pincfgs(struct hda_codec *codec)
 {
-	/* first free driver_pins and user_pins, then call restore_pincfg
-	 * so that only the values in init_pins are restored
-	 */
 	snd_array_free(&codec->driver_pins);
 #ifdef CONFIG_SND_HDA_HWDEP
 	snd_array_free(&codec->user_pins);
 #endif
-	restore_pincfgs(codec);
 	snd_array_free(&codec->init_pins);
 }
 
@@ -1192,8 +1168,9 @@
 {
 	if (!codec)
 		return;
+	cancel_delayed_work_sync(&codec->jackpoll_work);
 	snd_hda_jack_tbl_clear(codec);
-	restore_init_pincfgs(codec);
+	free_init_pincfgs(codec);
 #ifdef CONFIG_PM
 	cancel_delayed_work(&codec->power_work);
 	flush_workqueue(codec->bus->workq);
@@ -1235,7 +1212,7 @@
  *
  * Returns 0 if successful, or a negative error code.
  */
-int /*__devinit*/ snd_hda_codec_new(struct hda_bus *bus,
+int snd_hda_codec_new(struct hda_bus *bus,
 				unsigned int codec_addr,
 				struct hda_codec **codecp)
 {
@@ -1275,6 +1252,8 @@
 	snd_array_init(&codec->cvt_setups, sizeof(struct hda_cvt_setup), 8);
 	snd_array_init(&codec->conn_lists, sizeof(hda_nid_t), 64);
 	snd_array_init(&codec->spdif_out, sizeof(struct hda_spdif_out), 16);
+	snd_array_init(&codec->jacktbl, sizeof(struct hda_jack_tbl), 16);
+	INIT_DELAYED_WORK(&codec->jackpoll_work, hda_jackpoll_work);
 
 #ifdef CONFIG_PM
 	spin_lock_init(&codec->power_lock);
@@ -1588,7 +1567,7 @@
 #define INFO_AMP_VOL(ch)	(1 << (1 + (ch)))
 
 /* initialize the hash table */
-static void /*__devinit*/ init_hda_cache(struct hda_cache_rec *cache,
+static void init_hda_cache(struct hda_cache_rec *cache,
 				     unsigned int record_size)
 {
 	memset(cache, 0, sizeof(*cache));
@@ -2153,12 +2132,12 @@
 
 /* find a mixer control element with the given name */
 static struct snd_kcontrol *
-_snd_hda_find_mixer_ctl(struct hda_codec *codec,
-			const char *name, int idx)
+find_mixer_ctl(struct hda_codec *codec, const char *name, int dev, int idx)
 {
 	struct snd_ctl_elem_id id;
 	memset(&id, 0, sizeof(id));
 	id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
+	id.device = dev;
 	id.index = idx;
 	if (snd_BUG_ON(strlen(name) >= sizeof(id.name)))
 		return NULL;
@@ -2176,15 +2155,16 @@
 struct snd_kcontrol *snd_hda_find_mixer_ctl(struct hda_codec *codec,
 					    const char *name)
 {
-	return _snd_hda_find_mixer_ctl(codec, name, 0);
+	return find_mixer_ctl(codec, name, 0, 0);
 }
 EXPORT_SYMBOL_HDA(snd_hda_find_mixer_ctl);
 
-static int find_empty_mixer_ctl_idx(struct hda_codec *codec, const char *name)
+static int find_empty_mixer_ctl_idx(struct hda_codec *codec, const char *name,
+				    int dev)
 {
 	int idx;
 	for (idx = 0; idx < 16; idx++) { /* 16 ctlrs should be large enough */
-		if (!_snd_hda_find_mixer_ctl(codec, name, idx))
+		if (!find_mixer_ctl(codec, name, dev, idx))
 			return idx;
 	}
 	return -EBUSY;
@@ -2351,7 +2331,7 @@
 		return -EBUSY;
 
 	/* OK, let it free */
-
+	cancel_delayed_work_sync(&codec->jackpoll_work);
 #ifdef CONFIG_PM
 	cancel_delayed_work_sync(&codec->power_work);
 	codec->power_on = 0;
@@ -2380,7 +2360,6 @@
 	init_hda_cache(&codec->cmd_cache, sizeof(struct hda_cache_head));
 	/* free only driver_pins so that init_pins + user_pins are restored */
 	snd_array_free(&codec->driver_pins);
-	restore_pincfgs(codec);
 	snd_array_free(&codec->cvt_setups);
 	snd_array_free(&codec->spdif_out);
 	codec->num_pcms = 0;
@@ -3135,26 +3114,48 @@
 };
 
 /**
- * snd_hda_create_spdif_out_ctls - create Output SPDIF-related controls
+ * snd_hda_create_dig_out_ctls - create Output SPDIF-related controls
  * @codec: the HDA codec
- * @nid: audio out widget NID
- *
- * Creates controls related with the SPDIF output.
- * Called from each patch supporting the SPDIF out.
+ * @associated_nid: NID that new ctls associated with
+ * @cvt_nid: converter NID
+ * @type: HDA_PCM_TYPE_*
+ * Creates controls related with the digital output.
+ * Called from each patch supporting the digital out.
  *
  * Returns 0 if successful, or a negative error code.
  */
-int snd_hda_create_spdif_out_ctls(struct hda_codec *codec,
-				  hda_nid_t associated_nid,
-				  hda_nid_t cvt_nid)
+int snd_hda_create_dig_out_ctls(struct hda_codec *codec,
+				hda_nid_t associated_nid,
+				hda_nid_t cvt_nid,
+				int type)
 {
 	int err;
 	struct snd_kcontrol *kctl;
 	struct snd_kcontrol_new *dig_mix;
-	int idx;
+	int idx, dev = 0;
+	const int spdif_pcm_dev = 1;
 	struct hda_spdif_out *spdif;
 
-	idx = find_empty_mixer_ctl_idx(codec, "IEC958 Playback Switch");
+	if (codec->primary_dig_out_type == HDA_PCM_TYPE_HDMI &&
+	    type == HDA_PCM_TYPE_SPDIF) {
+		dev = spdif_pcm_dev;
+	} else if (codec->primary_dig_out_type == HDA_PCM_TYPE_SPDIF &&
+		   type == HDA_PCM_TYPE_HDMI) {
+		for (idx = 0; idx < codec->spdif_out.used; idx++) {
+			spdif = snd_array_elem(&codec->spdif_out, idx);
+			for (dig_mix = dig_mixes; dig_mix->name; dig_mix++) {
+				kctl = find_mixer_ctl(codec, dig_mix->name, 0, idx);
+				if (!kctl)
+					break;
+				kctl->id.device = spdif_pcm_dev;
+			}
+		}
+		codec->primary_dig_out_type = HDA_PCM_TYPE_HDMI;
+	}
+	if (!codec->primary_dig_out_type)
+		codec->primary_dig_out_type = type;
+
+	idx = find_empty_mixer_ctl_idx(codec, "IEC958 Playback Switch", dev);
 	if (idx < 0) {
 		printk(KERN_ERR "hda_codec: too many IEC958 outputs\n");
 		return -EBUSY;
@@ -3164,6 +3165,7 @@
 		kctl = snd_ctl_new1(dig_mix, codec);
 		if (!kctl)
 			return -ENOMEM;
+		kctl->id.device = dev;
 		kctl->id.index = idx;
 		kctl->private_value = codec->spdif_out.used - 1;
 		err = snd_hda_ctl_add(codec, associated_nid, kctl);
@@ -3176,7 +3178,7 @@
 	spdif->status = convert_to_spdif_status(spdif->ctls);
 	return 0;
 }
-EXPORT_SYMBOL_HDA(snd_hda_create_spdif_out_ctls);
+EXPORT_SYMBOL_HDA(snd_hda_create_dig_out_ctls);
 
 /* get the hda_spdif_out entry from the given NID
  * call within spdif_mutex lock
@@ -3351,7 +3353,7 @@
 	struct snd_kcontrol_new *dig_mix;
 	int idx;
 
-	idx = find_empty_mixer_ctl_idx(codec, "IEC958 Capture Switch");
+	idx = find_empty_mixer_ctl_idx(codec, "IEC958 Capture Switch", 0);
 	if (idx < 0) {
 		printk(KERN_ERR "hda_codec: too many IEC958 inputs\n");
 		return -EBUSY;
@@ -3650,10 +3652,8 @@
 	 */
 	hda_keep_power_on(codec);
 	hda_set_power_state(codec, AC_PWRST_D0);
-	restore_pincfgs(codec); /* restore all current pin configs */
 	restore_shutup_pins(codec);
 	hda_exec_init_verbs(codec);
-	snd_hda_jack_set_dirty_all(codec);
 	if (codec->patch_ops.resume)
 		codec->patch_ops.resume(codec);
 	else {
@@ -3662,7 +3662,13 @@
 		snd_hda_codec_resume_amp(codec);
 		snd_hda_codec_resume_cache(codec);
 	}
-	snd_hda_jack_report_sync(codec);
+
+	if (codec->jackpoll_interval)
+		hda_jackpoll_work(&codec->jackpoll_work.work);
+	else {
+		snd_hda_jack_set_dirty_all(codec);
+		snd_hda_jack_report_sync(codec);
+	}
 
 	codec->in_pm = 0;
 	snd_hda_power_down(codec); /* flag down before returning */
@@ -3678,7 +3684,7 @@
  *
  * Returns 0 if successful, otherwise a negative error code.
  */
-int /*__devinit*/ snd_hda_build_controls(struct hda_bus *bus)
+int snd_hda_build_controls(struct hda_bus *bus)
 {
 	struct hda_codec *codec;
 
@@ -3712,13 +3718,14 @@
 			struct hda_pcm_stream *hinfo =
 				&codec->pcm_info[i].stream[str];
 			struct snd_pcm_chmap *chmap;
+			const struct snd_pcm_chmap_elem *elem;
 
 			if (codec->pcm_info[i].own_chmap)
 				continue;
 			if (!pcm || !hinfo->substreams)
 				continue;
-			err = snd_pcm_add_chmap_ctls(pcm, str,
-						     snd_pcm_std_chmaps,
+			elem = hinfo->chmap ? hinfo->chmap : snd_pcm_std_chmaps;
+			err = snd_pcm_add_chmap_ctls(pcm, str, elem,
 						     hinfo->channels_max,
 						     0, &chmap);
 			if (err < 0)
@@ -3729,6 +3736,19 @@
 	return 0;
 }
 
+/* default channel maps for 2.1 speakers;
+ * since HD-audio supports only stereo, odd number channels are omitted
+ */
+const struct snd_pcm_chmap_elem snd_pcm_2_1_chmaps[] = {
+	{ .channels = 2,
+	  .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR } },
+	{ .channels = 4,
+	  .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR,
+		   SNDRV_CHMAP_LFE, SNDRV_CHMAP_LFE } },
+	{ }
+};
+EXPORT_SYMBOL_GPL(snd_pcm_2_1_chmaps);
+
 int snd_hda_codec_build_controls(struct hda_codec *codec)
 {
 	int err = 0;
@@ -3746,7 +3766,10 @@
 	if (err < 0)
 		return err;
 
-	snd_hda_jack_report_sync(codec); /* call at the last init point */
+	if (codec->jackpoll_interval)
+		hda_jackpoll_work(&codec->jackpoll_work.work);
+	else
+		snd_hda_jack_report_sync(codec); /* call at the last init point */
 	return 0;
 }
 
@@ -4458,7 +4481,7 @@
 				addr = codec->addr;
 			else if (!idx && !knew->index) {
 				idx = find_empty_mixer_ctl_idx(codec,
-							       knew->name);
+							       knew->name, 0);
 				if (idx <= 0)
 					return err;
 			} else
@@ -4771,6 +4794,34 @@
 
 
 /*
+ * process kcontrol info callback of a simple string enum array
+ * when @num_items is 0 or @texts is NULL, assume a boolean enum array
+ */
+int snd_hda_enum_helper_info(struct snd_kcontrol *kcontrol,
+			     struct snd_ctl_elem_info *uinfo,
+			     int num_items, const char * const *texts)
+{
+	static const char * const texts_default[] = {
+		"Disabled", "Enabled"
+	};
+
+	if (!texts || !num_items) {
+		num_items = 2;
+		texts = texts_default;
+	}
+
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
+	uinfo->count = 1;
+	uinfo->value.enumerated.items = num_items;
+	if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
+		uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
+	strcpy(uinfo->value.enumerated.name,
+	       texts[uinfo->value.enumerated.item]);
+	return 0;
+}
+EXPORT_SYMBOL_HDA(snd_hda_enum_helper_info);
+
+/*
  * Multi-channel / digital-out PCM helper functions
  */
 
@@ -4778,10 +4829,20 @@
 static void setup_dig_out_stream(struct hda_codec *codec, hda_nid_t nid,
 				 unsigned int stream_tag, unsigned int format)
 {
-	struct hda_spdif_out *spdif = snd_hda_spdif_out_of_nid(codec, nid);
+	struct hda_spdif_out *spdif;
+	unsigned int curr_fmt;
+	bool reset;
 
-	/* turn off SPDIF once; otherwise the IEC958 bits won't be updated */
-	if (codec->spdif_status_reset && (spdif->ctls & AC_DIG1_ENABLE))
+	spdif = snd_hda_spdif_out_of_nid(codec, nid);
+	curr_fmt = snd_hda_codec_read(codec, nid, 0,
+				      AC_VERB_GET_STREAM_FORMAT, 0);
+	reset = codec->spdif_status_reset &&
+		(spdif->ctls & AC_DIG1_ENABLE) &&
+		curr_fmt != format;
+
+	/* turn off SPDIF if needed; otherwise the IEC958 bits won't be
+	   updated */
+	if (reset)
 		set_dig_out_convert(codec, nid,
 				    spdif->ctls & ~AC_DIG1_ENABLE & 0xff,
 				    -1);
@@ -4793,7 +4854,7 @@
 						   format);
 	}
 	/* turn on again (if needed) */
-	if (codec->spdif_status_reset && (spdif->ctls & AC_DIG1_ENABLE))
+	if (reset)
 		set_dig_out_convert(codec, nid,
 				    spdif->ctls & 0xff, -1);
 }
@@ -5137,6 +5198,7 @@
 	struct hda_codec *codec;
 
 	list_for_each_entry(codec, &bus->codec_list, list) {
+		cancel_delayed_work_sync(&codec->jackpoll_work);
 		if (hda_codec_is_power_on(codec))
 			hda_call_codec_suspend(codec, false);
 	}
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h
index 4f4e545..8665540e 100644
--- a/sound/pci/hda/hda_codec.h
+++ b/sound/pci/hda/hda_codec.h
@@ -757,6 +757,7 @@
 	u32 rates;	/* supported rates */
 	u64 formats;	/* supported formats (SNDRV_PCM_FMTBIT_) */
 	unsigned int maxbps;	/* supported max. bit per sample */
+	const struct snd_pcm_chmap_elem *chmap; /* chmap to override */
 	struct hda_pcm_ops ops;
 };
 
@@ -836,6 +837,7 @@
 	struct mutex hash_mutex;
 	struct snd_array spdif_out;
 	unsigned int spdif_in_enable;	/* SPDIF input enable? */
+	int primary_dig_out_type;	/* primary digital out PCM type */
 	const hda_nid_t *slave_dig_outs; /* optional digital out slave widgets */
 	struct snd_array init_pins;	/* initial (BIOS) pin configurations */
 	struct snd_array driver_pins;	/* pin configs set by codec parser */
@@ -885,6 +887,8 @@
 
 	/* jack detection */
 	struct snd_array jacktbl;
+	unsigned long jackpoll_interval; /* In jiffies. Zero means no poll, rely on unsol events */
+	struct delayed_work jackpoll_work;
 
 #ifdef CONFIG_SND_HDA_INPUT_JACK
 	/* jack detection */
@@ -1024,6 +1028,8 @@
 int snd_hda_is_supported_format(struct hda_codec *codec, hda_nid_t nid,
 				unsigned int format);
 
+extern const struct snd_pcm_chmap_elem snd_pcm_2_1_chmaps[];
+
 /*
  * Misc
  */
diff --git a/sound/pci/hda/hda_hwdep.c b/sound/pci/hda/hda_hwdep.c
index 1af86d4..a5c9411 100644
--- a/sound/pci/hda/hda_hwdep.c
+++ b/sound/pci/hda/hda_hwdep.c
@@ -125,7 +125,7 @@
 	clear_hwdep_elements(hwdep->private_data);
 }
 
-int /*__devinit*/ snd_hda_create_hwdep(struct hda_codec *codec)
+int snd_hda_create_hwdep(struct hda_codec *codec)
 {
 	char hwname[16];
 	struct snd_hwdep *hwdep;
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index f9d870e..0f3d3db 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -47,6 +47,10 @@
 #include <linux/reboot.h>
 #include <linux/io.h>
 #include <linux/pm_runtime.h>
+#include <linux/clocksource.h>
+#include <linux/time.h>
+#include <linux/completion.h>
+
 #ifdef CONFIG_X86
 /* for snoop control */
 #include <asm/pgtable.h>
@@ -68,6 +72,7 @@
 static int bdl_pos_adj[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = -1};
 static int probe_mask[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = -1};
 static int probe_only[SNDRV_CARDS];
+static int jackpoll_ms[SNDRV_CARDS];
 static bool single_cmd;
 static int enable_msi = -1;
 #ifdef CONFIG_SND_HDA_PATCH_LOADER
@@ -95,6 +100,8 @@
 MODULE_PARM_DESC(probe_mask, "Bitmask to probe codecs (default = -1).");
 module_param_array(probe_only, int, NULL, 0444);
 MODULE_PARM_DESC(probe_only, "Only probing and no codec initialization.");
+module_param_array(jackpoll_ms, int, NULL, 0444);
+MODULE_PARM_DESC(jackpoll_ms, "Ms between polling for jack events (default = 0, using unsol events only)");
 module_param(single_cmd, bool, 0444);
 MODULE_PARM_DESC(single_cmd, "Use single command to communicate with codecs "
 		 "(for debugging only).");
@@ -185,7 +192,7 @@
 #ifdef CONFIG_SND_VERBOSE_PRINTK
 #define SFX	/* nop */
 #else
-#define SFX	"hda-intel: "
+#define SFX	"hda-intel "
 #endif
 
 #if defined(CONFIG_PM) && defined(CONFIG_VGA_SWITCHEROO)
@@ -416,6 +423,9 @@
 	unsigned int insufficient :1;
 	unsigned int wc_marked:1;
 	unsigned int no_period_wakeup:1;
+
+	struct timecounter  azx_tc;
+	struct cyclecounter azx_cc;
 };
 
 /* CORB/RIRB */
@@ -460,6 +470,7 @@
 	/* locks */
 	spinlock_t reg_lock;
 	struct mutex open_mutex;
+	struct completion probe_wait;
 
 	/* streams (x num_streams) */
 	struct azx_dev *azx_dev;
@@ -518,6 +529,9 @@
 	struct list_head list;
 };
 
+#define CREATE_TRACE_POINTS
+#include "hda_intel_trace.h"
+
 /* driver types */
 enum {
 	AZX_DRIVER_ICH,
@@ -589,15 +603,7 @@
 #define use_vga_switcheroo(chip)	0
 #endif
 
-#if defined(SUPPORT_VGA_SWITCHEROO) || defined(CONFIG_SND_HDA_PATCH_LOADER)
-#define DELAYED_INIT_MARK
-#define DELAYED_INITDATA_MARK
-#else
-#define DELAYED_INIT_MARK	__devinit
-#define DELAYED_INITDATA_MARK	__devinitdata
-#endif
-
-static char *driver_short_names[] DELAYED_INITDATA_MARK = {
+static char *driver_short_names[] = {
 	[AZX_DRIVER_ICH] = "HDA Intel",
 	[AZX_DRIVER_PCH] = "HDA Intel PCH",
 	[AZX_DRIVER_SCH] = "HDA Intel MID",
@@ -703,7 +709,7 @@
 				  snd_dma_pci_data(chip->pci),
 				  PAGE_SIZE, &chip->rb);
 	if (err < 0) {
-		snd_printk(KERN_ERR SFX "cannot allocate CORB/RIRB\n");
+		snd_printk(KERN_ERR SFX "%s: cannot allocate CORB/RIRB\n", pci_name(chip->pci));
 		return err;
 	}
 	mark_pages_wc(chip, &chip->rb, true);
@@ -793,7 +799,12 @@
 	spin_lock_irq(&chip->reg_lock);
 
 	/* add command to corb */
-	wp = azx_readb(chip, CORBWP);
+	wp = azx_readw(chip, CORBWP);
+	if (wp == 0xffff) {
+		/* something wrong, controller likely turned to D3 */
+		spin_unlock_irq(&chip->reg_lock);
+		return -1;
+	}
 	wp++;
 	wp %= ICH6_MAX_CORB_ENTRIES;
 
@@ -815,7 +826,12 @@
 	unsigned int addr;
 	u32 res, res_ex;
 
-	wp = azx_readb(chip, RIRBWP);
+	wp = azx_readw(chip, RIRBWP);
+	if (wp == 0xffff) {
+		/* something wrong, controller likely turned to D3 */
+		return;
+	}
+
 	if (wp == chip->rirb.wp)
 		return;
 	chip->rirb.wp = wp;
@@ -835,8 +851,9 @@
 			smp_wmb();
 			chip->rirb.cmds[addr]--;
 		} else
-			snd_printk(KERN_ERR SFX "spurious response %#x:%#x, "
+			snd_printk(KERN_ERR SFX "%s: spurious response %#x:%#x, "
 				   "last cmd=%#08x\n",
+				   pci_name(chip->pci),
 				   res, res_ex,
 				   chip->last_cmd[addr]);
 	}
@@ -879,9 +896,9 @@
 	}
 
 	if (!chip->polling_mode && chip->poll_count < 2) {
-		snd_printdd(SFX "azx_get_response timeout, "
+		snd_printdd(SFX "%s: azx_get_response timeout, "
 			   "polling the codec once: last cmd=0x%08x\n",
-			   chip->last_cmd[addr]);
+			   pci_name(chip->pci), chip->last_cmd[addr]);
 		do_poll = 1;
 		chip->poll_count++;
 		goto again;
@@ -889,17 +906,17 @@
 
 
 	if (!chip->polling_mode) {
-		snd_printk(KERN_WARNING SFX "azx_get_response timeout, "
+		snd_printk(KERN_WARNING SFX "%s: azx_get_response timeout, "
 			   "switching to polling mode: last cmd=0x%08x\n",
-			   chip->last_cmd[addr]);
+			   pci_name(chip->pci), chip->last_cmd[addr]);
 		chip->polling_mode = 1;
 		goto again;
 	}
 
 	if (chip->msi) {
-		snd_printk(KERN_WARNING SFX "No response from codec, "
+		snd_printk(KERN_WARNING SFX "%s: No response from codec, "
 			   "disabling MSI: last cmd=0x%08x\n",
-			   chip->last_cmd[addr]);
+			   pci_name(chip->pci), chip->last_cmd[addr]);
 		free_irq(chip->irq, chip);
 		chip->irq = -1;
 		pci_disable_msi(chip->pci);
@@ -965,8 +982,8 @@
 		udelay(1);
 	}
 	if (printk_ratelimit())
-		snd_printd(SFX "get_response timeout: IRS=0x%x\n",
-			   azx_readw(chip, IRS));
+		snd_printd(SFX "%s: get_response timeout: IRS=0x%x\n",
+			   pci_name(chip->pci), azx_readw(chip, IRS));
 	chip->rirb.res[addr] = -1;
 	return -EIO;
 }
@@ -993,8 +1010,8 @@
 		udelay(1);
 	}
 	if (printk_ratelimit())
-		snd_printd(SFX "send_cmd timeout: IRS=0x%x, val=0x%x\n",
-			   azx_readw(chip, IRS), val);
+		snd_printd(SFX "%s: send_cmd timeout: IRS=0x%x, val=0x%x\n",
+			   pci_name(chip->pci), azx_readw(chip, IRS), val);
 	return -EIO;
 }
 
@@ -1047,7 +1064,7 @@
 /* reset codec link */
 static int azx_reset(struct azx *chip, int full_reset)
 {
-	int count;
+	unsigned long timeout;
 
 	if (!full_reset)
 		goto __skip;
@@ -1058,29 +1075,31 @@
 	/* reset controller */
 	azx_writel(chip, GCTL, azx_readl(chip, GCTL) & ~ICH6_GCTL_RESET);
 
-	count = 50;
-	while (azx_readb(chip, GCTL) && --count)
-		msleep(1);
+	timeout = jiffies + msecs_to_jiffies(100);
+	while (azx_readb(chip, GCTL) &&
+			time_before(jiffies, timeout))
+		usleep_range(500, 1000);
 
 	/* delay for >= 100us for codec PLL to settle per spec
 	 * Rev 0.9 section 5.5.1
 	 */
-	msleep(1);
+	usleep_range(500, 1000);
 
 	/* Bring controller out of reset */
 	azx_writeb(chip, GCTL, azx_readb(chip, GCTL) | ICH6_GCTL_RESET);
 
-	count = 50;
-	while (!azx_readb(chip, GCTL) && --count)
-		msleep(1);
+	timeout = jiffies + msecs_to_jiffies(100);
+	while (!azx_readb(chip, GCTL) &&
+			time_before(jiffies, timeout))
+		usleep_range(500, 1000);
 
 	/* Brent Chartrand said to wait >= 540us for codecs to initialize */
-	msleep(1);
+	usleep_range(1000, 1200);
 
       __skip:
 	/* check to see if controller is ready */
 	if (!azx_readb(chip, GCTL)) {
-		snd_printd(SFX "azx_reset: controller not ready!\n");
+		snd_printd(SFX "%s: azx_reset: controller not ready!\n", pci_name(chip->pci));
 		return -EBUSY;
 	}
 
@@ -1092,7 +1111,7 @@
 	/* detect codecs */
 	if (!chip->codec_mask) {
 		chip->codec_mask = azx_readw(chip, STATESTS);
-		snd_printdd(SFX "codec_mask = 0x%x\n", chip->codec_mask);
+		snd_printdd(SFX "%s: codec_mask = 0x%x\n", pci_name(chip->pci), chip->codec_mask);
 	}
 
 	return 0;
@@ -1236,7 +1255,7 @@
 	 * The PCI register TCSEL is defined in the Intel manuals.
 	 */
 	if (!(chip->driver_caps & AZX_DCAPS_NO_TCSEL)) {
-		snd_printdd(SFX "Clearing TCSEL\n");
+		snd_printdd(SFX "%s: Clearing TCSEL\n", pci_name(chip->pci));
 		update_pci_byte(chip->pci, ICH6_PCIREG_TCSEL, 0x07, 0);
 	}
 
@@ -1244,7 +1263,7 @@
 	 * we need to enable snoop.
 	 */
 	if (chip->driver_caps & AZX_DCAPS_ATI_SNOOP) {
-		snd_printdd(SFX "Setting ATI snoop: %d\n", azx_snoop(chip));
+		snd_printdd(SFX "%s: Setting ATI snoop: %d\n", pci_name(chip->pci), azx_snoop(chip));
 		update_pci_byte(chip->pci,
 				ATI_SB450_HDAUDIO_MISC_CNTR2_ADDR, 0x07,
 				azx_snoop(chip) ? ATI_SB450_HDAUDIO_ENABLE_SNOOP : 0);
@@ -1252,7 +1271,7 @@
 
 	/* For NVIDIA HDA, enable snoop */
 	if (chip->driver_caps & AZX_DCAPS_NVIDIA_SNOOP) {
-		snd_printdd(SFX "Setting Nvidia snoop: %d\n", azx_snoop(chip));
+		snd_printdd(SFX "%s: Setting Nvidia snoop: %d\n", pci_name(chip->pci), azx_snoop(chip));
 		update_pci_byte(chip->pci,
 				NVIDIA_HDA_TRANSREG_ADDR,
 				0x0f, NVIDIA_HDA_ENABLE_COHBITS);
@@ -1277,8 +1296,8 @@
 			pci_read_config_word(chip->pci,
 				INTEL_SCH_HDA_DEVC, &snoop);
 		}
-		snd_printdd(SFX "SCH snoop: %s\n",
-				(snoop & INTEL_SCH_HDA_DEVC_NOSNOOP)
+		snd_printdd(SFX "%s: SCH snoop: %s\n",
+				pci_name(chip->pci), (snoop & INTEL_SCH_HDA_DEVC_NOSNOOP)
 				? "Disabled" : "Enabled");
         }
 }
@@ -1438,8 +1457,8 @@
 				pos_align;
 		pos_adj = frames_to_bytes(runtime, pos_adj);
 		if (pos_adj >= period_bytes) {
-			snd_printk(KERN_WARNING SFX "Too big adjustment %d\n",
-				   bdl_pos_adj[chip->dev_index]);
+			snd_printk(KERN_WARNING SFX "%s: Too big adjustment %d\n",
+				   pci_name(chip->pci), bdl_pos_adj[chip->dev_index]);
 			pos_adj = 0;
 		} else {
 			ofs = setup_bdle(chip, substream, azx_dev,
@@ -1463,8 +1482,8 @@
 	return 0;
 
  error:
-	snd_printk(KERN_ERR SFX "Too many BDL entries: buffer=%d, period=%d\n",
-		   azx_dev->bufsize, period_bytes);
+	snd_printk(KERN_ERR SFX "%s: Too many BDL entries: buffer=%d, period=%d\n",
+		   pci_name(chip->pci), azx_dev->bufsize, period_bytes);
 	return -EINVAL;
 }
 
@@ -1561,7 +1580,7 @@
 	mutex_unlock(&chip->bus->cmd_mutex);
 	if (res == -1)
 		return -EIO;
-	snd_printdd(SFX "codec #%d probed OK\n", addr);
+	snd_printdd(SFX "%s: codec #%d probed OK\n", pci_name(chip->pci), addr);
 	return 0;
 }
 
@@ -1588,17 +1607,33 @@
 	bus->in_reset = 0;
 }
 
+static int get_jackpoll_interval(struct azx *chip)
+{
+	int i = jackpoll_ms[chip->dev_index];
+	unsigned int j;
+	if (i == 0)
+		return 0;
+	if (i < 50 || i > 60000)
+		j = 0;
+	else
+		j = msecs_to_jiffies(i);
+	if (j == 0)
+		snd_printk(KERN_WARNING SFX
+			   "jackpoll_ms value out of range: %d\n", i);
+	return j;
+}
+
 /*
  * Codec initialization
  */
 
 /* number of codec slots for each chipset: 0 = default slots (i.e. 4) */
-static unsigned int azx_max_codecs[AZX_NUM_DRIVERS] DELAYED_INITDATA_MARK = {
+static unsigned int azx_max_codecs[AZX_NUM_DRIVERS] = {
 	[AZX_DRIVER_NVIDIA] = 8,
 	[AZX_DRIVER_TERA] = 1,
 };
 
-static int DELAYED_INIT_MARK azx_codec_create(struct azx *chip, const char *model)
+static int azx_codec_create(struct azx *chip, const char *model)
 {
 	struct hda_bus_template bus_temp;
 	int c, codecs, err;
@@ -1622,7 +1657,7 @@
 		return err;
 
 	if (chip->driver_caps & AZX_DCAPS_RIRB_DELAY) {
-		snd_printd(SFX "Enable delay in RIRB handling\n");
+		snd_printd(SFX "%s: Enable delay in RIRB handling\n", pci_name(chip->pci));
 		chip->bus->needs_damn_long_delay = 1;
 	}
 
@@ -1639,8 +1674,8 @@
 				 * that don't exist
 				 */
 				snd_printk(KERN_WARNING SFX
-					   "Codec #%d probe error; "
-					   "disabling it...\n", c);
+					   "%s: Codec #%d probe error; "
+					   "disabling it...\n", pci_name(chip->pci), c);
 				chip->codec_mask &= ~(1 << c);
 				/* More badly, accessing to a non-existing
 				 * codec often screws up the controller chip,
@@ -1660,7 +1695,8 @@
 	 * access works around the stall.  Grrr...
 	 */
 	if (chip->driver_caps & AZX_DCAPS_SYNC_WRITE) {
-		snd_printd(SFX "Enable sync_write for stable communication\n");
+		snd_printd(SFX "%s: Enable sync_write for stable communication\n",
+			pci_name(chip->pci));
 		chip->bus->sync_write = 1;
 		chip->bus->allow_bus_reset = 1;
 	}
@@ -1672,19 +1708,20 @@
 			err = snd_hda_codec_new(chip->bus, c, &codec);
 			if (err < 0)
 				continue;
+			codec->jackpoll_interval = get_jackpoll_interval(chip);
 			codec->beep_mode = chip->beep_mode;
 			codecs++;
 		}
 	}
 	if (!codecs) {
-		snd_printk(KERN_ERR SFX "no codecs initialized\n");
+		snd_printk(KERN_ERR SFX "%s: no codecs initialized\n", pci_name(chip->pci));
 		return -ENXIO;
 	}
 	return 0;
 }
 
 /* configure each codec instance */
-static int __devinit azx_codec_configure(struct azx *chip)
+static int azx_codec_configure(struct azx *chip)
 {
 	struct hda_codec *codec;
 	list_for_each_entry(codec, &chip->bus->codec_list, list) {
@@ -1734,6 +1771,64 @@
 	azx_dev->opened = 0;
 }
 
+static cycle_t azx_cc_read(const struct cyclecounter *cc)
+{
+	struct azx_dev *azx_dev = container_of(cc, struct azx_dev, azx_cc);
+	struct snd_pcm_substream *substream = azx_dev->substream;
+	struct azx_pcm *apcm = snd_pcm_substream_chip(substream);
+	struct azx *chip = apcm->chip;
+
+	return azx_readl(chip, WALLCLK);
+}
+
+static void azx_timecounter_init(struct snd_pcm_substream *substream,
+				bool force, cycle_t last)
+{
+	struct azx_dev *azx_dev = get_azx_dev(substream);
+	struct timecounter *tc = &azx_dev->azx_tc;
+	struct cyclecounter *cc = &azx_dev->azx_cc;
+	u64 nsec;
+
+	cc->read = azx_cc_read;
+	cc->mask = CLOCKSOURCE_MASK(32);
+
+	/*
+	 * Converting from 24 MHz to ns means applying a 125/3 factor.
+	 * To avoid any saturation issues in intermediate operations,
+	 * the 125 factor is applied first. The division is applied
+	 * last after reading the timecounter value.
+	 * Applying the 1/3 factor as part of the multiplication
+	 * requires at least 20 bits for a decent precision, however
+	 * overflows occur after about 4 hours or less, not a option.
+	 */
+
+	cc->mult = 125; /* saturation after 195 years */
+	cc->shift = 0;
+
+	nsec = 0; /* audio time is elapsed time since trigger */
+	timecounter_init(tc, cc, nsec);
+	if (force)
+		/*
+		 * force timecounter to use predefined value,
+		 * used for synchronized starts
+		 */
+		tc->cycle_last = last;
+}
+
+static int azx_get_wallclock_tstamp(struct snd_pcm_substream *substream,
+				struct timespec *ts)
+{
+	struct azx_dev *azx_dev = get_azx_dev(substream);
+	u64 nsec;
+
+	nsec = timecounter_read(&azx_dev->azx_tc);
+	nsec = div_u64(nsec, 3); /* can be optimized */
+
+	*ts = ns_to_timespec(nsec);
+
+	return 0;
+}
+
 static struct snd_pcm_hardware azx_pcm_hw = {
 	.info =			(SNDRV_PCM_INFO_MMAP |
 				 SNDRV_PCM_INFO_INTERLEAVED |
@@ -1743,6 +1838,7 @@
 				 /* SNDRV_PCM_INFO_RESUME |*/
 				 SNDRV_PCM_INFO_PAUSE |
 				 SNDRV_PCM_INFO_SYNC_START |
+				 SNDRV_PCM_INFO_HAS_WALL_CLOCK |
 				 SNDRV_PCM_INFO_NO_PERIOD_WAKEUP),
 	.formats =		SNDRV_PCM_FMTBIT_S16_LE,
 	.rates =		SNDRV_PCM_RATE_48000,
@@ -1782,6 +1878,12 @@
 	runtime->hw.rates = hinfo->rates;
 	snd_pcm_limit_hw_rates(runtime);
 	snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
+
+	/* avoid wrap-around with wall-clock */
+	snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_TIME,
+				20,
+				178000000);
+
 	if (chip->align_buffer_size)
 		/* constrain buffer sizes to be multiple of 128
 		   bytes. This is more efficient in terms of memory
@@ -1821,6 +1923,12 @@
 		mutex_unlock(&chip->open_mutex);
 		return -EINVAL;
 	}
+
+	/* disable WALLCLOCK timestamps for capture streams
+	   until we figure out how to handle digital inputs */
+	if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
+		runtime->hw.info &= ~SNDRV_PCM_INFO_HAS_WALL_CLOCK;
+
 	spin_lock_irqsave(&chip->reg_lock, flags);
 	azx_dev->substream = substream;
 	azx_dev->running = 0;
@@ -1916,16 +2024,16 @@
 						ctls);
 	if (!format_val) {
 		snd_printk(KERN_ERR SFX
-			   "invalid format_val, rate=%d, ch=%d, format=%d\n",
-			   runtime->rate, runtime->channels, runtime->format);
+			   "%s: invalid format_val, rate=%d, ch=%d, format=%d\n",
+			   pci_name(chip->pci), runtime->rate, runtime->channels, runtime->format);
 		return -EINVAL;
 	}
 
 	bufsize = snd_pcm_lib_buffer_bytes(substream);
 	period_bytes = snd_pcm_lib_period_bytes(substream);
 
-	snd_printdd(SFX "azx_pcm_prepare: bufsize=0x%x, format=0x%x\n",
-		    bufsize, format_val);
+	snd_printdd(SFX "%s: azx_pcm_prepare: bufsize=0x%x, format=0x%x\n",
+		    pci_name(chip->pci), bufsize, format_val);
 
 	if (bufsize != azx_dev->bufsize ||
 	    period_bytes != azx_dev->period_bytes ||
@@ -1967,6 +2075,9 @@
 	int rstart = 0, start, nsync = 0, sbits = 0;
 	int nwait, timeout;
 
+	azx_dev = get_azx_dev(substream);
+	trace_azx_pcm_trigger(chip, azx_dev, cmd);
+
 	switch (cmd) {
 	case SNDRV_PCM_TRIGGER_START:
 		rstart = 1;
@@ -2057,6 +2168,22 @@
 			azx_readl(chip, OLD_SSYNC) & ~sbits);
 	else
 		azx_writel(chip, SSYNC, azx_readl(chip, SSYNC) & ~sbits);
+	if (start) {
+		azx_timecounter_init(substream, 0, 0);
+		if (nsync > 1) {
+			cycle_t cycle_last;
+
+			/* same start cycle for master and group */
+			azx_dev = get_azx_dev(substream);
+			cycle_last = azx_dev->azx_tc.cycle_last;
+
+			snd_pcm_group_for_each_entry(s, substream) {
+				if (s->pcm->card != substream->pcm->card)
+					continue;
+				azx_timecounter_init(s, 1, cycle_last);
+			}
+		}
+	}
 	spin_unlock(&chip->reg_lock);
 	return 0;
 }
@@ -2123,6 +2250,7 @@
 {
 	unsigned int pos;
 	int stream = azx_dev->substream->stream;
+	int delay = 0;
 
 	switch (chip->position_fix[stream]) {
 	case POS_FIX_LPIB:
@@ -2156,7 +2284,6 @@
 	    chip->position_fix[stream] == POS_FIX_POSBUF &&
 	    (chip->driver_caps & AZX_DCAPS_COUNT_LPIB_DELAY)) {
 		unsigned int lpib_pos = azx_sd_readl(azx_dev, SD_LPIB);
-		int delay;
 		if (stream == SNDRV_PCM_STREAM_PLAYBACK)
 			delay = pos - lpib_pos;
 		else
@@ -2165,15 +2292,16 @@
 			delay += azx_dev->bufsize;
 		if (delay >= azx_dev->period_bytes) {
 			snd_printk(KERN_WARNING SFX
-				   "Unstable LPIB (%d >= %d); "
+				   "%s: Unstable LPIB (%d >= %d); "
 				   "disabling LPIB delay counting\n",
-				   delay, azx_dev->period_bytes);
+				   pci_name(chip->pci), delay, azx_dev->period_bytes);
 			delay = 0;
 			chip->driver_caps &= ~AZX_DCAPS_COUNT_LPIB_DELAY;
 		}
 		azx_dev->substream->runtime->delay =
 			bytes_to_frames(azx_dev->substream->runtime, delay);
 	}
+	trace_azx_get_position(chip, azx_dev, pos, delay);
 	return pos;
 }
 
@@ -2199,13 +2327,11 @@
 {
 	u32 wallclk;
 	unsigned int pos;
-	int stream;
 
 	wallclk = azx_readl(chip, WALLCLK) - azx_dev->start_wallclk;
 	if (wallclk < (azx_dev->period_wallclk * 2) / 3)
 		return -1;	/* bogus (too early) interrupt */
 
-	stream = azx_dev->substream->stream;
 	pos = azx_get_position(chip, azx_dev, true);
 
 	if (WARN_ONCE(!azx_dev->period_bytes,
@@ -2296,6 +2422,7 @@
 	.prepare = azx_pcm_prepare,
 	.trigger = azx_pcm_trigger,
 	.pointer = azx_pcm_pointer,
+	.wall_clock =  azx_get_wallclock_tstamp,
 	.mmap = azx_pcm_mmap,
 	.page = snd_pcm_sgbuf_ops_page,
 };
@@ -2324,7 +2451,8 @@
 
 	list_for_each_entry(apcm, &chip->pcm_list, list) {
 		if (apcm->pcm->device == pcm_dev) {
-			snd_printk(KERN_ERR SFX "PCM %d already exists\n", pcm_dev);
+			snd_printk(KERN_ERR SFX "%s: PCM %d already exists\n",
+				   pci_name(chip->pci), pcm_dev);
 			return -EBUSY;
 		}
 	}
@@ -2365,7 +2493,7 @@
 /*
  * mixer creation - all stuff is implemented in hda module
  */
-static int __devinit azx_mixer_create(struct azx *chip)
+static int azx_mixer_create(struct azx *chip)
 {
 	return snd_hda_build_controls(chip->bus);
 }
@@ -2374,7 +2502,7 @@
 /*
  * initialize SD streams
  */
-static int __devinit azx_init_stream(struct azx *chip)
+static int azx_init_stream(struct azx *chip)
 {
 	int i;
 
@@ -2502,6 +2630,9 @@
 	struct azx *chip = card->private_data;
 	struct azx_pcm *p;
 
+	if (chip->disabled)
+		return 0;
+
 	snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
 	azx_clear_irq_pending(chip);
 	list_for_each_entry(p, &chip->pcm_list, list)
@@ -2527,6 +2658,9 @@
 	struct snd_card *card = dev_get_drvdata(dev);
 	struct azx *chip = card->private_data;
 
+	if (chip->disabled)
+		return 0;
+
 	pci_set_power_state(pci, PCI_D0);
 	pci_restore_state(pci);
 	if (pci_enable_device(pci) < 0) {
@@ -2557,10 +2691,6 @@
 	struct snd_card *card = dev_get_drvdata(dev);
 	struct azx *chip = card->private_data;
 
-	if (!power_save_controller ||
-	    !(chip->driver_caps & AZX_DCAPS_PM_RUNTIME))
-		return -EAGAIN;
-
 	azx_stop_chip(chip);
 	azx_clear_irq_pending(chip);
 	return 0;
@@ -2575,12 +2705,25 @@
 	azx_init_chip(chip, 1);
 	return 0;
 }
+
+static int azx_runtime_idle(struct device *dev)
+{
+	struct snd_card *card = dev_get_drvdata(dev);
+	struct azx *chip = card->private_data;
+
+	if (!power_save_controller ||
+	    !(chip->driver_caps & AZX_DCAPS_PM_RUNTIME))
+		return -EBUSY;
+
+	return 0;
+}
+
 #endif /* CONFIG_PM_RUNTIME */
 
 #ifdef CONFIG_PM
 static const struct dev_pm_ops azx_pm = {
 	SET_SYSTEM_SLEEP_PM_OPS(azx_suspend, azx_resume)
-	SET_RUNTIME_PM_OPS(azx_runtime_suspend, azx_runtime_resume, NULL)
+	SET_RUNTIME_PM_OPS(azx_runtime_suspend, azx_runtime_resume, azx_runtime_idle)
 };
 
 #define AZX_PM_OPS	&azx_pm
@@ -2612,11 +2755,11 @@
 		unregister_reboot_notifier(&chip->reboot_notifier);
 }
 
-static int DELAYED_INIT_MARK azx_first_init(struct azx *chip);
-static int DELAYED_INIT_MARK azx_probe_continue(struct azx *chip);
+static int azx_first_init(struct azx *chip);
+static int azx_probe_continue(struct azx *chip);
 
 #ifdef SUPPORT_VGA_SWITCHEROO
-static struct pci_dev __devinit *get_bound_vga(struct pci_dev *pci);
+static struct pci_dev *get_bound_vga(struct pci_dev *pci);
 
 static void azx_vs_set_state(struct pci_dev *pci,
 			     enum vga_switcheroo_state state)
@@ -2625,6 +2768,7 @@
 	struct azx *chip = card->private_data;
 	bool disabled;
 
+	wait_for_completion(&chip->probe_wait);
 	if (chip->init_failed)
 		return;
 
@@ -2648,15 +2792,14 @@
 		}
 	} else {
 		snd_printk(KERN_INFO SFX
-			   "%s %s via VGA-switcheroo\n",
-			   disabled ? "Disabling" : "Enabling",
-			   pci_name(chip->pci));
+			   "%s: %s via VGA-switcheroo\n", pci_name(chip->pci),
+			   disabled ? "Disabling" : "Enabling");
 		if (disabled) {
 			azx_suspend(&pci->dev);
 			chip->disabled = true;
 			if (snd_hda_lock_devices(chip->bus))
-				snd_printk(KERN_WARNING SFX
-					   "Cannot lock devices!\n");
+				snd_printk(KERN_WARNING SFX "%s: Cannot lock devices!\n",
+					   pci_name(chip->pci));
 		} else {
 			snd_hda_unlock_devices(chip->bus);
 			chip->disabled = false;
@@ -2670,6 +2813,7 @@
 	struct snd_card *card = pci_get_drvdata(pci);
 	struct azx *chip = card->private_data;
 
+	wait_for_completion(&chip->probe_wait);
 	if (chip->init_failed)
 		return false;
 	if (chip->disabled || !chip->bus)
@@ -2680,7 +2824,7 @@
 	return true;
 }
 
-static void __devinit init_vga_switcheroo(struct azx *chip)
+static void init_vga_switcheroo(struct azx *chip)
 {
 	struct pci_dev *p = get_bound_vga(chip->pci);
 	if (p) {
@@ -2697,7 +2841,7 @@
 	.can_switch = azx_vs_can_switch,
 };
 
-static int __devinit register_vga_switcheroo(struct azx *chip)
+static int register_vga_switcheroo(struct azx *chip)
 {
 	int err;
 
@@ -2731,6 +2875,9 @@
 
 	azx_notifier_unregister(chip);
 
+	chip->init_failed = 1; /* to be sure */
+	complete(&chip->probe_wait);
+
 	if (use_vga_switcheroo(chip)) {
 		if (chip->disabled && chip->bus)
 			snd_hda_unlock_devices(chip->bus);
@@ -2789,7 +2936,7 @@
 /*
  * Check of disabled HDMI controller by vga-switcheroo
  */
-static struct pci_dev __devinit *get_bound_vga(struct pci_dev *pci)
+static struct pci_dev *get_bound_vga(struct pci_dev *pci)
 {
 	struct pci_dev *p;
 
@@ -2812,7 +2959,7 @@
 	return NULL;
 }
 
-static bool __devinit check_hdmi_disabled(struct pci_dev *pci)
+static bool check_hdmi_disabled(struct pci_dev *pci)
 {
 	bool vga_inactive = false;
 	struct pci_dev *p = get_bound_vga(pci);
@@ -2829,7 +2976,7 @@
 /*
  * white/black-listing for position_fix
  */
-static struct snd_pci_quirk position_fix_list[] __devinitdata = {
+static struct snd_pci_quirk position_fix_list[] = {
 	SND_PCI_QUIRK(0x1028, 0x01cc, "Dell D820", POS_FIX_LPIB),
 	SND_PCI_QUIRK(0x1028, 0x01de, "Dell Precision 390", POS_FIX_LPIB),
 	SND_PCI_QUIRK(0x103c, 0x306d, "HP dv3", POS_FIX_LPIB),
@@ -2847,7 +2994,7 @@
 	{}
 };
 
-static int __devinit check_position_fix(struct azx *chip, int fix)
+static int check_position_fix(struct azx *chip, int fix)
 {
 	const struct snd_pci_quirk *q;
 
@@ -2871,11 +3018,11 @@
 
 	/* Check VIA/ATI HD Audio Controller exist */
 	if (chip->driver_caps & AZX_DCAPS_POSFIX_VIA) {
-		snd_printd(SFX "Using VIACOMBO position fix\n");
+		snd_printd(SFX "%s: Using VIACOMBO position fix\n", pci_name(chip->pci));
 		return POS_FIX_VIACOMBO;
 	}
 	if (chip->driver_caps & AZX_DCAPS_POSFIX_LPIB) {
-		snd_printd(SFX "Using LPIB position fix\n");
+		snd_printd(SFX "%s: Using LPIB position fix\n", pci_name(chip->pci));
 		return POS_FIX_LPIB;
 	}
 	return POS_FIX_AUTO;
@@ -2884,7 +3031,7 @@
 /*
  * black-lists for probe_mask
  */
-static struct snd_pci_quirk probe_mask_list[] __devinitdata = {
+static struct snd_pci_quirk probe_mask_list[] = {
 	/* Thinkpad often breaks the controller communication when accessing
 	 * to the non-working (or non-existing) modem codec slot.
 	 */
@@ -2905,7 +3052,7 @@
 
 #define AZX_FORCE_CODEC_MASK	0x100
 
-static void __devinit check_probe_mask(struct azx *chip, int dev)
+static void check_probe_mask(struct azx *chip, int dev)
 {
 	const struct snd_pci_quirk *q;
 
@@ -2933,7 +3080,7 @@
 /*
  * white/black-list for enable_msi
  */
-static struct snd_pci_quirk msi_black_list[] __devinitdata = {
+static struct snd_pci_quirk msi_black_list[] = {
 	SND_PCI_QUIRK(0x1043, 0x81f2, "ASUS", 0), /* Athlon64 X2 + nvidia */
 	SND_PCI_QUIRK(0x1043, 0x81f6, "ASUS", 0), /* nvidia */
 	SND_PCI_QUIRK(0x1043, 0x822d, "ASUS", 0), /* Athlon64 X2 + nvidia MCP55 */
@@ -2942,7 +3089,7 @@
 	{}
 };
 
-static void __devinit check_msi(struct azx *chip)
+static void check_msi(struct azx *chip)
 {
 	const struct snd_pci_quirk *q;
 
@@ -2968,7 +3115,7 @@
 }
 
 /* check the snoop mode availability */
-static void __devinit azx_check_snoop_available(struct azx *chip)
+static void azx_check_snoop_available(struct azx *chip)
 {
 	bool snoop = chip->snoop;
 
@@ -2991,8 +3138,8 @@
 	}
 
 	if (snoop != chip->snoop) {
-		snd_printk(KERN_INFO SFX "Force to %s mode\n",
-			   snoop ? "snoop" : "non-snoop");
+		snd_printk(KERN_INFO SFX "%s: Force to %s mode\n",
+			   pci_name(chip->pci), snoop ? "snoop" : "non-snoop");
 		chip->snoop = snoop;
 	}
 }
@@ -3000,9 +3147,9 @@
 /*
  * constructor
  */
-static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci,
-				int dev, unsigned int driver_caps,
-				struct azx **rchip)
+static int azx_create(struct snd_card *card, struct pci_dev *pci,
+		      int dev, unsigned int driver_caps,
+		      struct azx **rchip)
 {
 	static struct snd_device_ops ops = {
 		.dev_free = azx_dev_free,
@@ -3018,7 +3165,7 @@
 
 	chip = kzalloc(sizeof(*chip), GFP_KERNEL);
 	if (!chip) {
-		snd_printk(KERN_ERR SFX "cannot allocate chip\n");
+		snd_printk(KERN_ERR SFX "%s: Cannot allocate chip\n", pci_name(pci));
 		pci_disable_device(pci);
 		return -ENOMEM;
 	}
@@ -3036,6 +3183,7 @@
 	INIT_LIST_HEAD(&chip->pcm_list);
 	INIT_LIST_HEAD(&chip->list);
 	init_vga_switcheroo(chip);
+	init_completion(&chip->probe_wait);
 
 	chip->position_fix[0] = chip->position_fix[1] =
 		check_position_fix(chip, position_fix[dev]);
@@ -3063,29 +3211,10 @@
 		}
 	}
 
-	if (check_hdmi_disabled(pci)) {
-		snd_printk(KERN_INFO SFX "VGA controller for %s is disabled\n",
-			   pci_name(pci));
-		if (use_vga_switcheroo(chip)) {
-			snd_printk(KERN_INFO SFX "Delaying initialization\n");
-			chip->disabled = true;
-			goto ok;
-		}
-		kfree(chip);
-		pci_disable_device(pci);
-		return -ENXIO;
-	}
-
-	err = azx_first_init(chip);
-	if (err < 0) {
-		azx_free(chip);
-		return err;
-	}
-
- ok:
 	err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
 	if (err < 0) {
-		snd_printk(KERN_ERR SFX "Error creating device [card]!\n");
+		snd_printk(KERN_ERR SFX "%s: Error creating device [card]!\n",
+		   pci_name(chip->pci));
 		azx_free(chip);
 		return err;
 	}
@@ -3094,7 +3223,7 @@
 	return 0;
 }
 
-static int DELAYED_INIT_MARK azx_first_init(struct azx *chip)
+static int azx_first_init(struct azx *chip)
 {
 	int dev = chip->dev_index;
 	struct pci_dev *pci = chip->pci;
@@ -3120,7 +3249,7 @@
 	chip->addr = pci_resource_start(pci, 0);
 	chip->remap_addr = pci_ioremap_bar(pci, 0);
 	if (chip->remap_addr == NULL) {
-		snd_printk(KERN_ERR SFX "ioremap error\n");
+		snd_printk(KERN_ERR SFX "%s: ioremap error\n", pci_name(chip->pci));
 		return -ENXIO;
 	}
 
@@ -3135,7 +3264,7 @@
 	synchronize_irq(chip->irq);
 
 	gcap = azx_readw(chip, GCAP);
-	snd_printdd(SFX "chipset global capabilities = 0x%x\n", gcap);
+	snd_printdd(SFX "%s: chipset global capabilities = 0x%x\n", pci_name(chip->pci), gcap);
 
 	/* disable SB600 64bit support for safety */
 	if (chip->pci->vendor == PCI_VENDOR_ID_ATI) {
@@ -3152,7 +3281,7 @@
 
 	/* disable 64bit DMA address on some devices */
 	if (chip->driver_caps & AZX_DCAPS_NO_64BIT) {
-		snd_printd(SFX "Disabling 64bit DMA\n");
+		snd_printd(SFX "%s: Disabling 64bit DMA\n", pci_name(chip->pci));
 		gcap &= ~ICH6_GCAP_64OK;
 	}
 
@@ -3207,7 +3336,7 @@
 	chip->azx_dev = kcalloc(chip->num_streams, sizeof(*chip->azx_dev),
 				GFP_KERNEL);
 	if (!chip->azx_dev) {
-		snd_printk(KERN_ERR SFX "cannot malloc azx_dev\n");
+		snd_printk(KERN_ERR SFX "%s: cannot malloc azx_dev\n", pci_name(chip->pci));
 		return -ENOMEM;
 	}
 
@@ -3217,7 +3346,7 @@
 					  snd_dma_pci_data(chip->pci),
 					  BDL_SIZE, &chip->azx_dev[i].bdl);
 		if (err < 0) {
-			snd_printk(KERN_ERR SFX "cannot allocate BDL\n");
+			snd_printk(KERN_ERR SFX "%s: cannot allocate BDL\n", pci_name(chip->pci));
 			return -ENOMEM;
 		}
 		mark_pages_wc(chip, &chip->azx_dev[i].bdl, true);
@@ -3227,7 +3356,7 @@
 				  snd_dma_pci_data(chip->pci),
 				  chip->num_streams * 8, &chip->posbuf);
 	if (err < 0) {
-		snd_printk(KERN_ERR SFX "cannot allocate posbuf\n");
+		snd_printk(KERN_ERR SFX "%s: cannot allocate posbuf\n", pci_name(chip->pci));
 		return -ENOMEM;
 	}
 	mark_pages_wc(chip, &chip->posbuf, true);
@@ -3245,7 +3374,7 @@
 
 	/* codec detection */
 	if (!chip->codec_mask) {
-		snd_printk(KERN_ERR SFX "no codecs found!\n");
+		snd_printk(KERN_ERR SFX "%s: no codecs found!\n", pci_name(chip->pci));
 		return -ENODEV;
 	}
 
@@ -3281,7 +3410,8 @@
 	struct pci_dev *pci = chip->pci;
 
 	if (!fw) {
-		snd_printk(KERN_ERR SFX "Cannot load firmware, aborting\n");
+		snd_printk(KERN_ERR SFX "%s: Cannot load firmware, aborting\n",
+			   pci_name(chip->pci));
 		goto error;
 	}
 
@@ -3299,8 +3429,8 @@
 }
 #endif
 
-static int __devinit azx_probe(struct pci_dev *pci,
-			       const struct pci_device_id *pci_id)
+static int azx_probe(struct pci_dev *pci,
+		     const struct pci_device_id *pci_id)
 {
 	static int dev;
 	struct snd_card *card;
@@ -3317,7 +3447,7 @@
 
 	err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
 	if (err < 0) {
-		snd_printk(KERN_ERR SFX "Error creating card!\n");
+		snd_printk(KERN_ERR "hda-intel: Error creating card!\n");
 		return err;
 	}
 
@@ -3327,12 +3457,34 @@
 	if (err < 0)
 		goto out_free;
 	card->private_data = chip;
+
+	pci_set_drvdata(pci, card);
+
+	err = register_vga_switcheroo(chip);
+	if (err < 0) {
+		snd_printk(KERN_ERR SFX
+			   "%s: Error registering VGA-switcheroo client\n", pci_name(pci));
+		goto out_free;
+	}
+
+	if (check_hdmi_disabled(pci)) {
+		snd_printk(KERN_INFO SFX "%s: VGA controller is disabled\n",
+			   pci_name(pci));
+		snd_printk(KERN_INFO SFX "%s: Delaying initialization\n", pci_name(pci));
+		chip->disabled = true;
+	}
+
 	probe_now = !chip->disabled;
+	if (probe_now) {
+		err = azx_first_init(chip);
+		if (err < 0)
+			goto out_free;
+	}
 
 #ifdef CONFIG_SND_HDA_PATCH_LOADER
 	if (patch[dev] && *patch[dev]) {
-		snd_printk(KERN_ERR SFX "Applying patch firmware '%s'\n",
-			   patch[dev]);
+		snd_printk(KERN_ERR SFX "%s: Applying patch firmware '%s'\n",
+			   pci_name(pci), patch[dev]);
 		err = request_firmware_nowait(THIS_MODULE, true, patch[dev],
 					      &pci->dev, GFP_KERNEL, card,
 					      azx_firmware_cb);
@@ -3348,27 +3500,20 @@
 			goto out_free;
 	}
 
-	pci_set_drvdata(pci, card);
-
 	if (pci_dev_run_wake(pci))
 		pm_runtime_put_noidle(&pci->dev);
 
-	err = register_vga_switcheroo(chip);
-	if (err < 0) {
-		snd_printk(KERN_ERR SFX
-			   "Error registering VGA-switcheroo client\n");
-		goto out_free;
-	}
-
 	dev++;
+	complete(&chip->probe_wait);
 	return 0;
 
 out_free:
 	snd_card_free(card);
+	pci_set_drvdata(pci, NULL);
 	return err;
 }
 
-static int DELAYED_INIT_MARK azx_probe_continue(struct azx *chip)
+static int azx_probe_continue(struct azx *chip)
 {
 	int dev = chip->dev_index;
 	int err;
@@ -3387,8 +3532,10 @@
 					 chip->fw->data);
 		if (err < 0)
 			goto out_free;
+#ifndef CONFIG_PM
 		release_firmware(chip->fw); /* no longer needed */
 		chip->fw = NULL;
+#endif
 	}
 #endif
 	if ((probe_only[dev] & 1) == 0) {
@@ -3423,7 +3570,7 @@
 	return err;
 }
 
-static void __devexit azx_remove(struct pci_dev *pci)
+static void azx_remove(struct pci_dev *pci)
 {
 	struct snd_card *card = pci_get_drvdata(pci);
 
@@ -3610,7 +3757,7 @@
 	.name = KBUILD_MODNAME,
 	.id_table = azx_ids,
 	.probe = azx_probe,
-	.remove = __devexit_p(azx_remove),
+	.remove = azx_remove,
 	.driver = {
 		.pm = AZX_PM_OPS,
 	},
diff --git a/sound/pci/hda/hda_intel_trace.h b/sound/pci/hda/hda_intel_trace.h
new file mode 100644
index 0000000..7b5e4c2
--- /dev/null
+++ b/sound/pci/hda/hda_intel_trace.h
@@ -0,0 +1,62 @@
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM hda_intel
+#define TRACE_INCLUDE_FILE hda_intel_trace
+
+#if !defined(_TRACE_HDA_INTEL_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_HDA_INTEL_H
+
+#include <linux/tracepoint.h>
+
+struct azx;
+struct azx_dev;
+
+TRACE_EVENT(azx_pcm_trigger,
+
+	TP_PROTO(struct azx *chip, struct azx_dev *dev, int cmd),
+
+	TP_ARGS(chip, dev, cmd),
+
+	TP_STRUCT__entry(
+		__field( int, card )
+		__field( int, idx )
+		__field( int, cmd )
+	),
+
+	TP_fast_assign(
+		__entry->card = (chip)->card->number;
+		__entry->idx = (dev)->index;
+		__entry->cmd = cmd;
+	),
+
+	TP_printk("[%d:%d] cmd=%d", __entry->card, __entry->idx, __entry->cmd)
+);
+
+TRACE_EVENT(azx_get_position,
+
+    TP_PROTO(struct azx *chip, struct azx_dev *dev, unsigned int pos, unsigned int delay),
+
+	    TP_ARGS(chip, dev, pos, delay),
+
+	TP_STRUCT__entry(
+		__field( int, card )
+		__field( int, idx )
+		__field( unsigned int, pos )
+		__field( unsigned int, delay )
+	),
+
+	TP_fast_assign(
+		__entry->card = (chip)->card->number;
+		__entry->idx = (dev)->index;
+		__entry->pos = pos;
+		__entry->delay = delay;
+	),
+
+	TP_printk("[%d:%d] pos=%u, delay=%u", __entry->card, __entry->idx, __entry->pos, __entry->delay)
+);
+
+#endif /* _TRACE_HDA_INTEL_H */
+
+/* This part must be outside protection */
+#undef TRACE_INCLUDE_PATH
+#define TRACE_INCLUDE_PATH .
+#include <trace/define_trace.h>
diff --git a/sound/pci/hda/hda_jack.c b/sound/pci/hda/hda_jack.c
index 5c690cb..6e9f57b 100644
--- a/sound/pci/hda/hda_jack.c
+++ b/sound/pci/hda/hda_jack.c
@@ -95,7 +95,6 @@
 	struct hda_jack_tbl *jack = snd_hda_jack_tbl_get(codec, nid);
 	if (jack)
 		return jack;
-	snd_array_init(&codec->jacktbl, sizeof(*jack), 16);
 	jack = snd_array_new(&codec->jacktbl);
 	if (!jack)
 		return NULL;
@@ -122,6 +121,8 @@
 	snd_array_free(&codec->jacktbl);
 }
 
+#define get_jack_plug_state(sense) !!(sense & AC_PINSENSE_PRESENCE)
+
 /* update the cached value and notification flag if needed */
 static void jack_detect_update(struct hda_codec *codec,
 			       struct hda_jack_tbl *jack)
@@ -134,7 +135,21 @@
 	else
 		jack->pin_sense = read_pin_sense(codec, jack->nid);
 
+	/* A gating jack indicates the jack is invalid if gating is unplugged */
+	if (jack->gating_jack && !snd_hda_jack_detect(codec, jack->gating_jack))
+		jack->pin_sense &= ~AC_PINSENSE_PRESENCE;
+
 	jack->jack_dirty = 0;
+
+	/* If a jack is gated by this one update it. */
+	if (jack->gated_jack) {
+		struct hda_jack_tbl *gated =
+			snd_hda_jack_tbl_get(codec, jack->gated_jack);
+		if (gated) {
+			gated->jack_dirty = 1;
+			jack_detect_update(codec, gated);
+		}
+	}
 }
 
 /**
@@ -173,8 +188,6 @@
 }
 EXPORT_SYMBOL_HDA(snd_hda_pin_sense);
 
-#define get_jack_plug_state(sense) !!(sense & AC_PINSENSE_PRESENCE)
-
 /**
  * snd_hda_jack_detect - query pin Presence Detect status
  * @codec: the CODEC to sense
@@ -206,6 +219,8 @@
 		jack->action = action;
 	if (cb)
 		jack->callback = cb;
+	if (codec->jackpoll_interval > 0)
+		return 0; /* No unsol if we're polling instead */
 	return snd_hda_codec_write_cache(codec, nid, 0,
 					 AC_VERB_SET_UNSOLICITED_ENABLE,
 					 AC_USRSP_EN | jack->tag);
@@ -220,16 +235,46 @@
 EXPORT_SYMBOL_HDA(snd_hda_jack_detect_enable);
 
 /**
+ * snd_hda_jack_set_gating_jack - Set gating jack.
+ *
+ * Indicates the gated jack is only valid when the gating jack is plugged.
+ */
+int snd_hda_jack_set_gating_jack(struct hda_codec *codec, hda_nid_t gated_nid,
+				 hda_nid_t gating_nid)
+{
+	struct hda_jack_tbl *gated = snd_hda_jack_tbl_get(codec, gated_nid);
+	struct hda_jack_tbl *gating = snd_hda_jack_tbl_get(codec, gating_nid);
+
+	if (!gated || !gating)
+		return -EINVAL;
+
+	gated->gating_jack = gating_nid;
+	gating->gated_jack = gated_nid;
+
+	return 0;
+}
+EXPORT_SYMBOL_HDA(snd_hda_jack_set_gating_jack);
+
+/**
  * snd_hda_jack_report_sync - sync the states of all jacks and report if changed
  */
 void snd_hda_jack_report_sync(struct hda_codec *codec)
 {
-	struct hda_jack_tbl *jack = codec->jacktbl.list;
+	struct hda_jack_tbl *jack;
 	int i, state;
 
+	/* update all jacks at first */
+	jack = codec->jacktbl.list;
+	for (i = 0; i < codec->jacktbl.used; i++, jack++)
+		if (jack->nid)
+			jack_detect_update(codec, jack);
+
+	/* report the updated jacks; it's done after updating all jacks
+	 * to make sure that all gating jacks properly have been set
+	 */
+	jack = codec->jacktbl.list;
 	for (i = 0; i < codec->jacktbl.used; i++, jack++)
 		if (jack->nid) {
-			jack_detect_update(codec, jack);
 			if (!jack->kctl)
 				continue;
 			state = get_jack_plug_state(jack->pin_sense);
@@ -422,6 +467,19 @@
 }
 EXPORT_SYMBOL_HDA(snd_hda_jack_add_kctls);
 
+static void call_jack_callback(struct hda_codec *codec,
+			       struct hda_jack_tbl *jack)
+{
+	if (jack->callback)
+		jack->callback(codec, jack);
+	if (jack->gated_jack) {
+		struct hda_jack_tbl *gated =
+			snd_hda_jack_tbl_get(codec, jack->gated_jack);
+		if (gated && gated->callback)
+			gated->callback(codec, gated);
+	}
+}
+
 void snd_hda_jack_unsol_event(struct hda_codec *codec, unsigned int res)
 {
 	struct hda_jack_tbl *event;
@@ -432,10 +490,29 @@
 		return;
 	event->jack_dirty = 1;
 
-	if (event->callback)
-		event->callback(codec, event);
-
+	call_jack_callback(codec, event);
 	snd_hda_jack_report_sync(codec);
 }
 EXPORT_SYMBOL_HDA(snd_hda_jack_unsol_event);
 
+void snd_hda_jack_poll_all(struct hda_codec *codec)
+{
+	struct hda_jack_tbl *jack = codec->jacktbl.list;
+	int i, changes = 0;
+
+	for (i = 0; i < codec->jacktbl.used; i++, jack++) {
+		unsigned int old_sense;
+		if (!jack->nid || !jack->jack_dirty || jack->phantom_jack)
+			continue;
+		old_sense = get_jack_plug_state(jack->pin_sense);
+		jack_detect_update(codec, jack);
+		if (old_sense == get_jack_plug_state(jack->pin_sense))
+			continue;
+		changes = 1;
+		call_jack_callback(codec, jack);
+	}
+	if (changes)
+		snd_hda_jack_report_sync(codec);
+}
+EXPORT_SYMBOL_HDA(snd_hda_jack_poll_all);
+
diff --git a/sound/pci/hda/hda_jack.h b/sound/pci/hda/hda_jack.h
index af8dd47..ec12abd 100644
--- a/sound/pci/hda/hda_jack.h
+++ b/sound/pci/hda/hda_jack.h
@@ -28,6 +28,8 @@
 	unsigned int jack_detect:1;	/* capable of jack-detection? */
 	unsigned int jack_dirty:1;	/* needs to update? */
 	unsigned int phantom_jack:1;    /* a fixed, always present port? */
+	hda_nid_t gating_jack;		/* valid when gating jack plugged */
+	hda_nid_t gated_jack;		/* gated is dependent on this jack */
 	struct snd_kcontrol *kctl;	/* assigned kctl for jack-detection */
 #ifdef CONFIG_SND_HDA_INPUT_JACK
 	int type;
@@ -69,6 +71,8 @@
 					unsigned char action,
 					hda_jack_callback cb);
 
+int snd_hda_jack_set_gating_jack(struct hda_codec *codec, hda_nid_t gated_nid,
+				 hda_nid_t gating_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);
@@ -84,4 +88,6 @@
 
 void snd_hda_jack_unsol_event(struct hda_codec *codec, unsigned int res);
 
+void snd_hda_jack_poll_all(struct hda_codec *codec);
+
 #endif /* __SOUND_HDA_JACK_H */
diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h
index 09dbdc3..4b40a5e 100644
--- a/sound/pci/hda/hda_local.h
+++ b/sound/pci/hda/hda_local.h
@@ -240,9 +240,11 @@
 /*
  * SPDIF I/O
  */
-int snd_hda_create_spdif_out_ctls(struct hda_codec *codec,
-				  hda_nid_t associated_nid,
-				  hda_nid_t cvt_nid);
+int snd_hda_create_dig_out_ctls(struct hda_codec *codec,
+				hda_nid_t associated_nid,
+				hda_nid_t cvt_nid, int type);
+#define snd_hda_create_spdif_out_ctls(codec, anid, cnid) \
+	snd_hda_create_dig_out_ctls(codec, anid, cnid, HDA_PCM_TYPE_SPDIF)
 int snd_hda_create_spdif_in_ctls(struct hda_codec *codec, hda_nid_t nid);
 
 /*
@@ -599,6 +601,15 @@
 #define get_amp_min_mute(kc)	(((kc)->private_value >> 29) & 0x1)
 
 /*
+ * enum control helper
+ */
+int snd_hda_enum_helper_info(struct snd_kcontrol *kcontrol,
+			     struct snd_ctl_elem_info *uinfo,
+			     int num_entries, const char * const *texts);
+#define snd_hda_enum_bool_helper_info(kcontrol, uinfo) \
+	snd_hda_enum_helper_info(kcontrol, uinfo, 0, NULL)
+
+/*
  * CEA Short Audio Descriptor data
  */
 struct cea_sad {
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c
index 1eeba73..89fc503 100644
--- a/sound/pci/hda/patch_analog.c
+++ b/sound/pci/hda/patch_analog.c
@@ -636,7 +636,6 @@
 	if (!spec)
 		return;
 
-	ad198x_shutup(codec);
 	ad198x_free_kctls(codec);
 	kfree(spec);
 	snd_hda_detach_beep_device(codec);
@@ -1247,16 +1246,27 @@
 	return get_defcfg_connect(conf) != AC_JACK_PORT_NONE;
 }
 
+static int alloc_ad_spec(struct hda_codec *codec)
+{
+	struct ad198x_spec *spec;
+
+	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
+	if (!spec)
+		return -ENOMEM;
+	codec->spec = spec;
+	snd_array_init(&spec->kctls, sizeof(struct snd_kcontrol_new), 32);
+	return 0;
+}
+
 static int patch_ad1986a(struct hda_codec *codec)
 {
 	struct ad198x_spec *spec;
 	int err, board_config;
 
-	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
-	if (spec == NULL)
-		return -ENOMEM;
-
-	codec->spec = spec;
+	err = alloc_ad_spec(codec);
+	if (err < 0)
+		return err;
+	spec = codec->spec;
 
 	err = snd_hda_attach_beep_device(codec, 0x19);
 	if (err < 0) {
@@ -1549,11 +1559,10 @@
 	struct ad198x_spec *spec;
 	int err;
 
-	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
-	if (spec == NULL)
-		return -ENOMEM;
-
-	codec->spec = spec;
+	err = alloc_ad_spec(codec);
+	if (err < 0)
+		return err;
+	spec = codec->spec;
 
 	err = snd_hda_attach_beep_device(codec, 0x10);
 	if (err < 0) {
@@ -1955,11 +1964,10 @@
 	struct ad198x_spec *spec;
 	int err, board_config;
 
-	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
-	if (spec == NULL)
+	err = alloc_ad_spec(codec);
+	if (err < 0)
 		return -ENOMEM;
-
-	codec->spec = spec;
+	spec = codec->spec;
 
 	err = snd_hda_attach_beep_device(codec, 0x10);
 	if (err < 0) {
@@ -2837,7 +2845,6 @@
 {
 	struct snd_kcontrol_new *knew;
 
-	snd_array_init(&spec->kctls, sizeof(*knew), 32);
 	knew = snd_array_new(&spec->kctls);
 	if (!knew)
 		return -ENOMEM;
@@ -3255,11 +3262,10 @@
 	struct ad198x_spec *spec;
 	int err, board_config;
 
-	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
-	if (spec == NULL)
-		return -ENOMEM;
-
-	codec->spec = spec;
+	err = alloc_ad_spec(codec);
+	if (err < 0)
+		return err;
+	spec = codec->spec;
 
 	if (is_rev2(codec))
 		snd_printk(KERN_INFO "patch_analog: AD1988A rev.2 is detected, enable workarounds\n");
@@ -3575,11 +3581,10 @@
 	struct ad198x_spec *spec;
 	int err;
 
-	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
-	if (spec == NULL)
-		return -ENOMEM;
-
-	codec->spec = spec;
+	err = alloc_ad_spec(codec);
+	if (err < 0)
+		return err;
+	spec = codec->spec;
 
 	err = snd_hda_attach_beep_device(codec, 0x10);
 	if (err < 0) {
@@ -4575,11 +4580,10 @@
 	struct ad198x_spec *spec;
 	int err, board_config;
 
-	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
-	if (spec == NULL)
-		return -ENOMEM;
-
-	codec->spec = spec;
+	err = alloc_ad_spec(codec);
+	if (err < 0)
+		return err;
+	spec = codec->spec;
 
 	err = snd_hda_attach_beep_device(codec, 0x10);
 	if (err < 0) {
@@ -4988,11 +4992,10 @@
 	struct ad198x_spec *spec;
 	int err, board_config;
 
-	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
-	if (spec == NULL)
-		return -ENOMEM;
-
-	codec->spec = spec;
+	err = alloc_ad_spec(codec);
+	if (err < 0)
+		return err;
+	spec = codec->spec;
 
 	err = snd_hda_attach_beep_device(codec, 0x10);
 	if (err < 0) {
diff --git a/sound/pci/hda/patch_cirrus.c b/sound/pci/hda/patch_cirrus.c
index 3bcb671..a2537b2 100644
--- a/sound/pci/hda/patch_cirrus.c
+++ b/sound/pci/hda/patch_cirrus.c
@@ -68,6 +68,7 @@
 
 	unsigned int hp_detect:1;
 	unsigned int mic_detect:1;
+	unsigned int speaker_2_1:1;
 	/* CS421x */
 	unsigned int spdif_detect:1;
 	unsigned int sense_b:1;
@@ -84,7 +85,7 @@
 	CS420X_GPIO_13,
 	CS420X_GPIO_23,
 	CS420X_MBP101,
-	CS420X_MBP101_COEF,
+	CS420X_MBP81,
 	CS420X_AUTO,
 	/* aliases */
 	CS420X_IMAC27_122 = CS420X_GPIO_23,
@@ -343,6 +344,9 @@
 	info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->dac_nid[0];
 	info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max =
 		spec->multiout.max_channels;
+	if (spec->speaker_2_1)
+		info->stream[SNDRV_PCM_STREAM_PLAYBACK].chmap =
+			snd_pcm_2_1_chmaps;
 	info->stream[SNDRV_PCM_STREAM_CAPTURE] = cs_pcm_analog_capture;
 	info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
 		spec->adc_nid[spec->cur_input];
@@ -443,6 +447,9 @@
 	spec->multiout.dac_nids = spec->dac_nid;
 	spec->multiout.max_channels = i * 2;
 
+	if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT && i == 2)
+		spec->speaker_2_1 = 1; /* assume 2.1 speakers */
+
 	/* add HP and speakers */
 	extra_nids = 0;
 	for (i = 0; i < cfg->hp_outs; i++) {
@@ -633,7 +640,9 @@
 		index = idx;
 		break;
 	case AUTO_PIN_SPEAKER_OUT:
-		if (num_ctls > 1)
+		if (spec->speaker_2_1)
+			name = idx ? "Bass Speaker" : "Speaker";
+		else if (num_ctls > 1)
 			name = speakers[idx];
 		else
 			name = "Speaker";
@@ -874,8 +883,9 @@
 	if (!spec->multiout.dig_out_nid)
 		return 0;
 
-	err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid,
-					    spec->multiout.dig_out_nid);
+	err = snd_hda_create_dig_out_ctls(codec, spec->multiout.dig_out_nid,
+					  spec->multiout.dig_out_nid,
+					  spec->pcm_rec[1].pcm_type);
 	if (err < 0)
 		return err;
 	err = snd_hda_create_spdif_share_sw(codec, &spec->multiout);
@@ -1079,9 +1089,6 @@
 		if (spec->mic_detect)
 			cs_automic(codec, NULL);
 
-		coef = 0x000a; /* ADC1/2 - Digital and Analog Soft Ramp */
-		cs_vendor_coef_set(codec, IDX_ADC_CFG, coef);
-
 		coef = cs_vendor_coef_get(codec, IDX_BEEP_CFG);
 		if (is_active_pin(codec, CS_DMIC2_PIN_NID))
 			coef |= 1 << 4; /* DMIC2 2 chan on, GPIO1 off */
@@ -1111,6 +1118,9 @@
 	  | 0x1000 /* Enable DACs High Pass Filter */
 	  | 0x0400 /* Disable Coefficient Auto increment */
 	  )},
+	/* ADC1/2 - Digital and Analog Soft Ramp */
+	{0x11, AC_VERB_SET_COEF_INDEX, IDX_ADC_CFG},
+	{0x11, AC_VERB_SET_PROC_COEF, 0x000a},
 	/* Beep */
 	{0x11, AC_VERB_SET_COEF_INDEX, IDX_BEEP_CFG},
 	{0x11, AC_VERB_SET_PROC_COEF, 0x0007}, /* Enable Beep thru DAC1/2/3 */
@@ -1167,14 +1177,6 @@
 	{} /* terminator */
 };
 
-static const struct hda_verb mbp101_init_verbs[] = {
-	{0x11, AC_VERB_SET_COEF_INDEX, 0x0002},
-	{0x11, AC_VERB_SET_PROC_COEF, 0x100a},
-	{0x11, AC_VERB_SET_COEF_INDEX, 0x0004},
-	{0x11, AC_VERB_SET_PROC_COEF, 0x000f},
-	{}
-};
-
 /* SPDIF setup */
 static void init_digital(struct hda_codec *codec)
 {
@@ -1199,6 +1201,8 @@
 
 	snd_hda_sequence_write(codec, cs_coef_init_verbs);
 
+	snd_hda_gen_apply_verbs(codec);
+
 	if (spec->gpio_mask) {
 		snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_MASK,
 				    spec->gpio_mask);
@@ -1291,6 +1295,7 @@
 	{ .id = CS420X_IMAC27_122, .name = "imac27_122" },
 	{ .id = CS420X_APPLE, .name = "apple" },
 	{ .id = CS420X_MBP101, .name = "mbp101" },
+	{ .id = CS420X_MBP81, .name = "mbp81" },
 	{}
 };
 
@@ -1303,6 +1308,7 @@
 	/*SND_PCI_QUIRK(0x8086, 0x7270, "IMac 27 Inch", CS420X_IMAC27),*/
 
 	/* codec SSID */
+	SND_PCI_QUIRK(0x106b, 0x1c00, "MacBookPro 8,1", CS420X_MBP81),
 	SND_PCI_QUIRK(0x106b, 0x2000, "iMac 12,2", CS420X_IMAC27_122),
 	SND_PCI_QUIRK(0x106b, 0x2800, "MacBookPro 10,1", CS420X_MBP101),
 	SND_PCI_QUIRK_VENDOR(0x106b, "Apple", CS420X_APPLE),
@@ -1413,11 +1419,16 @@
 		.type = HDA_FIXUP_PINS,
 		.v.pins = mbp101_pincfgs,
 		.chained = true,
-		.chain_id = CS420X_MBP101_COEF,
+		.chain_id = CS420X_GPIO_13,
 	},
-	[CS420X_MBP101_COEF] = {
+	[CS420X_MBP81] = {
 		.type = HDA_FIXUP_VERBS,
-		.v.verbs = mbp101_init_verbs,
+		.v.verbs = (const struct hda_verb[]) {
+			/* internal mic ADC2: right only, single ended */
+			{0x11, AC_VERB_SET_COEF_INDEX, IDX_ADC_CFG},
+			{0x11, AC_VERB_SET_PROC_COEF, 0x102a},
+			{}
+		},
 		.chained = true,
 		.chain_id = CS420X_GPIO_13,
 	},
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index 03b1dc3..60890bf 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -337,6 +337,8 @@
 	},
 };
 
+static bool is_2_1_speaker(struct conexant_spec *spec);
+
 static int conexant_build_pcms(struct hda_codec *codec)
 {
 	struct conexant_spec *spec = codec->spec;
@@ -351,6 +353,9 @@
 		spec->multiout.max_channels;
 	info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
 		spec->multiout.dac_nids[0];
+	if (is_2_1_speaker(spec))
+		info->stream[SNDRV_PCM_STREAM_PLAYBACK].chmap =
+			snd_pcm_2_1_chmaps;
 	if (spec->capture_stream)
 		info->stream[SNDRV_PCM_STREAM_CAPTURE] = *spec->capture_stream;
 	else {
@@ -472,7 +477,7 @@
 #endif
 
 static const char * const slave_pfxs[] = {
-	"Headphone", "Speaker", "Front", "Surround", "CLFE",
+	"Headphone", "Speaker", "Bass Speaker", "Front", "Surround", "CLFE",
 	NULL
 };
 
@@ -3430,28 +3435,13 @@
 {
 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 	struct conexant_spec *spec = codec->spec;
-	static const char * const texts2[] = {
-		"Disabled", "Enabled"
-	};
 	static const char * const texts3[] = {
 		"Disabled", "Speaker Only", "Line Out+Speaker"
 	};
-	const char * const *texts;
 
-	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
-	uinfo->count = 1;
-	if (spec->automute_hp_lo) {
-		uinfo->value.enumerated.items = 3;
-		texts = texts3;
-	} else {
-		uinfo->value.enumerated.items = 2;
-		texts = texts2;
-	}
-	if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
-		uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
-	strcpy(uinfo->value.enumerated.name,
-	       texts[uinfo->value.enumerated.item]);
-	return 0;
+	if (spec->automute_hp_lo)
+		return snd_hda_enum_helper_info(kcontrol, uinfo, 3, texts3);
+	return snd_hda_enum_bool_helper_info(kcontrol, uinfo);
 }
 
 static int cx_automute_mode_get(struct snd_kcontrol *kcontrol,
@@ -4116,11 +4106,26 @@
 	return 0;
 }
 
+static bool is_2_1_speaker(struct conexant_spec *spec)
+{
+	int i, type, num_spk = 0;
+
+	for (i = 0; i < spec->dac_info_filled; i++) {
+		type = spec->dac_info[i].type;
+		if (type == AUTO_PIN_LINE_OUT)
+			type = spec->autocfg.line_out_type;
+		if (type == AUTO_PIN_SPEAKER_OUT)
+			num_spk++;
+	}
+	return (num_spk == 2 && spec->autocfg.line_out_type != AUTO_PIN_LINE_OUT);
+}
+
 static int cx_auto_build_output_controls(struct hda_codec *codec)
 {
 	struct conexant_spec *spec = codec->spec;
 	int i, err;
 	int num_line = 0, num_hp = 0, num_spk = 0;
+	bool speaker_2_1;
 	static const char * const texts[3] = { "Front", "Surround", "CLFE" };
 
 	if (spec->dac_info_filled == 1)
@@ -4128,6 +4133,8 @@
 					 spec->dac_info[0].pin,
 					 "Master", 0);
 
+	speaker_2_1 = is_2_1_speaker(spec);
+
 	for (i = 0; i < spec->dac_info_filled; i++) {
 		const char *label;
 		int idx, type;
@@ -4146,8 +4153,13 @@
 			idx = num_hp++;
 			break;
 		case AUTO_PIN_SPEAKER_OUT:
-			label = "Speaker";
-			idx = num_spk++;
+			if (speaker_2_1) {
+				label = num_spk++ ? "Bass Speaker" : "Speaker";
+				idx = 0;
+			} else {
+				label = "Speaker";
+				idx = num_spk++;
+			}
 			break;
 		}
 		err = try_add_pb_volume(codec, dac,
@@ -4405,7 +4417,10 @@
 enum {
 	CXT_PINCFG_LENOVO_X200,
 	CXT_PINCFG_LENOVO_TP410,
+	CXT_PINCFG_LEMOTE_A1004,
+	CXT_PINCFG_LEMOTE_A1205,
 	CXT_FIXUP_STEREO_DMIC,
+	CXT_FIXUP_INC_MIC_BOOST,
 };
 
 static void cxt_fixup_stereo_dmic(struct hda_codec *codec,
@@ -4415,6 +4430,19 @@
 	spec->fixup_stereo_dmic = 1;
 }
 
+static void cxt5066_increase_mic_boost(struct hda_codec *codec,
+				   const struct hda_fixup *fix, int action)
+{
+	if (action != HDA_FIXUP_ACT_PRE_PROBE)
+		return;
+
+	snd_hda_override_amp_caps(codec, 0x17, HDA_OUTPUT,
+				  (0x3 << AC_AMPCAP_OFFSET_SHIFT) |
+				  (0x4 << AC_AMPCAP_NUM_STEPS_SHIFT) |
+				  (0x27 << AC_AMPCAP_STEP_SIZE_SHIFT) |
+				  (0 << AC_AMPCAP_MUTE_SHIFT));
+}
+
 /* ThinkPad X200 & co with cxt5051 */
 static const struct hda_pintbl cxt_pincfg_lenovo_x200[] = {
 	{ 0x16, 0x042140ff }, /* HP (seq# overridden) */
@@ -4432,6 +4460,18 @@
 	{}
 };
 
+/* Lemote A1004/A1205 with cxt5066 */
+static const struct hda_pintbl cxt_pincfg_lemote[] = {
+	{ 0x1a, 0x90a10020 }, /* Internal mic */
+	{ 0x1b, 0x03a11020 }, /* External mic */
+	{ 0x1d, 0x400101f0 }, /* Not used */
+	{ 0x1e, 0x40a701f0 }, /* Not used */
+	{ 0x20, 0x404501f0 }, /* Not used */
+	{ 0x22, 0x404401f0 }, /* Not used */
+	{ 0x23, 0x40a701f0 }, /* Not used */
+	{}
+};
+
 static const struct hda_fixup cxt_fixups[] = {
 	[CXT_PINCFG_LENOVO_X200] = {
 		.type = HDA_FIXUP_PINS,
@@ -4441,10 +4481,24 @@
 		.type = HDA_FIXUP_PINS,
 		.v.pins = cxt_pincfg_lenovo_tp410,
 	},
+	[CXT_PINCFG_LEMOTE_A1004] = {
+		.type = HDA_FIXUP_PINS,
+		.chained = true,
+		.chain_id = CXT_FIXUP_INC_MIC_BOOST,
+		.v.pins = cxt_pincfg_lemote,
+	},
+	[CXT_PINCFG_LEMOTE_A1205] = {
+		.type = HDA_FIXUP_PINS,
+		.v.pins = cxt_pincfg_lemote,
+	},
 	[CXT_FIXUP_STEREO_DMIC] = {
 		.type = HDA_FIXUP_FUNC,
 		.v.func = cxt_fixup_stereo_dmic,
 	},
+	[CXT_FIXUP_INC_MIC_BOOST] = {
+		.type = HDA_FIXUP_FUNC,
+		.v.func = cxt5066_increase_mic_boost,
+	},
 };
 
 static const struct snd_pci_quirk cxt5051_fixups[] = {
@@ -4453,6 +4507,7 @@
 };
 
 static const struct snd_pci_quirk cxt5066_fixups[] = {
+	SND_PCI_QUIRK(0x1025, 0x0543, "Acer Aspire One 522", CXT_FIXUP_STEREO_DMIC),
 	SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo T400", CXT_PINCFG_LENOVO_TP410),
 	SND_PCI_QUIRK(0x17aa, 0x215e, "Lenovo T410", CXT_PINCFG_LENOVO_TP410),
 	SND_PCI_QUIRK(0x17aa, 0x215f, "Lenovo T510", CXT_PINCFG_LENOVO_TP410),
@@ -4461,6 +4516,8 @@
 	SND_PCI_QUIRK(0x17aa, 0x3975, "Lenovo U300s", CXT_FIXUP_STEREO_DMIC),
 	SND_PCI_QUIRK(0x17aa, 0x3977, "Lenovo IdeaPad U310", CXT_FIXUP_STEREO_DMIC),
 	SND_PCI_QUIRK(0x17aa, 0x397b, "Lenovo S205", CXT_FIXUP_STEREO_DMIC),
+	SND_PCI_QUIRK(0x1c06, 0x2011, "Lemote A1004", CXT_PINCFG_LEMOTE_A1004),
+	SND_PCI_QUIRK(0x1c06, 0x2012, "Lemote A1205", CXT_PINCFG_LEMOTE_A1205),
 	{}
 };
 
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
index 71555cc..0fcfa6f 100644
--- a/sound/pci/hda/patch_hdmi.c
+++ b/sound/pci/hda/patch_hdmi.c
@@ -1193,12 +1193,11 @@
 	struct hdmi_spec_per_pin *per_pin;
 	int err;
 
-	caps = snd_hda_param_read(codec, pin_nid, AC_PAR_PIN_CAP);
+	caps = snd_hda_query_pin_caps(codec, pin_nid);
 	if (!(caps & (AC_PINCAP_HDMI | AC_PINCAP_DP)))
 		return 0;
 
-	config = snd_hda_codec_read(codec, pin_nid, 0,
-				AC_VERB_GET_CONFIG_DEFAULT, 0);
+	config = snd_hda_codec_get_pincfg(codec, pin_nid);
 	if (get_defcfg_connect(config) == AC_JACK_PORT_NONE)
 		return 0;
 
@@ -1272,7 +1271,7 @@
 		unsigned int caps;
 		unsigned int type;
 
-		caps = snd_hda_param_read(codec, nid, AC_PAR_AUDIO_WIDGET_CAP);
+		caps = get_wcaps(codec, nid);
 		type = get_wcaps_type(caps);
 
 		if (!(caps & AC_WCAP_DIGITAL))
@@ -1288,13 +1287,17 @@
 		}
 	}
 
+#ifdef CONFIG_PM
+	/* We're seeing some problems with unsolicited hot plug events on
+	 * PantherPoint after S3, if this is not enabled */
+	if (codec->vendor_id == 0x80862806)
+		codec->bus->power_keep_link_on = 1;
 	/*
 	 * G45/IbexPeak don't support EPSS: the unsolicited pin hot plug event
 	 * can be lost and presence sense verb will become inaccurate if the
 	 * HDA link is powered off at hot plug or hw initialization time.
 	 */
-#ifdef CONFIG_PM
-	if (!(snd_hda_param_read(codec, codec->afg, AC_PAR_POWER_STATE) &
+	else if (!(snd_hda_param_read(codec, codec->afg, AC_PAR_POWER_STATE) &
 	      AC_PWRST_EPSS))
 		codec->bus->power_keep_link_on = 1;
 #endif
@@ -1589,9 +1592,10 @@
 		if (err < 0)
 			return err;
 
-		err = snd_hda_create_spdif_out_ctls(codec,
-						    per_pin->pin_nid,
-						    per_pin->mux_nids[0]);
+		err = snd_hda_create_dig_out_ctls(codec,
+						  per_pin->pin_nid,
+						  per_pin->mux_nids[0],
+						  HDA_PCM_TYPE_HDMI);
 		if (err < 0)
 			return err;
 		snd_hda_spdif_ctls_unassign(codec, pin_idx);
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index ad68d22..7743775 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -153,8 +153,8 @@
 	const struct hda_channel_mode *channel_mode;
 	int num_channel_mode;
 	int need_dac_fix;
-	int const_channel_count;
-	int ext_channel_count;
+	int const_channel_count;	/* min. channel count (for speakers) */
+	int ext_channel_count;		/* current channel count for multi-io */
 
 	/* PCM information */
 	struct hda_pcm pcm_rec[3];	/* used in alc_build_pcms() */
@@ -815,28 +815,13 @@
 {
 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 	struct alc_spec *spec = codec->spec;
-	static const char * const texts2[] = {
-		"Disabled", "Enabled"
-	};
 	static const char * const texts3[] = {
 		"Disabled", "Speaker Only", "Line Out+Speaker"
 	};
-	const char * const *texts;
 
-	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
-	uinfo->count = 1;
-	if (spec->automute_speaker_possible && spec->automute_lo_possible) {
-		uinfo->value.enumerated.items = 3;
-		texts = texts3;
-	} else {
-		uinfo->value.enumerated.items = 2;
-		texts = texts2;
-	}
-	if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
-		uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
-	strcpy(uinfo->value.enumerated.name,
-	       texts[uinfo->value.enumerated.item]);
-	return 0;
+	if (spec->automute_speaker_possible && spec->automute_lo_possible)
+		return snd_hda_enum_helper_info(kcontrol, uinfo, 3, texts3);
+	return snd_hda_enum_bool_helper_info(kcontrol, uinfo);
 }
 
 static int alc_automute_mode_get(struct snd_kcontrol *kcontrol,
@@ -903,23 +888,25 @@
 	.put = alc_automute_mode_put,
 };
 
-static struct snd_kcontrol_new *alc_kcontrol_new(struct alc_spec *spec)
+static struct snd_kcontrol_new *
+alc_kcontrol_new(struct alc_spec *spec, const char *name,
+		 const struct snd_kcontrol_new *temp)
 {
-	snd_array_init(&spec->kctls, sizeof(struct snd_kcontrol_new), 32);
-	return snd_array_new(&spec->kctls);
+	struct snd_kcontrol_new *knew = snd_array_new(&spec->kctls);
+	if (!knew)
+		return NULL;
+	*knew = *temp;
+	knew->name = kstrdup(name, GFP_KERNEL);
+	if (!knew->name)
+		return NULL;
+	return knew;
 }
 
 static int alc_add_automute_mode_enum(struct hda_codec *codec)
 {
 	struct alc_spec *spec = codec->spec;
-	struct snd_kcontrol_new *knew;
 
-	knew = alc_kcontrol_new(spec);
-	if (!knew)
-		return -ENOMEM;
-	*knew = alc_automute_mode_enum;
-	knew->name = kstrdup("Auto-Mute Mode", GFP_KERNEL);
-	if (!knew->name)
+	if (!alc_kcontrol_new(spec, "Auto-Mute Mode", &alc_automute_mode_enum))
 		return -ENOMEM;
 	return 0;
 }
@@ -928,12 +915,12 @@
  * Check the availability of HP/line-out auto-mute;
  * Set up appropriately if really supported
  */
-static void alc_init_automute(struct hda_codec *codec)
+static int alc_init_automute(struct hda_codec *codec)
 {
 	struct alc_spec *spec = codec->spec;
 	struct auto_pin_cfg *cfg = &spec->autocfg;
 	int present = 0;
-	int i;
+	int i, err;
 
 	if (cfg->hp_pins[0])
 		present++;
@@ -942,7 +929,7 @@
 	if (cfg->speaker_pins[0])
 		present++;
 	if (present < 2) /* need two different output types */
-		return;
+		return 0;
 
 	if (!cfg->speaker_pins[0] &&
 	    cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) {
@@ -992,9 +979,13 @@
 	spec->automute_lo = spec->automute_lo_possible;
 	spec->automute_speaker = spec->automute_speaker_possible;
 
-	if (spec->automute_speaker_possible || spec->automute_lo_possible)
+	if (spec->automute_speaker_possible || spec->automute_lo_possible) {
 		/* create a control for automute mode */
-		alc_add_automute_mode_enum(codec);
+		err = alc_add_automute_mode_enum(codec);
+		if (err < 0)
+			return err;
+	}
+	return 0;
 }
 
 /* return the position of NID in the list, or -1 if not found */
@@ -1094,7 +1085,7 @@
  * Check the availability of auto-mic switch;
  * Set up if really supported
  */
-static void alc_init_auto_mic(struct hda_codec *codec)
+static int alc_init_auto_mic(struct hda_codec *codec)
 {
 	struct alc_spec *spec = codec->spec;
 	struct auto_pin_cfg *cfg = &spec->autocfg;
@@ -1102,7 +1093,7 @@
 	int i;
 
 	if (spec->shared_mic_hp)
-		return; /* no auto-mic for the shared I/O */
+		return 0; /* no auto-mic for the shared I/O */
 
 	spec->ext_mic_idx = spec->int_mic_idx = spec->dock_mic_idx = -1;
 
@@ -1114,25 +1105,25 @@
 		switch (snd_hda_get_input_pin_attr(defcfg)) {
 		case INPUT_PIN_ATTR_INT:
 			if (fixed)
-				return; /* already occupied */
+				return 0; /* already occupied */
 			if (cfg->inputs[i].type != AUTO_PIN_MIC)
-				return; /* invalid type */
+				return 0; /* invalid type */
 			fixed = nid;
 			break;
 		case INPUT_PIN_ATTR_UNUSED:
-			return; /* invalid entry */
+			return 0; /* invalid entry */
 		case INPUT_PIN_ATTR_DOCK:
 			if (dock)
-				return; /* already occupied */
+				return 0; /* already occupied */
 			if (cfg->inputs[i].type > AUTO_PIN_LINE_IN)
-				return; /* invalid type */
+				return 0; /* invalid type */
 			dock = nid;
 			break;
 		default:
 			if (ext)
-				return; /* already occupied */
+				return 0; /* already occupied */
 			if (cfg->inputs[i].type != AUTO_PIN_MIC)
-				return; /* invalid type */
+				return 0; /* invalid type */
 			ext = nid;
 			break;
 		}
@@ -1142,11 +1133,11 @@
 		dock = 0;
 	}
 	if (!ext || !fixed)
-		return;
+		return 0;
 	if (!is_jack_detectable(codec, ext))
-		return; /* no unsol support */
+		return 0; /* no unsol support */
 	if (dock && !is_jack_detectable(codec, dock))
-		return; /* no unsol support */
+		return 0; /* no unsol support */
 
 	/* check imux indices */
 	spec->ext_mic_pin = ext;
@@ -1155,17 +1146,26 @@
 
 	spec->auto_mic = 1;
 	if (!alc_auto_mic_check_imux(codec))
-		return;
+		return 0;
 
 	snd_printdd("realtek: Enable auto-mic switch on NID 0x%x/0x%x/0x%x\n",
 		    ext, fixed, dock);
+
+	return 0;
 }
 
 /* check the availabilities of auto-mute and auto-mic switches */
-static void alc_auto_check_switches(struct hda_codec *codec)
+static int alc_auto_check_switches(struct hda_codec *codec)
 {
-	alc_init_automute(codec);
-	alc_init_auto_mic(codec);
+	int err;
+
+	err = alc_init_automute(codec);
+	if (err < 0)
+		return err;
+	err = alc_init_auto_mic(codec);
+	if (err < 0)
+		return err;
+	return 0;
 }
 
 /*
@@ -1757,12 +1757,9 @@
 static int alc_add_inv_dmic_mixer(struct hda_codec *codec, hda_nid_t nid)
 {
 	struct alc_spec *spec = codec->spec;
-	struct snd_kcontrol_new *knew = alc_kcontrol_new(spec);
-	if (!knew)
-		return -ENOMEM;
-	*knew = alc_inv_dmic_sw;
-	knew->name = kstrdup("Inverted Internal Mic Capture Switch", GFP_KERNEL);
-	if (!knew->name)
+
+	if (!alc_kcontrol_new(spec, "Inverted Internal Mic Capture Switch",
+			      &alc_inv_dmic_sw))
 		return -ENOMEM;
 	spec->inv_dmic_fixup = 1;
 	spec->inv_dmic_muted = 0;
@@ -1836,9 +1833,10 @@
 			return err;
 	}
 	if (spec->multiout.dig_out_nid) {
-		err = snd_hda_create_spdif_out_ctls(codec,
-						    spec->multiout.dig_out_nid,
-						    spec->multiout.dig_out_nid);
+		err = snd_hda_create_dig_out_ctls(codec,
+						  spec->multiout.dig_out_nid,
+						  spec->multiout.dig_out_nid,
+						  spec->pcm_rec[1].pcm_type);
 		if (err < 0)
 			return err;
 		if (!spec->no_analog) {
@@ -2259,6 +2257,10 @@
 		info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
 		info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max =
 			spec->multiout.max_channels;
+		if (spec->autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT &&
+		    spec->autocfg.line_outs == 2)
+			info->stream[SNDRV_PCM_STREAM_PLAYBACK].chmap =
+				snd_pcm_2_1_chmaps;
 	}
 	if (spec->adc_nids) {
 		p = spec->stream_analog_capture;
@@ -2399,7 +2401,6 @@
 	if (!spec)
 		return;
 
-	alc_shutup(codec);
 	alc_free_kctls(codec);
 	alc_free_bind_ctls(codec);
 	snd_hda_gen_free(&spec->gen);
@@ -2534,13 +2535,9 @@
 {
 	struct snd_kcontrol_new *knew;
 
-	knew = alc_kcontrol_new(spec);
+	knew = alc_kcontrol_new(spec, name, &alc_control_templates[type]);
 	if (!knew)
 		return -ENOMEM;
-	*knew = alc_control_templates[type];
-	knew->name = kstrdup(name, GFP_KERNEL);
-	if (!knew->name)
-		return -ENOMEM;
 	knew->index = cidx;
 	if (get_amp_nid_(val))
 		knew->subdevice = HDA_SUBDEV_AMP_FLAG;
@@ -3601,7 +3598,6 @@
 {
 	struct alc_spec *spec = codec->spec;
 	struct hda_bind_ctls **ctlp, *ctl;
-	snd_array_init(&spec->bind_ctls, sizeof(ctl), 8);
 	ctlp = snd_array_new(&spec->bind_ctls);
 	if (!ctlp)
 		return NULL;
@@ -3965,8 +3961,9 @@
 	spec->ext_channel_count = (ch + 1) * 2;
 	for (i = 0; i < spec->multi_ios; i++)
 		alc_set_multi_io(codec, i, i < ch);
-	spec->multiout.max_channels = spec->ext_channel_count;
-	if (spec->need_dac_fix && !spec->const_channel_count)
+	spec->multiout.max_channels = max(spec->ext_channel_count,
+					  spec->const_channel_count);
+	if (spec->need_dac_fix)
 		spec->multiout.num_dacs = spec->multiout.max_channels / 2;
 	return 1;
 }
@@ -3984,14 +3981,8 @@
 	struct alc_spec *spec = codec->spec;
 
 	if (spec->multi_ios > 0) {
-		struct snd_kcontrol_new *knew;
-
-		knew = alc_kcontrol_new(spec);
-		if (!knew)
-			return -ENOMEM;
-		*knew = alc_auto_channel_mode_enum;
-		knew->name = kstrdup("Channel Mode", GFP_KERNEL);
-		if (!knew->name)
+		if (!alc_kcontrol_new(spec, "Channel Mode",
+				      &alc_auto_channel_mode_enum))
 			return -ENOMEM;
 	}
 	return 0;
@@ -4334,7 +4325,17 @@
 	if (err < 0)
 		return err;
 
-	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
+	/* check the multiple speaker pins */
+	if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
+		spec->const_channel_count = cfg->line_outs * 2;
+	else
+		spec->const_channel_count = cfg->speaker_outs * 2;
+
+	if (spec->multi_ios > 0)
+		spec->multiout.max_channels = max(spec->ext_channel_count,
+						  spec->const_channel_count);
+	else
+		spec->multiout.max_channels = spec->multiout.num_dacs * 2;
 
  dig_only:
 	alc_auto_parse_digital(codec);
@@ -4346,7 +4347,9 @@
 		alc_ssid_check(codec, ssid_nids);
 
 	if (!spec->no_analog) {
-		alc_auto_check_switches(codec);
+		err = alc_auto_check_switches(codec);
+		if (err < 0)
+			return err;
 		err = alc_auto_add_mic_boost(codec);
 		if (err < 0)
 			return err;
@@ -4372,6 +4375,8 @@
 	codec->spec = spec;
 	spec->mixer_nid = mixer_nid;
 	snd_hda_gen_init(&spec->gen);
+	snd_array_init(&spec->kctls, sizeof(struct snd_kcontrol_new), 32);
+	snd_array_init(&spec->bind_ctls, sizeof(struct hda_bind_ctls *), 8);
 
 	err = alc_codec_rename_from_preset(codec);
 	if (err < 0) {
@@ -6009,6 +6014,16 @@
 	}
 }
 
+static void alc271_hp_gate_mic_jack(struct hda_codec *codec,
+				    const struct alc_fixup *fix,
+				    int action)
+{
+	struct alc_spec *spec = codec->spec;
+
+	if (action == ALC_FIXUP_ACT_PROBE)
+		snd_hda_jack_set_gating_jack(codec, spec->ext_mic_pin,
+					     spec->autocfg.hp_pins[0]);
+}
 
 enum {
 	ALC269_FIXUP_SONY_VAIO,
@@ -6031,6 +6046,8 @@
 	ALC269_FIXUP_INV_DMIC,
 	ALC269_FIXUP_LENOVO_DOCK,
 	ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT,
+	ALC271_FIXUP_AMIC_MIC2,
+	ALC271_FIXUP_HP_GATE_MIC_JACK,
 };
 
 static const struct alc_fixup alc269_fixups[] = {
@@ -6175,6 +6192,22 @@
 		.type = ALC_FIXUP_FUNC,
 		.v.func = alc269_fixup_pincfg_no_hp_to_lineout,
 	},
+	[ALC271_FIXUP_AMIC_MIC2] = {
+		.type = ALC_FIXUP_PINS,
+		.v.pins = (const struct alc_pincfg[]) {
+			{ 0x14, 0x99130110 }, /* speaker */
+			{ 0x19, 0x01a19c20 }, /* mic */
+			{ 0x1b, 0x99a7012f }, /* int-mic */
+			{ 0x21, 0x0121401f }, /* HP out */
+			{ }
+		},
+	},
+	[ALC271_FIXUP_HP_GATE_MIC_JACK] = {
+		.type = ALC_FIXUP_FUNC,
+		.v.func = alc271_hp_gate_mic_jack,
+		.chained = true,
+		.chain_id = ALC271_FIXUP_AMIC_MIC2,
+	},
 };
 
 static const struct snd_pci_quirk alc269_fixup_tbl[] = {
@@ -6195,6 +6228,7 @@
 	SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
 	SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO),
 	SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z),
+	SND_PCI_QUIRK(0x1025, 0x0742, "Acer AO756", ALC271_FIXUP_HP_GATE_MIC_JACK),
 	SND_PCI_QUIRK_VENDOR(0x1025, "Acer Aspire", ALC271_FIXUP_DMIC),
 	SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook", ALC269_FIXUP_LIFEBOOK),
 	SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE),
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index 9ba8af0..df13c0f 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -1081,7 +1081,7 @@
 
 static const char * const slave_pfxs[] = {
 	"Front", "Surround", "Center", "LFE", "Side",
-	"Headphone", "Speaker", "IEC958", "PCM",
+	"Headphone", "Speaker", "Bass Speaker", "IEC958", "PCM",
 	NULL
 };
 
@@ -1136,9 +1136,10 @@
 	}
 
 	if (spec->multiout.dig_out_nid) {
-		err = snd_hda_create_spdif_out_ctls(codec,
-						    spec->multiout.dig_out_nid,
-						    spec->multiout.dig_out_nid);
+		err = snd_hda_create_dig_out_ctls(codec,
+						  spec->multiout.dig_out_nid,
+						  spec->multiout.dig_out_nid,
+						  spec->autocfg.dig_out_type[0]);
 		if (err < 0)
 			return err;
 		err = snd_hda_create_spdif_share_sw(codec,
@@ -2515,6 +2516,11 @@
 	info->stream[SNDRV_PCM_STREAM_PLAYBACK] = stac92xx_pcm_analog_playback;
 	info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
 		spec->multiout.dac_nids[0];
+	if (spec->autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT &&
+	    spec->autocfg.line_outs == 2)
+		info->stream[SNDRV_PCM_STREAM_PLAYBACK].chmap =
+			snd_pcm_2_1_chmaps;
+
 	info->stream[SNDRV_PCM_STREAM_CAPTURE] = stac92xx_pcm_analog_capture;
 	info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
 	info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = spec->num_adcs;
@@ -2805,7 +2811,6 @@
 {
 	struct snd_kcontrol_new *knew;
 
-	snd_array_init(&spec->kctls, sizeof(*knew), 32);
 	knew = snd_array_new(&spec->kctls);
 	if (!knew)
 		return NULL;
@@ -3268,9 +3273,9 @@
 				idx = i;
 				break;
 			case AUTO_PIN_SPEAKER_OUT:
-				if (num_outs <= 1) {
-					name = "Speaker";
-					idx = i;
+				if (num_outs <= 2) {
+					name = i ? "Bass Speaker" : "Speaker";
+					idx = 0;
 					break;
 				}
 				/* Fall through in case of multi speaker outs */
@@ -4569,8 +4574,6 @@
 	if (! spec)
 		return;
 
-	stac92xx_shutup(codec);
-
 	kfree(spec);
 	snd_hda_detach_beep_device(codec);
 }
@@ -5155,20 +5158,34 @@
 	.reboot_notify = stac92xx_shutup,
 };
 
+static int alloc_stac_spec(struct hda_codec *codec, int num_pins,
+			   const hda_nid_t *pin_nids)
+{
+	struct sigmatel_spec *spec;
+
+	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
+	if (!spec)
+		return -ENOMEM;
+	codec->spec = spec;
+	codec->no_trigger_sense = 1; /* seems common with STAC/IDT codecs */
+	spec->num_pins = num_pins;
+	spec->pin_nids = pin_nids;
+	snd_array_init(&spec->kctls, sizeof(struct snd_kcontrol_new), 32);
+	return 0;
+}
+
 static int patch_stac9200(struct hda_codec *codec)
 {
 	struct sigmatel_spec *spec;
 	int err;
 
-	spec  = kzalloc(sizeof(*spec), GFP_KERNEL);
-	if (spec == NULL)
-		return -ENOMEM;
+	err = alloc_stac_spec(codec, ARRAY_SIZE(stac9200_pin_nids),
+			      stac9200_pin_nids);
+	if (err < 0)
+		return err;
 
-	codec->no_trigger_sense = 1;
-	codec->spec = spec;
+	spec = codec->spec;
 	spec->linear_tone_beep = 1;
-	spec->num_pins = ARRAY_SIZE(stac9200_pin_nids);
-	spec->pin_nids = stac9200_pin_nids;
 	spec->board_config = snd_hda_check_board_config(codec, STAC_9200_MODELS,
 							stac9200_models,
 							stac9200_cfg_tbl);
@@ -5224,15 +5241,13 @@
 	struct sigmatel_spec *spec;
 	int err;
 
-	spec  = kzalloc(sizeof(*spec), GFP_KERNEL);
-	if (spec == NULL)
-		return -ENOMEM;
+	err = alloc_stac_spec(codec, ARRAY_SIZE(stac925x_pin_nids),
+			      stac925x_pin_nids);
+	if (err < 0)
+		return err;
 
-	codec->no_trigger_sense = 1;
-	codec->spec = spec;
+	spec = codec->spec;
 	spec->linear_tone_beep = 1;
-	spec->num_pins = ARRAY_SIZE(stac925x_pin_nids);
-	spec->pin_nids = stac925x_pin_nids;
 
 	/* Check first for codec ID */
 	spec->board_config = snd_hda_check_board_codec_sid_config(codec,
@@ -5307,19 +5322,17 @@
 {
 	struct sigmatel_spec *spec;
 	hda_nid_t conn[STAC92HD73_DAC_COUNT + 2];
-	int err = 0;
+	int err;
 	int num_dacs;
 
-	spec  = kzalloc(sizeof(*spec), GFP_KERNEL);
-	if (spec == NULL)
-		return -ENOMEM;
+	err = alloc_stac_spec(codec, ARRAY_SIZE(stac92hd73xx_pin_nids),
+			      stac92hd73xx_pin_nids);
+	if (err < 0)
+		return err;
 
-	codec->no_trigger_sense = 1;
-	codec->spec = spec;
+	spec = codec->spec;
 	spec->linear_tone_beep = 0;
 	codec->slave_dig_outs = stac92hd73xx_slave_dig_outs;
-	spec->num_pins = ARRAY_SIZE(stac92hd73xx_pin_nids);
-	spec->pin_nids = stac92hd73xx_pin_nids;
 	spec->board_config = snd_hda_check_board_config(codec,
 							STAC_92HD73XX_MODELS,
 							stac92hd73xx_models,
@@ -5596,9 +5609,9 @@
 	int default_polarity = -1; /* no default cfg */
 	int err;
 
-	spec  = kzalloc(sizeof(*spec), GFP_KERNEL);
-	if (spec == NULL)
-		return -ENOMEM;
+	err = alloc_stac_spec(codec, 0, NULL); /* pins filled later */
+	if (err < 0)
+		return err;
 
 	if (hp_bnb2011_with_dock(codec)) {
 		snd_hda_codec_set_pincfg(codec, 0xa, 0x2101201f);
@@ -5606,11 +5619,9 @@
 	}
 
 	codec->epss = 0; /* longer delay needed for D3 */
-	codec->no_trigger_sense = 1;
-	codec->spec = spec;
-
 	stac92hd8x_fill_auto_spec(codec);
 
+	spec = codec->spec;
 	spec->linear_tone_beep = 0;
 	codec->slave_dig_outs = stac92hd83xxx_slave_dig_outs;
 	spec->digbeep_nid = 0x21;
@@ -5779,21 +5790,19 @@
 	struct sigmatel_spec *spec;
 	const struct hda_verb *unmute_init = stac92hd71bxx_unmute_core_init;
 	unsigned int pin_cfg;
-	int err = 0;
+	int err;
 
-	spec  = kzalloc(sizeof(*spec), GFP_KERNEL);
-	if (spec == NULL)
-		return -ENOMEM;
+	err = alloc_stac_spec(codec, STAC92HD71BXX_NUM_PINS,
+			      stac92hd71bxx_pin_nids_4port);
+	if (err < 0)
+		return err;
 
-	codec->no_trigger_sense = 1;
-	codec->spec = spec;
+	spec = codec->spec;
 	spec->linear_tone_beep = 0;
 	codec->patch_ops = stac92xx_patch_ops;
-	spec->num_pins = STAC92HD71BXX_NUM_PINS;
 	switch (codec->vendor_id) {
 	case 0x111d76b6:
 	case 0x111d76b7:
-		spec->pin_nids = stac92hd71bxx_pin_nids_4port;
 		break;
 	case 0x111d7603:
 	case 0x111d7608:
@@ -6024,15 +6033,13 @@
 	struct sigmatel_spec *spec;
 	int err;
 
-	spec  = kzalloc(sizeof(*spec), GFP_KERNEL);
-	if (spec == NULL)
-		return -ENOMEM;
+	err = alloc_stac_spec(codec, ARRAY_SIZE(stac922x_pin_nids),
+			      stac922x_pin_nids);
+	if (err < 0)
+		return err;
 
-	codec->no_trigger_sense = 1;
-	codec->spec = spec;
+	spec = codec->spec;
 	spec->linear_tone_beep = 1;
-	spec->num_pins = ARRAY_SIZE(stac922x_pin_nids);
-	spec->pin_nids = stac922x_pin_nids;
 	spec->board_config = snd_hda_check_board_config(codec, STAC_922X_MODELS,
 							stac922x_models,
 							stac922x_cfg_tbl);
@@ -6129,16 +6136,14 @@
 	struct sigmatel_spec *spec;
 	int err;
 
-	spec  = kzalloc(sizeof(*spec), GFP_KERNEL);
-	if (spec == NULL)
-		return -ENOMEM;
+	err = alloc_stac_spec(codec, ARRAY_SIZE(stac927x_pin_nids),
+			      stac927x_pin_nids);
+	if (err < 0)
+		return err;
 
-	codec->no_trigger_sense = 1;
-	codec->spec = spec;
+	spec = codec->spec;
 	spec->linear_tone_beep = 1;
 	codec->slave_dig_outs = stac927x_slave_dig_outs;
-	spec->num_pins = ARRAY_SIZE(stac927x_pin_nids);
-	spec->pin_nids = stac927x_pin_nids;
 	spec->board_config = snd_hda_check_board_config(codec, STAC_927X_MODELS,
 							stac927x_models,
 							stac927x_cfg_tbl);
@@ -6265,15 +6270,13 @@
 	struct sigmatel_spec *spec;
 	int err;
 
-	spec  = kzalloc(sizeof(*spec), GFP_KERNEL);
-	if (spec == NULL)
-		return -ENOMEM;
+	err = alloc_stac_spec(codec, ARRAY_SIZE(stac9205_pin_nids),
+			      stac9205_pin_nids);
+	if (err < 0)
+		return err;
 
-	codec->no_trigger_sense = 1;
-	codec->spec = spec;
+	spec = codec->spec;
 	spec->linear_tone_beep = 1;
-	spec->num_pins = ARRAY_SIZE(stac9205_pin_nids);
-	spec->pin_nids = stac9205_pin_nids;
 	spec->board_config = snd_hda_check_board_config(codec, STAC_9205_MODELS,
 							stac9205_models,
 							stac9205_cfg_tbl);
@@ -6421,14 +6424,13 @@
 	struct sigmatel_spec *spec;
 	int err;
 
-	spec  = kzalloc(sizeof(*spec), GFP_KERNEL);
-	if (spec == NULL)
-		return -ENOMEM;
-	codec->no_trigger_sense = 1;
-	codec->spec = spec;
+	err = alloc_stac_spec(codec, ARRAY_SIZE(stac9872_pin_nids),
+			      stac9872_pin_nids);
+	if (err < 0)
+		return err;
+
+	spec = codec->spec;
 	spec->linear_tone_beep = 1;
-	spec->num_pins = ARRAY_SIZE(stac9872_pin_nids);
-	spec->pin_nids = stac9872_pin_nids;
 
 	spec->board_config = snd_hda_check_board_config(codec, STAC_9872_MODELS,
 							stac9872_models,
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c
index 019e1a0..09bb649 100644
--- a/sound/pci/hda/patch_via.c
+++ b/sound/pci/hda/patch_via.c
@@ -76,6 +76,8 @@
 	VT2002P,
 	VT1812,
 	VT1802,
+	VT1705CF,
+	VT1808,
 	CODEC_TYPES,
 };
 
@@ -220,6 +222,7 @@
 	int vt1708_hp_present;
 
 	void (*set_widgets_power_state)(struct hda_codec *codec);
+	unsigned int dac_stream_tag[4];
 
 	struct hda_loopback_check loopback;
 	int num_loopbacks;
@@ -241,6 +244,7 @@
 	if (spec == NULL)
 		return NULL;
 
+	snd_array_init(&spec->kctls, sizeof(struct snd_kcontrol_new), 32);
 	mutex_init(&spec->config_mutex);
 	codec->spec = spec;
 	spec->codec = codec;
@@ -295,6 +299,10 @@
 		codec_type = VT1708S;
 	else if ((dev_id & 0xfff) == 0x446)
 		codec_type = VT1802;
+	else if (dev_id == 0x4760)
+		codec_type = VT1705CF;
+	else if (dev_id == 0x4761 || dev_id == 0x4762)
+		codec_type = VT1808;
 	else
 		codec_type = UNKNOWN;
 	return codec_type;
@@ -387,7 +395,6 @@
 {
 	struct snd_kcontrol_new *knew;
 
-	snd_array_init(&spec->kctls, sizeof(*knew), 32);
 	knew = snd_array_new(&spec->kctls);
 	if (!knew)
 		return NULL;
@@ -711,6 +718,28 @@
 	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_POWER_STATE, parm);
 }
 
+static void update_conv_power_state(struct hda_codec *codec, hda_nid_t nid,
+			       unsigned int parm, unsigned int index)
+{
+	struct via_spec *spec = codec->spec;
+	unsigned int format;
+	if (snd_hda_codec_read(codec, nid, 0,
+			       AC_VERB_GET_POWER_STATE, 0) == parm)
+		return;
+	format = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONV, 0);
+	if (format && (spec->dac_stream_tag[index] != format))
+		spec->dac_stream_tag[index] = format;
+
+	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_POWER_STATE, parm);
+	if (parm == AC_PWRST_D0) {
+		format = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONV, 0);
+		if (!format && (spec->dac_stream_tag[index] != format))
+			snd_hda_codec_write(codec, nid, 0,
+						  AC_VERB_SET_CHANNEL_STREAMID,
+						  spec->dac_stream_tag[index]);
+	}
+}
+
 static void set_pin_power_state(struct hda_codec *codec, hda_nid_t nid,
 				unsigned int *affected_parm)
 {
@@ -739,18 +768,7 @@
 static int via_pin_power_ctl_info(struct snd_kcontrol *kcontrol,
 				  struct snd_ctl_elem_info *uinfo)
 {
-	static const char * const texts[] = {
-		"Disabled", "Enabled"
-	};
-
-	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
-	uinfo->count = 1;
-	uinfo->value.enumerated.items = 2;
-	if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
-		uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
-	strcpy(uinfo->value.enumerated.name,
-	       texts[uinfo->value.enumerated.item]);
-	return 0;
+	return snd_hda_enum_bool_helper_info(kcontrol, uinfo);
 }
 
 static int via_pin_power_ctl_get(struct snd_kcontrol *kcontrol,
@@ -1096,6 +1114,11 @@
 		verb = 0xf93;
 		parm = enable ? 0x00 : 0xe0; /* 0x00: 4/40x, 0xe0: 1x */
 		break;
+	case VT1705CF:
+	case VT1808:
+		verb = 0xf82;
+		parm = enable ? 0x00 : 0xe0;  /* 0x00: 4/40x, 0xe0: 1x */
+		break;
 	default:
 		return;		/* other codecs are not supported */
 	}
@@ -1454,7 +1477,7 @@
  */
 static const char * const via_slave_pfxs[] = {
 	"Front", "Surround", "Center", "LFE", "Side",
-	"Headphone", "Speaker",
+	"Headphone", "Speaker", "Bass Speaker",
 	NULL,
 };
 
@@ -1555,6 +1578,10 @@
 				spec->multiout.dac_nids[0];
 			info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max =
 				spec->multiout.max_channels;
+			if (spec->autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT
+			    && spec->autocfg.line_outs == 2)
+				info->stream[SNDRV_PCM_STREAM_PLAYBACK].chmap =
+					snd_pcm_2_1_chmaps;
 		}
 
 		if (!spec->stream_analog_capture) {
@@ -1934,7 +1961,7 @@
 	struct auto_pin_cfg *cfg = &spec->autocfg;
 	struct nid_path *path;
 	static const char * const chname[4] = {
-		"Front", "Surround", "C/LFE", "Side"
+		"Front", "Surround", NULL /* "CLFE" */, "Side"
 	};
 	int i, idx, err;
 	int old_line_outs;
@@ -1969,8 +1996,8 @@
 		} else {
 			const char *pfx = chname[i];
 			if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT &&
-			    cfg->line_outs == 1)
-				pfx = "Speaker";
+			    cfg->line_outs <= 2)
+				pfx = i ? "Bass Speaker" : "Speaker";
 			err = create_ch_ctls(codec, pfx, 3, true, path);
 			if (err < 0)
 				return err;
@@ -3824,6 +3851,125 @@
 	return 0;
 }
 
+/* patch for vt3476 */
+
+static const struct hda_verb vt3476_init_verbs[] = {
+	/* Enable DMic 8/16/32K */
+	{0x1, 0xF7B, 0x30},
+	/* Enable Boost Volume backdoor */
+	{0x1, 0xFB9, 0x20},
+	/* Enable AOW-MW9 path */
+	{0x1, 0xFB8, 0x10},
+	{ }
+};
+
+static void set_widgets_power_state_vt3476(struct hda_codec *codec)
+{
+	struct via_spec *spec = codec->spec;
+	int imux_is_smixer;
+	unsigned int parm, parm2;
+	/* MUX10 (1eh) = stereo mixer */
+	imux_is_smixer =
+	snd_hda_codec_read(codec, 0x1e, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 4;
+	/* inputs */
+	/* PW 5/6/7 (29h/2ah/2bh) */
+	parm = AC_PWRST_D3;
+	set_pin_power_state(codec, 0x29, &parm);
+	set_pin_power_state(codec, 0x2a, &parm);
+	set_pin_power_state(codec, 0x2b, &parm);
+	if (imux_is_smixer)
+		parm = AC_PWRST_D0;
+	/* MUX10/11 (1eh/1fh), AIW 0/1 (10h/11h) */
+	update_power_state(codec, 0x1e, parm);
+	update_power_state(codec, 0x1f, parm);
+	update_power_state(codec, 0x10, parm);
+	update_power_state(codec, 0x11, parm);
+
+	/* outputs */
+	/* PW3 (27h), MW3(37h), AOW3 (bh) */
+	if (spec->codec_type == VT1705CF) {
+		parm = AC_PWRST_D3;
+		update_power_state(codec, 0x27, parm);
+		update_power_state(codec, 0x37, parm);
+	}	else {
+		parm = AC_PWRST_D3;
+		set_pin_power_state(codec, 0x27, &parm);
+		update_power_state(codec, 0x37, parm);
+	}
+
+	/* PW2 (26h), MW2(36h), AOW2 (ah) */
+	parm = AC_PWRST_D3;
+	set_pin_power_state(codec, 0x26, &parm);
+	update_power_state(codec, 0x36, parm);
+	if (spec->smart51_enabled) {
+		/* PW7(2bh), MW7(3bh), MUX7(1Bh) */
+		set_pin_power_state(codec, 0x2b, &parm);
+		update_power_state(codec, 0x3b, parm);
+		update_power_state(codec, 0x1b, parm);
+	}
+	update_conv_power_state(codec, 0xa, parm, 2);
+
+	/* PW1 (25h), MW1(35h), AOW1 (9h) */
+	parm = AC_PWRST_D3;
+	set_pin_power_state(codec, 0x25, &parm);
+	update_power_state(codec, 0x35, parm);
+	if (spec->smart51_enabled) {
+		/* PW6(2ah), MW6(3ah), MUX6(1ah) */
+		set_pin_power_state(codec, 0x2a, &parm);
+		update_power_state(codec, 0x3a, parm);
+		update_power_state(codec, 0x1a, parm);
+	}
+	update_conv_power_state(codec, 0x9, parm, 1);
+
+	/* PW4 (28h), MW4 (38h), MUX4(18h), AOW3(bh)/AOW0(8h) */
+	parm = AC_PWRST_D3;
+	set_pin_power_state(codec, 0x28, &parm);
+	update_power_state(codec, 0x38, parm);
+	update_power_state(codec, 0x18, parm);
+	if (spec->hp_independent_mode)
+		update_conv_power_state(codec, 0xb, parm, 3);
+	parm2 = parm; /* for pin 0x0b */
+
+	/* PW0 (24h), MW0(34h), MW9(3fh), AOW0 (8h) */
+	parm = AC_PWRST_D3;
+	set_pin_power_state(codec, 0x24, &parm);
+	update_power_state(codec, 0x34, parm);
+	if (!spec->hp_independent_mode && parm2 != AC_PWRST_D3)
+		parm = parm2;
+	update_conv_power_state(codec, 0x8, parm, 0);
+	/* MW9 (21h), Mw2 (1ah), AOW0 (8h) */
+	update_power_state(codec, 0x3f, imux_is_smixer ? AC_PWRST_D0 : parm);
+}
+
+static int patch_vt3476(struct hda_codec *codec)
+{
+	struct via_spec *spec;
+	int err;
+
+	/* create a codec specific record */
+	spec = via_new_spec(codec);
+	if (spec == NULL)
+		return -ENOMEM;
+
+	spec->aa_mix_nid = 0x3f;
+	add_secret_dac_path(codec);
+
+	/* automatic parse from the BIOS config */
+	err = via_parse_auto_config(codec);
+	if (err < 0) {
+		via_free(codec);
+		return err;
+	}
+
+	spec->init_verbs[spec->num_iverbs++] = vt3476_init_verbs;
+
+	codec->patch_ops = via_patch_ops;
+
+	spec->set_widgets_power_state = set_widgets_power_state_vt3476;
+
+	return 0;
+}
+
 /*
  * patch entries
  */
@@ -3917,6 +4063,12 @@
 		.patch = patch_vt2002P},
 	{ .id = 0x11068446, .name = "VT1802",
 		.patch = patch_vt2002P},
+	{ .id = 0x11064760, .name = "VT1705CF",
+		.patch = patch_vt3476},
+	{ .id = 0x11064761, .name = "VT1708SCE",
+		.patch = patch_vt3476},
+	{ .id = 0x11064762, .name = "VT1808",
+		.patch = patch_vt3476},
 	{} /* terminator */
 };
 
diff --git a/sound/pci/ice1712/Makefile b/sound/pci/ice1712/Makefile
index f7ce33f..7e50c13 100644
--- a/sound/pci/ice1712/Makefile
+++ b/sound/pci/ice1712/Makefile
@@ -5,7 +5,7 @@
 
 snd-ice17xx-ak4xxx-objs := ak4xxx.o
 snd-ice1712-objs := ice1712.o delta.o hoontech.o ews.o
-snd-ice1724-objs := ice1724.o amp.o revo.o aureon.o vt1720_mobo.o pontis.o prodigy192.o prodigy_hifi.o juli.o phase.o wtm.o se.o maya44.o quartet.o
+snd-ice1724-objs := ice1724.o amp.o revo.o aureon.o vt1720_mobo.o pontis.o prodigy192.o prodigy_hifi.o juli.o phase.o wtm.o se.o maya44.o quartet.o psc724.o wm8766.o wm8776.o
 
 # Toplevel Module Dependency
 obj-$(CONFIG_SND_ICE1712) += snd-ice1712.o snd-ice17xx-ak4xxx.o
diff --git a/sound/pci/ice1712/amp.c b/sound/pci/ice1712/amp.c
index e525da2..2f9b934 100644
--- a/sound/pci/ice1712/amp.c
+++ b/sound/pci/ice1712/amp.c
@@ -21,7 +21,6 @@
  *
  */      
 
-#include <asm/io.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
@@ -38,7 +37,7 @@
 	snd_vt1724_write_i2c(ice, WM_DEV, cval >> 8, cval & 0xff);
 }
 
-static int __devinit snd_vt1724_amp_init(struct snd_ice1712 *ice)
+static int snd_vt1724_amp_init(struct snd_ice1712 *ice)
 {
 	static const unsigned short wm_inits[] = {
 		WM_ATTEN_L,	0x0000,	/* 0 db */
@@ -66,7 +65,7 @@
 	return 0;
 }
 
-static int __devinit snd_vt1724_amp_add_controls(struct snd_ice1712 *ice)
+static int snd_vt1724_amp_add_controls(struct snd_ice1712 *ice)
 {
 	if (ice->ac97)
 		/* we use pins 39 and 41 of the VT1616 for left and right
@@ -78,7 +77,7 @@
 
 
 /* entry point */
-struct snd_ice1712_card_info snd_vt1724_amp_cards[] __devinitdata = {
+struct snd_ice1712_card_info snd_vt1724_amp_cards[] = {
 	{
 		.subvendor = VT1724_SUBDEVICE_AV710,
 		.name = "Chaintech AV-710",
diff --git a/sound/pci/ice1712/aureon.c b/sound/pci/ice1712/aureon.c
index 20bcdde..55902ec 100644
--- a/sound/pci/ice1712/aureon.c
+++ b/sound/pci/ice1712/aureon.c
@@ -46,7 +46,6 @@
  *                    on mixer switch and other coll stuff.
  */
 
-#include <linux/io.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
@@ -203,7 +202,8 @@
 static int aureon_universe_inmux_info(struct snd_kcontrol *kcontrol,
 				      struct snd_ctl_elem_info *uinfo)
 {
-	char *texts[3] = {"Internal Aux", "Wavetable", "Rear Line-In"};
+	static const char * const texts[3] =
+		{"Internal Aux", "Wavetable", "Rear Line-In"};
 
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
 	uinfo->count = 1;
@@ -1433,7 +1433,7 @@
  * mixers
  */
 
-static struct snd_kcontrol_new aureon_dac_controls[] __devinitdata = {
+static struct snd_kcontrol_new aureon_dac_controls[] = {
 	{
 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 		.name = "Master Playback Switch",
@@ -1548,7 +1548,7 @@
 	}
 };
 
-static struct snd_kcontrol_new wm_controls[] __devinitdata = {
+static struct snd_kcontrol_new wm_controls[] = {
 	{
 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 		.name = "PCM Playback Switch",
@@ -1614,7 +1614,7 @@
 	}
 };
 
-static struct snd_kcontrol_new ac97_controls[] __devinitdata = {
+static struct snd_kcontrol_new ac97_controls[] = {
 	{
 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 		.name = "AC97 Playback Switch",
@@ -1719,7 +1719,7 @@
 	}
 };
 
-static struct snd_kcontrol_new universe_ac97_controls[] __devinitdata = {
+static struct snd_kcontrol_new universe_ac97_controls[] = {
 	{
 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 		.name = "AC97 Playback Switch",
@@ -1851,7 +1851,7 @@
 
 };
 
-static struct snd_kcontrol_new cs8415_controls[] __devinitdata = {
+static struct snd_kcontrol_new cs8415_controls[] = {
 	{
 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 		.name = SNDRV_CTL_NAME_IEC958("", CAPTURE, SWITCH),
@@ -1896,7 +1896,7 @@
 	}
 };
 
-static int __devinit aureon_add_controls(struct snd_ice1712 *ice)
+static int aureon_add_controls(struct snd_ice1712 *ice)
 {
 	unsigned int i, counts;
 	int err;
@@ -2124,7 +2124,7 @@
 /*
  * initialize the chip
  */
-static int __devinit aureon_init(struct snd_ice1712 *ice)
+static int aureon_init(struct snd_ice1712 *ice)
 {
 	struct aureon_spec *spec;
 	int i, err;
@@ -2174,7 +2174,7 @@
  * hence the driver needs to sets up it properly.
  */
 
-static unsigned char aureon51_eeprom[] __devinitdata = {
+static unsigned char aureon51_eeprom[] = {
 	[ICE_EEP2_SYSCONF]     = 0x0a,	/* clock 512, spdif-in/ADC, 3DACs */
 	[ICE_EEP2_ACLINK]      = 0x80,	/* I2S */
 	[ICE_EEP2_I2S]         = 0xfc,	/* vol, 96k, 24bit, 192k */
@@ -2190,7 +2190,7 @@
 	[ICE_EEP2_GPIO_STATE2] = 0x00,
 };
 
-static unsigned char aureon71_eeprom[] __devinitdata = {
+static unsigned char aureon71_eeprom[] = {
 	[ICE_EEP2_SYSCONF]     = 0x0b,	/* clock 512, spdif-in/ADC, 4DACs */
 	[ICE_EEP2_ACLINK]      = 0x80,	/* I2S */
 	[ICE_EEP2_I2S]         = 0xfc,	/* vol, 96k, 24bit, 192k */
@@ -2207,7 +2207,7 @@
 };
 #define prodigy71_eeprom aureon71_eeprom
 
-static unsigned char aureon71_universe_eeprom[] __devinitdata = {
+static unsigned char aureon71_universe_eeprom[] = {
 	[ICE_EEP2_SYSCONF]     = 0x2b,	/* clock 512, mpu401, spdif-in/ADC,
 					 * 4DACs
 					 */
@@ -2225,7 +2225,7 @@
 	[ICE_EEP2_GPIO_STATE2] = 0x00,
 };
 
-static unsigned char prodigy71lt_eeprom[] __devinitdata = {
+static unsigned char prodigy71lt_eeprom[] = {
 	[ICE_EEP2_SYSCONF]     = 0x4b,	/* clock 384, spdif-in/ADC, 4DACs */
 	[ICE_EEP2_ACLINK]      = 0x80,	/* I2S */
 	[ICE_EEP2_I2S]         = 0xfc,	/* vol, 96k, 24bit, 192k */
@@ -2243,7 +2243,7 @@
 #define prodigy71xt_eeprom prodigy71lt_eeprom
 
 /* entry point */
-struct snd_ice1712_card_info snd_vt1724_aureon_cards[] __devinitdata = {
+struct snd_ice1712_card_info snd_vt1724_aureon_cards[] = {
 	{
 		.subvendor = VT1724_SUBDEVICE_AUREON51_SKY,
 		.name = "Terratec Aureon 5.1-Sky",
diff --git a/sound/pci/ice1712/delta.c b/sound/pci/ice1712/delta.c
index 20c6b07..9e28cc1 100644
--- a/sound/pci/ice1712/delta.c
+++ b/sound/pci/ice1712/delta.c
@@ -22,7 +22,6 @@
  *
  */      
 
-#include <asm/io.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
@@ -432,7 +431,7 @@
 	return 0;
 }
 
-static struct snd_kcontrol_new snd_ice1712_delta1010lt_wordclock_status __devinitdata =
+static struct snd_kcontrol_new snd_ice1712_delta1010lt_wordclock_status =
 {
 	.access =	(SNDRV_CTL_ELEM_ACCESS_READ),
 	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
@@ -445,7 +444,7 @@
  * initialize the chips on M-Audio cards
  */
 
-static struct snd_akm4xxx akm_audiophile __devinitdata = {
+static struct snd_akm4xxx akm_audiophile = {
 	.type = SND_AK4528,
 	.num_adcs = 2,
 	.num_dacs = 2,
@@ -454,7 +453,7 @@
 	}
 };
 
-static struct snd_ak4xxx_private akm_audiophile_priv __devinitdata = {
+static struct snd_ak4xxx_private akm_audiophile_priv = {
 	.caddr = 2,
 	.cif = 0,
 	.data_mask = ICE1712_DELTA_AP_DOUT,
@@ -466,7 +465,7 @@
 	.mask_flags = 0,
 };
 
-static struct snd_akm4xxx akm_delta410 __devinitdata = {
+static struct snd_akm4xxx akm_delta410 = {
 	.type = SND_AK4529,
 	.num_adcs = 2,
 	.num_dacs = 8,
@@ -475,7 +474,7 @@
 	}
 };
 
-static struct snd_ak4xxx_private akm_delta410_priv __devinitdata = {
+static struct snd_ak4xxx_private akm_delta410_priv = {
 	.caddr = 0,
 	.cif = 0,
 	.data_mask = ICE1712_DELTA_AP_DOUT,
@@ -487,7 +486,7 @@
 	.mask_flags = 0,
 };
 
-static struct snd_akm4xxx akm_delta1010lt __devinitdata = {
+static struct snd_akm4xxx akm_delta1010lt = {
 	.type = SND_AK4524,
 	.num_adcs = 8,
 	.num_dacs = 8,
@@ -497,7 +496,7 @@
 	}
 };
 
-static struct snd_ak4xxx_private akm_delta1010lt_priv __devinitdata = {
+static struct snd_ak4xxx_private akm_delta1010lt_priv = {
 	.caddr = 2,
 	.cif = 0, /* the default level of the CIF pin from AK4524 */
 	.data_mask = ICE1712_DELTA_1010LT_DOUT,
@@ -509,7 +508,7 @@
 	.mask_flags = 0,
 };
 
-static struct snd_akm4xxx akm_delta66e __devinitdata = {
+static struct snd_akm4xxx akm_delta66e = {
 	.type = SND_AK4524,
 	.num_adcs = 4,
 	.num_dacs = 4,
@@ -519,7 +518,7 @@
 	}
 };
 
-static struct snd_ak4xxx_private akm_delta66e_priv __devinitdata = {
+static struct snd_ak4xxx_private akm_delta66e_priv = {
 	.caddr = 2,
 	.cif = 0, /* the default level of the CIF pin from AK4524 */
 	.data_mask = ICE1712_DELTA_66E_DOUT,
@@ -532,7 +531,7 @@
 };
 
 
-static struct snd_akm4xxx akm_delta44 __devinitdata = {
+static struct snd_akm4xxx akm_delta44 = {
 	.type = SND_AK4524,
 	.num_adcs = 4,
 	.num_dacs = 4,
@@ -542,7 +541,7 @@
 	}
 };
 
-static struct snd_ak4xxx_private akm_delta44_priv __devinitdata = {
+static struct snd_ak4xxx_private akm_delta44_priv = {
 	.caddr = 2,
 	.cif = 0, /* the default level of the CIF pin from AK4524 */
 	.data_mask = ICE1712_DELTA_CODEC_SERIAL_DATA,
@@ -554,7 +553,7 @@
 	.mask_flags = 0,
 };
 
-static struct snd_akm4xxx akm_vx442 __devinitdata = {
+static struct snd_akm4xxx akm_vx442 = {
 	.type = SND_AK4524,
 	.num_adcs = 4,
 	.num_dacs = 4,
@@ -564,7 +563,7 @@
 	}
 };
 
-static struct snd_ak4xxx_private akm_vx442_priv __devinitdata = {
+static struct snd_ak4xxx_private akm_vx442_priv = {
 	.caddr = 2,
 	.cif = 0,
 	.data_mask = ICE1712_VX442_DOUT,
@@ -576,7 +575,7 @@
 	.mask_flags = 0,
 };
 
-static int __devinit snd_ice1712_delta_init(struct snd_ice1712 *ice)
+static int snd_ice1712_delta_init(struct snd_ice1712 *ice)
 {
 	int err;
 	struct snd_akm4xxx *ak;
@@ -617,7 +616,7 @@
 		ice->num_total_dacs = 4;	/* two AK4324 codecs */
 		break;
 	case ICE1712_SUBDEVICE_VX442:
-	case ICE1712_SUBDEVICE_DELTA66E:	/* omni not suported yet */
+	case ICE1712_SUBDEVICE_DELTA66E:	/* omni not supported yet */
 		ice->num_total_dacs = 4;
 		ice->num_total_adcs = 4;
 		break;
@@ -714,19 +713,19 @@
  * additional controls for M-Audio cards
  */
 
-static struct snd_kcontrol_new snd_ice1712_delta1010_wordclock_select __devinitdata =
+static struct snd_kcontrol_new snd_ice1712_delta1010_wordclock_select =
 ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_MIXER, "Word Clock Sync", 0, ICE1712_DELTA_WORD_CLOCK_SELECT, 1, 0);
-static struct snd_kcontrol_new snd_ice1712_delta1010lt_wordclock_select __devinitdata =
+static struct snd_kcontrol_new snd_ice1712_delta1010lt_wordclock_select =
 ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_MIXER, "Word Clock Sync", 0, ICE1712_DELTA_1010LT_WORDCLOCK, 0, 0);
-static struct snd_kcontrol_new snd_ice1712_delta1010_wordclock_status __devinitdata =
+static struct snd_kcontrol_new snd_ice1712_delta1010_wordclock_status =
 ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_MIXER, "Word Clock Status", 0, ICE1712_DELTA_WORD_CLOCK_STATUS, 1, SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE);
-static struct snd_kcontrol_new snd_ice1712_deltadio2496_spdif_in_select __devinitdata =
+static struct snd_kcontrol_new snd_ice1712_deltadio2496_spdif_in_select =
 ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_MIXER, "IEC958 Input Optical", 0, ICE1712_DELTA_SPDIF_INPUT_SELECT, 0, 0);
-static struct snd_kcontrol_new snd_ice1712_delta_spdif_in_status __devinitdata =
+static struct snd_kcontrol_new snd_ice1712_delta_spdif_in_status =
 ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_MIXER, "Delta IEC958 Input Status", 0, ICE1712_DELTA_SPDIF_IN_STAT, 1, SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE);
 
 
-static int __devinit snd_ice1712_delta_add_controls(struct snd_ice1712 *ice)
+static int snd_ice1712_delta_add_controls(struct snd_ice1712 *ice)
 {
 	int err;
 
@@ -802,7 +801,7 @@
 
 
 /* entry point */
-struct snd_ice1712_card_info snd_ice1712_delta_cards[] __devinitdata = {
+struct snd_ice1712_card_info snd_ice1712_delta_cards[] = {
 	{
 		.subvendor = ICE1712_SUBDEVICE_DELTA1010,
 		.name = "M Audio Delta 1010",
diff --git a/sound/pci/ice1712/ews.c b/sound/pci/ice1712/ews.c
index 6fe35b8..bc2e701 100644
--- a/sound/pci/ice1712/ews.c
+++ b/sound/pci/ice1712/ews.c
@@ -22,7 +22,6 @@
  *
  */      
 
-#include <asm/io.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
@@ -344,7 +343,7 @@
 
 /*
  */
-static struct snd_akm4xxx akm_ews88mt __devinitdata = {
+static struct snd_akm4xxx akm_ews88mt = {
 	.num_adcs = 8,
 	.num_dacs = 8,
 	.type = SND_AK4524,
@@ -354,7 +353,7 @@
 	}
 };
 
-static struct snd_ak4xxx_private akm_ews88mt_priv __devinitdata = {
+static struct snd_ak4xxx_private akm_ews88mt_priv = {
 	.caddr = 2,
 	.cif = 1, /* CIF high */
 	.data_mask = ICE1712_EWS88_SERIAL_DATA,
@@ -366,7 +365,7 @@
 	.mask_flags = 0,
 };
 
-static struct snd_akm4xxx akm_ewx2496 __devinitdata = {
+static struct snd_akm4xxx akm_ewx2496 = {
 	.num_adcs = 2,
 	.num_dacs = 2,
 	.type = SND_AK4524,
@@ -375,7 +374,7 @@
 	}
 };
 
-static struct snd_ak4xxx_private akm_ewx2496_priv __devinitdata = {
+static struct snd_ak4xxx_private akm_ewx2496_priv = {
 	.caddr = 2,
 	.cif = 1, /* CIF high */
 	.data_mask = ICE1712_EWS88_SERIAL_DATA,
@@ -387,7 +386,7 @@
 	.mask_flags = 0,
 };
 
-static struct snd_akm4xxx akm_6fire __devinitdata = {
+static struct snd_akm4xxx akm_6fire = {
 	.num_adcs = 6,
 	.num_dacs = 6,
 	.type = SND_AK4524,
@@ -396,7 +395,7 @@
 	}
 };
 
-static struct snd_ak4xxx_private akm_6fire_priv __devinitdata = {
+static struct snd_ak4xxx_private akm_6fire_priv = {
 	.caddr = 2,
 	.cif = 1, /* CIF high */
 	.data_mask = ICE1712_6FIRE_SERIAL_DATA,
@@ -420,7 +419,7 @@
 
 static int snd_ice1712_6fire_write_pca(struct snd_ice1712 *ice, unsigned char reg, unsigned char data);
 
-static int __devinit snd_ice1712_ews_init(struct snd_ice1712 *ice)
+static int snd_ice1712_ews_init(struct snd_ice1712 *ice)
 {
 	int err;
 	struct snd_akm4xxx *ak;
@@ -576,7 +575,7 @@
 /* i/o sensitivity - this callback is shared among other devices, too */
 static int snd_ice1712_ewx_io_sense_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo){
 
-	static char *texts[2] = {
+	static const char * const texts[2] = {
 		"+4dBu", "-10dBV",
 	};
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
@@ -616,7 +615,7 @@
 	return val != nval;
 }
 
-static struct snd_kcontrol_new snd_ice1712_ewx2496_controls[] __devinitdata = {
+static struct snd_kcontrol_new snd_ice1712_ewx2496_controls[] = {
 	{
 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 		.name = "Input Sensitivity Switch",
@@ -724,7 +723,7 @@
 	return ndata != data;
 }
 
-static struct snd_kcontrol_new snd_ice1712_ews88mt_input_sense __devinitdata = {
+static struct snd_kcontrol_new snd_ice1712_ews88mt_input_sense = {
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name = "Input Sensitivity Switch",
 	.info = snd_ice1712_ewx_io_sense_info,
@@ -733,7 +732,7 @@
 	.count = 8,
 };
 
-static struct snd_kcontrol_new snd_ice1712_ews88mt_output_sense __devinitdata = {
+static struct snd_kcontrol_new snd_ice1712_ews88mt_output_sense = {
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name = "Output Sensitivity Switch",
 	.info = snd_ice1712_ewx_io_sense_info,
@@ -811,7 +810,7 @@
   .private_value = xshift | (xinvert << 8),\
 }
 
-static struct snd_kcontrol_new snd_ice1712_ews88d_controls[] __devinitdata = {
+static struct snd_kcontrol_new snd_ice1712_ews88d_controls[] = {
 	EWS88D_CONTROL(SNDRV_CTL_ELEM_IFACE_MIXER, "IEC958 Input Optical", 0, 1, 0), /* inverted */
 	EWS88D_CONTROL(SNDRV_CTL_ELEM_IFACE_MIXER, "ADAT Output Optical", 1, 0, 0),
 	EWS88D_CONTROL(SNDRV_CTL_ELEM_IFACE_MIXER, "ADAT External Master Clock", 2, 0, 0),
@@ -899,7 +898,7 @@
 
 static int snd_ice1712_6fire_select_input_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
-	static char *texts[4] = {
+	static const char * const texts[4] = {
 		"Internal", "Front Input", "Rear Input", "Wave Table"
 	};
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
@@ -948,7 +947,7 @@
   .private_value = xshift | (xinvert << 8),\
 }
 
-static struct snd_kcontrol_new snd_ice1712_6fire_controls[] __devinitdata = {
+static struct snd_kcontrol_new snd_ice1712_6fire_controls[] = {
 	{
 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 		.name = "Analog Input Select",
@@ -964,7 +963,7 @@
 };
 
 
-static int __devinit snd_ice1712_ews_add_controls(struct snd_ice1712 *ice)
+static int snd_ice1712_ews_add_controls(struct snd_ice1712 *ice)
 {
 	unsigned int idx;
 	int err;
@@ -1030,7 +1029,7 @@
 
 
 /* entry point */
-struct snd_ice1712_card_info snd_ice1712_ews_cards[] __devinitdata = {
+struct snd_ice1712_card_info snd_ice1712_ews_cards[] = {
 	{
 		.subvendor = ICE1712_SUBDEVICE_EWX2496,
 		.name = "TerraTec EWX24/96",
diff --git a/sound/pci/ice1712/hoontech.c b/sound/pci/ice1712/hoontech.c
index 6914189..59e37c5 100644
--- a/sound/pci/ice1712/hoontech.c
+++ b/sound/pci/ice1712/hoontech.c
@@ -21,7 +21,6 @@
  *
  */      
 
-#include <asm/io.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
@@ -40,7 +39,7 @@
 	unsigned short boxconfig[4];
 };
 
-static void __devinit snd_ice1712_stdsp24_gpio_write(struct snd_ice1712 *ice, unsigned char byte)
+static void snd_ice1712_stdsp24_gpio_write(struct snd_ice1712 *ice, unsigned char byte)
 {
 	byte |= ICE1712_STDSP24_CLOCK_BIT;
 	udelay(100);
@@ -53,7 +52,7 @@
 	snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, byte);
 }
 
-static void __devinit snd_ice1712_stdsp24_darear(struct snd_ice1712 *ice, int activate)
+static void snd_ice1712_stdsp24_darear(struct snd_ice1712 *ice, int activate)
 {
 	struct hoontech_spec *spec = ice->spec;
 	mutex_lock(&ice->gpio_mutex);
@@ -62,7 +61,7 @@
 	mutex_unlock(&ice->gpio_mutex);
 }
 
-static void __devinit snd_ice1712_stdsp24_mute(struct snd_ice1712 *ice, int activate)
+static void snd_ice1712_stdsp24_mute(struct snd_ice1712 *ice, int activate)
 {
 	struct hoontech_spec *spec = ice->spec;
 	mutex_lock(&ice->gpio_mutex);
@@ -71,7 +70,7 @@
 	mutex_unlock(&ice->gpio_mutex);
 }
 
-static void __devinit snd_ice1712_stdsp24_insel(struct snd_ice1712 *ice, int activate)
+static void snd_ice1712_stdsp24_insel(struct snd_ice1712 *ice, int activate)
 {
 	struct hoontech_spec *spec = ice->spec;
 	mutex_lock(&ice->gpio_mutex);
@@ -80,7 +79,7 @@
 	mutex_unlock(&ice->gpio_mutex);
 }
 
-static void __devinit snd_ice1712_stdsp24_box_channel(struct snd_ice1712 *ice, int box, int chn, int activate)
+static void snd_ice1712_stdsp24_box_channel(struct snd_ice1712 *ice, int box, int chn, int activate)
 {
 	struct hoontech_spec *spec = ice->spec;
 
@@ -130,7 +129,7 @@
 	mutex_unlock(&ice->gpio_mutex);
 }
 
-static void __devinit snd_ice1712_stdsp24_box_midi(struct snd_ice1712 *ice, int box, int master)
+static void snd_ice1712_stdsp24_box_midi(struct snd_ice1712 *ice, int box, int master)
 {
 	struct hoontech_spec *spec = ice->spec;
 
@@ -158,7 +157,7 @@
 	mutex_unlock(&ice->gpio_mutex);
 }
 
-static void __devinit snd_ice1712_stdsp24_midi2(struct snd_ice1712 *ice, int activate)
+static void snd_ice1712_stdsp24_midi2(struct snd_ice1712 *ice, int activate)
 {
 	struct hoontech_spec *spec = ice->spec;
 	mutex_lock(&ice->gpio_mutex);
@@ -167,7 +166,7 @@
 	mutex_unlock(&ice->gpio_mutex);
 }
 
-static int __devinit snd_ice1712_hoontech_init(struct snd_ice1712 *ice)
+static int snd_ice1712_hoontech_init(struct snd_ice1712 *ice)
 {
 	struct hoontech_spec *spec;
 	int box, chn;
@@ -267,10 +266,10 @@
 	snd_ice1712_write(ice, ICE1712_IREG_GPIO_WRITE_MASK, ~tmp);
 }
 
-static int __devinit snd_ice1712_value_init(struct snd_ice1712 *ice)
+static int snd_ice1712_value_init(struct snd_ice1712 *ice)
 {
 	/* Hoontech STDSP24 with modified hardware */
-	static struct snd_akm4xxx akm_stdsp24_mv __devinitdata = {
+	static struct snd_akm4xxx akm_stdsp24_mv = {
 		.num_adcs = 2,
 		.num_dacs = 2,
 		.type = SND_AK4524,
@@ -279,7 +278,7 @@
 		}
 	};
 
-	static struct snd_ak4xxx_private akm_stdsp24_mv_priv __devinitdata = {
+	static struct snd_ak4xxx_private akm_stdsp24_mv_priv = {
 		.caddr = 2,
 		.cif = 1, /* CIF high */
 		.data_mask = ICE1712_STDSP24_SERIAL_DATA,
@@ -317,7 +316,7 @@
 	return 0;
 }
 
-static int __devinit snd_ice1712_ez8_init(struct snd_ice1712 *ice)
+static int snd_ice1712_ez8_init(struct snd_ice1712 *ice)
 {
 	ice->gpio.write_mask = ice->eeprom.gpiomask;
 	ice->gpio.direction = ice->eeprom.gpiodir;
@@ -329,7 +328,7 @@
 
 
 /* entry point */
-struct snd_ice1712_card_info snd_ice1712_hoontech_cards[] __devinitdata = {
+struct snd_ice1712_card_info snd_ice1712_hoontech_cards[] = {
 	{
 		.subvendor = ICE1712_SUBDEVICE_STDSP24,
 		.name = "Hoontech SoundTrack Audio DSP24",
diff --git a/sound/pci/ice1712/ice1712.c b/sound/pci/ice1712/ice1712.c
index 5be2e12..2ffdc35 100644
--- a/sound/pci/ice1712/ice1712.c
+++ b/sound/pci/ice1712/ice1712.c
@@ -47,7 +47,6 @@
  */
 
 
-#include <linux/io.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
@@ -280,7 +279,7 @@
 	return val != nval;
 }
 
-static struct snd_kcontrol_new snd_ice1712_mixer_digmix_route_ac97 __devinitdata = {
+static struct snd_kcontrol_new snd_ice1712_mixer_digmix_route_ac97 = {
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name = "Digital Mixer To AC97",
 	.info = snd_ice1712_digmix_route_ac97_info,
@@ -388,7 +387,7 @@
 /*
  * create and initialize callbacks for cs8427 interface
  */
-int __devinit snd_ice1712_init_cs8427(struct snd_ice1712 *ice, int addr)
+int snd_ice1712_init_cs8427(struct snd_ice1712 *ice, int addr)
 {
 	int err;
 
@@ -879,7 +878,7 @@
 	.pointer =	snd_ice1712_capture_pointer,
 };
 
-static int __devinit snd_ice1712_pcm(struct snd_ice1712 *ice, int device, struct snd_pcm **rpcm)
+static int snd_ice1712_pcm(struct snd_ice1712 *ice, int device, struct snd_pcm **rpcm)
 {
 	struct snd_pcm *pcm;
 	int err;
@@ -909,7 +908,7 @@
 	return 0;
 }
 
-static int __devinit snd_ice1712_pcm_ds(struct snd_ice1712 *ice, int device, struct snd_pcm **rpcm)
+static int snd_ice1712_pcm_ds(struct snd_ice1712 *ice, int device, struct snd_pcm **rpcm)
 {
 	struct snd_pcm *pcm;
 	int err;
@@ -1254,7 +1253,7 @@
 	.pointer =	snd_ice1712_capture_pro_pointer,
 };
 
-static int __devinit snd_ice1712_pcm_profi(struct snd_ice1712 *ice, int device, struct snd_pcm **rpcm)
+static int snd_ice1712_pcm_profi(struct snd_ice1712 *ice, int device, struct snd_pcm **rpcm)
 {
 	struct snd_pcm *pcm;
 	int err;
@@ -1388,7 +1387,7 @@
 
 static const DECLARE_TLV_DB_SCALE(db_scale_playback, -14400, 150, 0);
 
-static struct snd_kcontrol_new snd_ice1712_multi_playback_ctrls[] __devinitdata = {
+static struct snd_kcontrol_new snd_ice1712_multi_playback_ctrls[] = {
 	{
 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 		.name = "Multi Playback Switch",
@@ -1412,7 +1411,7 @@
 	},
 };
 
-static struct snd_kcontrol_new snd_ice1712_multi_capture_analog_switch __devinitdata = {
+static struct snd_kcontrol_new snd_ice1712_multi_capture_analog_switch = {
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name = "H/W Multi Capture Switch",
 	.info = snd_ice1712_pro_mixer_switch_info,
@@ -1421,7 +1420,7 @@
 	.private_value = 10,
 };
 
-static struct snd_kcontrol_new snd_ice1712_multi_capture_spdif_switch __devinitdata = {
+static struct snd_kcontrol_new snd_ice1712_multi_capture_spdif_switch = {
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name = SNDRV_CTL_NAME_IEC958("Multi ", CAPTURE, SWITCH),
 	.info = snd_ice1712_pro_mixer_switch_info,
@@ -1431,7 +1430,7 @@
 	.count = 2,
 };
 
-static struct snd_kcontrol_new snd_ice1712_multi_capture_analog_volume __devinitdata = {
+static struct snd_kcontrol_new snd_ice1712_multi_capture_analog_volume = {
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
 		   SNDRV_CTL_ELEM_ACCESS_TLV_READ),
@@ -1443,7 +1442,7 @@
 	.tlv = { .p = db_scale_playback }
 };
 
-static struct snd_kcontrol_new snd_ice1712_multi_capture_spdif_volume __devinitdata = {
+static struct snd_kcontrol_new snd_ice1712_multi_capture_spdif_volume = {
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name = SNDRV_CTL_NAME_IEC958("Multi ", CAPTURE, VOLUME),
 	.info = snd_ice1712_pro_mixer_volume_info,
@@ -1453,7 +1452,7 @@
 	.count = 2,
 };
 
-static int __devinit snd_ice1712_build_pro_mixer(struct snd_ice1712 *ice)
+static int snd_ice1712_build_pro_mixer(struct snd_ice1712 *ice)
 {
 	struct snd_card *card = ice->card;
 	unsigned int idx;
@@ -1512,7 +1511,7 @@
 	ice->ac97 = NULL;
 }
 
-static int __devinit snd_ice1712_ac97_mixer(struct snd_ice1712 *ice)
+static int snd_ice1712_ac97_mixer(struct snd_ice1712 *ice)
 {
 	int err, bus_num = 0;
 	struct snd_ac97_template ac97;
@@ -1611,7 +1610,7 @@
 	snd_iprintf(buffer, "  GPIO_DIRECTION   : 0x%02x\n", (unsigned)snd_ice1712_read(ice, ICE1712_IREG_GPIO_DIRECTION));
 }
 
-static void __devinit snd_ice1712_proc_init(struct snd_ice1712 *ice)
+static void snd_ice1712_proc_init(struct snd_ice1712 *ice)
 {
 	struct snd_info_entry *entry;
 
@@ -1640,7 +1639,7 @@
 	return 0;
 }
 
-static struct snd_kcontrol_new snd_ice1712_eeprom __devinitdata = {
+static struct snd_kcontrol_new snd_ice1712_eeprom = {
 	.iface = SNDRV_CTL_ELEM_IFACE_CARD,
 	.name = "ICE1712 EEPROM",
 	.access = SNDRV_CTL_ELEM_ACCESS_READ,
@@ -1676,7 +1675,7 @@
 	return 0;
 }
 
-static struct snd_kcontrol_new snd_ice1712_spdif_default __devinitdata =
+static struct snd_kcontrol_new snd_ice1712_spdif_default =
 {
 	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,
 	.name =         SNDRV_CTL_NAME_IEC958("", PLAYBACK, DEFAULT),
@@ -1727,7 +1726,7 @@
 	return 0;
 }
 
-static struct snd_kcontrol_new snd_ice1712_spdif_maskc __devinitdata =
+static struct snd_kcontrol_new snd_ice1712_spdif_maskc =
 {
 	.access =	SNDRV_CTL_ELEM_ACCESS_READ,
 	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,
@@ -1736,7 +1735,7 @@
 	.get =		snd_ice1712_spdif_maskc_get,
 };
 
-static struct snd_kcontrol_new snd_ice1712_spdif_maskp __devinitdata =
+static struct snd_kcontrol_new snd_ice1712_spdif_maskp =
 {
 	.access =	SNDRV_CTL_ELEM_ACCESS_READ,
 	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,
@@ -1763,7 +1762,7 @@
 	return 0;
 }
 
-static struct snd_kcontrol_new snd_ice1712_spdif_stream __devinitdata =
+static struct snd_kcontrol_new snd_ice1712_spdif_stream =
 {
 	.access =	(SNDRV_CTL_ELEM_ACCESS_READWRITE |
 			 SNDRV_CTL_ELEM_ACCESS_INACTIVE),
@@ -1894,7 +1893,7 @@
 	return change;
 }
 
-static struct snd_kcontrol_new snd_ice1712_pro_internal_clock __devinitdata = {
+static struct snd_kcontrol_new snd_ice1712_pro_internal_clock = {
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name = "Multi Track Internal Clock",
 	.info = snd_ice1712_pro_internal_clock_info,
@@ -1965,7 +1964,7 @@
 	return change;
 }
 
-static struct snd_kcontrol_new snd_ice1712_pro_internal_clock_default __devinitdata = {
+static struct snd_kcontrol_new snd_ice1712_pro_internal_clock_default = {
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name = "Multi Track Internal Clock Default",
 	.info = snd_ice1712_pro_internal_clock_default_info,
@@ -1996,7 +1995,7 @@
 	return change;
 }
 
-static struct snd_kcontrol_new snd_ice1712_pro_rate_locking __devinitdata = {
+static struct snd_kcontrol_new snd_ice1712_pro_rate_locking = {
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name = "Multi Track Rate Locking",
 	.info = snd_ice1712_pro_rate_locking_info,
@@ -2027,7 +2026,7 @@
 	return change;
 }
 
-static struct snd_kcontrol_new snd_ice1712_pro_rate_reset __devinitdata = {
+static struct snd_kcontrol_new snd_ice1712_pro_rate_reset = {
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name = "Multi Track Rate Reset",
 	.info = snd_ice1712_pro_rate_reset_info,
@@ -2194,7 +2193,7 @@
 	return change;
 }
 
-static struct snd_kcontrol_new snd_ice1712_mixer_pro_analog_route __devinitdata = {
+static struct snd_kcontrol_new snd_ice1712_mixer_pro_analog_route = {
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name = "H/W Playback Route",
 	.info = snd_ice1712_pro_route_info,
@@ -2202,7 +2201,7 @@
 	.put = snd_ice1712_pro_route_analog_put,
 };
 
-static struct snd_kcontrol_new snd_ice1712_mixer_pro_spdif_route __devinitdata = {
+static struct snd_kcontrol_new snd_ice1712_mixer_pro_spdif_route = {
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, NONE) "Route",
 	.info = snd_ice1712_pro_route_info,
@@ -2244,7 +2243,7 @@
 	return change;
 }
 
-static struct snd_kcontrol_new snd_ice1712_mixer_pro_volume_rate __devinitdata = {
+static struct snd_kcontrol_new snd_ice1712_mixer_pro_volume_rate = {
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name = "Multi Track Volume Rate",
 	.info = snd_ice1712_pro_volume_rate_info,
@@ -2277,7 +2276,7 @@
 	return 0;
 }
 
-static struct snd_kcontrol_new snd_ice1712_mixer_pro_peak __devinitdata = {
+static struct snd_kcontrol_new snd_ice1712_mixer_pro_peak = {
 	.iface = SNDRV_CTL_ELEM_IFACE_PCM,
 	.name = "Multi Track Peak",
 	.access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
@@ -2292,16 +2291,16 @@
 /*
  * list of available boards
  */
-static struct snd_ice1712_card_info *card_tables[] __devinitdata = {
+static struct snd_ice1712_card_info *card_tables[] = {
 	snd_ice1712_hoontech_cards,
 	snd_ice1712_delta_cards,
 	snd_ice1712_ews_cards,
 	NULL,
 };
 
-static unsigned char __devinit snd_ice1712_read_i2c(struct snd_ice1712 *ice,
-						 unsigned char dev,
-						 unsigned char addr)
+static unsigned char snd_ice1712_read_i2c(struct snd_ice1712 *ice,
+					  unsigned char dev,
+					  unsigned char addr)
 {
 	long t = 0x10000;
 
@@ -2311,8 +2310,8 @@
 	return inb(ICEREG(ice, I2C_DATA));
 }
 
-static int __devinit snd_ice1712_read_eeprom(struct snd_ice1712 *ice,
-					     const char *modelname)
+static int snd_ice1712_read_eeprom(struct snd_ice1712 *ice,
+				   const char *modelname)
 {
 	int dev = 0xa0;		/* EEPROM device address */
 	unsigned int i, size;
@@ -2386,7 +2385,7 @@
 
 
 
-static int __devinit snd_ice1712_chip_init(struct snd_ice1712 *ice)
+static int snd_ice1712_chip_init(struct snd_ice1712 *ice)
 {
 	outb(ICE1712_RESET | ICE1712_NATIVE, ICEREG(ice, CONTROL));
 	udelay(200);
@@ -2433,7 +2432,7 @@
 	return 0;
 }
 
-int __devinit snd_ice1712_spdif_build_controls(struct snd_ice1712 *ice)
+int snd_ice1712_spdif_build_controls(struct snd_ice1712 *ice)
 {
 	int err;
 	struct snd_kcontrol *kctl;
@@ -2461,7 +2460,7 @@
 }
 
 
-static int __devinit snd_ice1712_build_controls(struct snd_ice1712 *ice)
+static int snd_ice1712_build_controls(struct snd_ice1712 *ice)
 {
 	int err;
 
@@ -2531,13 +2530,13 @@
 	return snd_ice1712_free(ice);
 }
 
-static int __devinit snd_ice1712_create(struct snd_card *card,
-					struct pci_dev *pci,
-					const char *modelname,
-					int omni,
-					int cs8427_timeout,
-					int dxr_enable,
-					struct snd_ice1712 **r_ice1712)
+static int snd_ice1712_create(struct snd_card *card,
+			      struct pci_dev *pci,
+			      const char *modelname,
+			      int omni,
+			      int cs8427_timeout,
+			      int dxr_enable,
+			      struct snd_ice1712 **r_ice1712)
 {
 	struct snd_ice1712 *ice;
 	int err;
@@ -2651,10 +2650,10 @@
  *
  */
 
-static struct snd_ice1712_card_info no_matched __devinitdata;
+static struct snd_ice1712_card_info no_matched;
 
-static int __devinit snd_ice1712_probe(struct pci_dev *pci,
-				       const struct pci_device_id *pci_id)
+static int snd_ice1712_probe(struct pci_dev *pci,
+			     const struct pci_device_id *pci_id)
 {
 	static int dev;
 	struct snd_card *card;
@@ -2686,6 +2685,7 @@
 	for (tbl = card_tables; *tbl; tbl++) {
 		for (c = *tbl; c->subvendor; c++) {
 			if (c->subvendor == ice->eeprom.subvendor) {
+				ice->card_info = c;
 				strcpy(card->shortname, c->name);
 				if (c->driver) /* specific driver? */
 					strcpy(card->driver, c->driver);
@@ -2797,9 +2797,14 @@
 	return 0;
 }
 
-static void __devexit snd_ice1712_remove(struct pci_dev *pci)
+static void snd_ice1712_remove(struct pci_dev *pci)
 {
-	snd_card_free(pci_get_drvdata(pci));
+	struct snd_card *card = pci_get_drvdata(pci);
+	struct snd_ice1712 *ice = card->private_data;
+
+	if (ice->card_info && ice->card_info->chip_exit)
+		ice->card_info->chip_exit(ice);
+	snd_card_free(card);
 	pci_set_drvdata(pci, NULL);
 }
 
@@ -2807,7 +2812,7 @@
 	.name = KBUILD_MODNAME,
 	.id_table = snd_ice1712_ids,
 	.probe = snd_ice1712_probe,
-	.remove = __devexit_p(snd_ice1712_remove),
+	.remove = snd_ice1712_remove,
 };
 
 module_pci_driver(ice1712_driver);
diff --git a/sound/pci/ice1712/ice1712.h b/sound/pci/ice1712/ice1712.h
index d0e7d87..b209fc3 100644
--- a/sound/pci/ice1712/ice1712.h
+++ b/sound/pci/ice1712/ice1712.h
@@ -22,6 +22,7 @@
  *
  */
 
+#include <linux/io.h>
 #include <sound/control.h>
 #include <sound/ac97_codec.h>
 #include <sound/rawmidi.h>
@@ -288,6 +289,7 @@
 	} ops;
 };
 
+struct snd_ice1712_card_info;
 
 struct snd_ice1712 {
 	unsigned long conp_dma_size;
@@ -324,6 +326,7 @@
 	struct snd_info_entry *proc_entry;
 
 	struct snd_ice1712_eeprom eeprom;
+	struct snd_ice1712_card_info *card_info;
 
 	unsigned int pro_volumes[20];
 	unsigned int omni:1;		/* Delta Omni I/O */
@@ -381,7 +384,7 @@
 	unsigned char (*set_mclk)(struct snd_ice1712 *ice, unsigned int rate);
 	int (*set_spdif_clock)(struct snd_ice1712 *ice, int type);
 	int (*get_spdif_master_type)(struct snd_ice1712 *ice);
-	char **ext_clock_names;
+	const char * const *ext_clock_names;
 	int ext_clock_count;
 	void (*pro_open)(struct snd_ice1712 *, struct snd_pcm_substream *);
 #ifdef CONFIG_PM_SLEEP
@@ -513,10 +516,11 @@
 
 struct snd_ice1712_card_info {
 	unsigned int subvendor;
-	char *name;
-	char *model;
-	char *driver;
+	const char *name;
+	const char *model;
+	const char *driver;
 	int (*chip_init)(struct snd_ice1712 *);
+	void (*chip_exit)(struct snd_ice1712 *);
 	int (*build_controls)(struct snd_ice1712 *);
 	unsigned int no_mpu401:1;
 	unsigned int mpu401_1_info_flags;
diff --git a/sound/pci/ice1712/ice1724.c b/sound/pci/ice1712/ice1724.c
index 245d874..ce70e7f 100644
--- a/sound/pci/ice1712/ice1724.c
+++ b/sound/pci/ice1712/ice1724.c
@@ -22,7 +22,6 @@
  *
  */
 
-#include <linux/io.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
@@ -54,6 +53,7 @@
 #include "wtm.h"
 #include "se.h"
 #include "quartet.h"
+#include "psc724.h"
 
 MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
 MODULE_DESCRIPTION("VIA ICEnsemble ICE1724/1720 (Envy24HT/PT)");
@@ -106,7 +106,7 @@
 static int PRO_RATE_RESET = 1;
 static unsigned int PRO_RATE_DEFAULT = 44100;
 
-static char *ext_clock_names[1] = { "IEC958 In" };
+static const char * const ext_clock_names[1] = { "IEC958 In" };
 
 /*
  *  Basic I/O
@@ -1135,7 +1135,7 @@
 	.pointer =	snd_vt1724_pcm_pointer,
 };
 
-static int __devinit snd_vt1724_pcm_profi(struct snd_ice1712 *ice, int device)
+static int snd_vt1724_pcm_profi(struct snd_ice1712 *ice, int device)
 {
 	struct snd_pcm *pcm;
 	int capt, err;
@@ -1315,7 +1315,7 @@
 };
 
 
-static int __devinit snd_vt1724_pcm_spdif(struct snd_ice1712 *ice, int device)
+static int snd_vt1724_pcm_spdif(struct snd_ice1712 *ice, int device)
 {
 	char *name;
 	struct snd_pcm *pcm;
@@ -1449,7 +1449,7 @@
 };
 
 
-static int __devinit snd_vt1724_pcm_indep(struct snd_ice1712 *ice, int device)
+static int snd_vt1724_pcm_indep(struct snd_ice1712 *ice, int device)
 {
 	struct snd_pcm *pcm;
 	int play;
@@ -1484,7 +1484,7 @@
  *  Mixer section
  */
 
-static int __devinit snd_vt1724_ac97_mixer(struct snd_ice1712 *ice)
+static int snd_vt1724_ac97_mixer(struct snd_ice1712 *ice)
 {
 	int err;
 
@@ -1570,7 +1570,7 @@
 			    idx, inb(ice->profi_port+idx));
 }
 
-static void __devinit snd_vt1724_proc_init(struct snd_ice1712 *ice)
+static void snd_vt1724_proc_init(struct snd_ice1712 *ice)
 {
 	struct snd_info_entry *entry;
 
@@ -1599,7 +1599,7 @@
 	return 0;
 }
 
-static struct snd_kcontrol_new snd_vt1724_eeprom __devinitdata = {
+static struct snd_kcontrol_new snd_vt1724_eeprom = {
 	.iface = SNDRV_CTL_ELEM_IFACE_CARD,
 	.name = "ICE1724 EEPROM",
 	.access = SNDRV_CTL_ELEM_ACCESS_READ,
@@ -1712,7 +1712,7 @@
 	return val != old;
 }
 
-static struct snd_kcontrol_new snd_vt1724_spdif_default __devinitdata =
+static struct snd_kcontrol_new snd_vt1724_spdif_default =
 {
 	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,
 	.name =         SNDRV_CTL_NAME_IEC958("", PLAYBACK, DEFAULT),
@@ -1744,7 +1744,7 @@
 	return 0;
 }
 
-static struct snd_kcontrol_new snd_vt1724_spdif_maskc __devinitdata =
+static struct snd_kcontrol_new snd_vt1724_spdif_maskc =
 {
 	.access =	SNDRV_CTL_ELEM_ACCESS_READ,
 	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,
@@ -1753,7 +1753,7 @@
 	.get =		snd_vt1724_spdif_maskc_get,
 };
 
-static struct snd_kcontrol_new snd_vt1724_spdif_maskp __devinitdata =
+static struct snd_kcontrol_new snd_vt1724_spdif_maskp =
 {
 	.access =	SNDRV_CTL_ELEM_ACCESS_READ,
 	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,
@@ -1790,7 +1790,7 @@
 	return old != val;
 }
 
-static struct snd_kcontrol_new snd_vt1724_spdif_switch __devinitdata =
+static struct snd_kcontrol_new snd_vt1724_spdif_switch =
 {
 	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
 	/* FIXME: the following conflict with IEC958 Playback Route */
@@ -1965,7 +1965,7 @@
 	return old_rate != new_rate;
 }
 
-static struct snd_kcontrol_new snd_vt1724_pro_internal_clock __devinitdata = {
+static struct snd_kcontrol_new snd_vt1724_pro_internal_clock = {
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name = "Multi Track Internal Clock",
 	.info = snd_vt1724_pro_internal_clock_info,
@@ -1996,7 +1996,7 @@
 	return change;
 }
 
-static struct snd_kcontrol_new snd_vt1724_pro_rate_locking __devinitdata = {
+static struct snd_kcontrol_new snd_vt1724_pro_rate_locking = {
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name = "Multi Track Rate Locking",
 	.info = snd_vt1724_pro_rate_locking_info,
@@ -2027,7 +2027,7 @@
 	return change;
 }
 
-static struct snd_kcontrol_new snd_vt1724_pro_rate_reset __devinitdata = {
+static struct snd_kcontrol_new snd_vt1724_pro_rate_reset = {
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name = "Multi Track Rate Reset",
 	.info = snd_vt1724_pro_rate_reset_info,
@@ -2042,7 +2042,7 @@
 static int snd_vt1724_pro_route_info(struct snd_kcontrol *kcontrol,
 				     struct snd_ctl_elem_info *uinfo)
 {
-	static char *texts[] = {
+	static const char * const texts[] = {
 		"PCM Out", /* 0 */
 		"H/W In 0", "H/W In 1", /* 1-2 */
 		"IEC958 In L", "IEC958 In R", /* 3-4 */
@@ -2149,7 +2149,7 @@
 					 digital_route_shift(idx));
 }
 
-static struct snd_kcontrol_new snd_vt1724_mixer_pro_analog_route __devinitdata =
+static struct snd_kcontrol_new snd_vt1724_mixer_pro_analog_route =
 {
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name = "H/W Playback Route",
@@ -2158,7 +2158,7 @@
 	.put = snd_vt1724_pro_route_analog_put,
 };
 
-static struct snd_kcontrol_new snd_vt1724_mixer_pro_spdif_route __devinitdata = {
+static struct snd_kcontrol_new snd_vt1724_mixer_pro_spdif_route = {
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, NONE) "Route",
 	.info = snd_vt1724_pro_route_info,
@@ -2194,7 +2194,7 @@
 	return 0;
 }
 
-static struct snd_kcontrol_new snd_vt1724_mixer_pro_peak __devinitdata = {
+static struct snd_kcontrol_new snd_vt1724_mixer_pro_peak = {
 	.iface = SNDRV_CTL_ELEM_IFACE_PCM,
 	.name = "Multi Track Peak",
 	.access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
@@ -2206,13 +2206,13 @@
  *
  */
 
-static struct snd_ice1712_card_info no_matched __devinitdata;
+static struct snd_ice1712_card_info no_matched;
 
 
 /*
   ooAoo cards with no controls
 */
-static unsigned char ooaoo_sq210_eeprom[] __devinitdata = {
+static unsigned char ooaoo_sq210_eeprom[] = {
 	[ICE_EEP2_SYSCONF]     = 0x4c,	/* 49MHz crystal, no mpu401, no ADC,
 					   1xDACs */
 	[ICE_EEP2_ACLINK]      = 0x80,	/* I2S */
@@ -2232,7 +2232,7 @@
 };
 
 
-struct snd_ice1712_card_info snd_vt1724_ooaoo_cards[] __devinitdata = {
+static struct snd_ice1712_card_info snd_vt1724_ooaoo_cards[] = {
 	{
 		.name = "ooAoo SQ210a",
 		.model = "sq210a",
@@ -2242,7 +2242,7 @@
 	{ } /* terminator */
 };
 
-static struct snd_ice1712_card_info *card_tables[] __devinitdata = {
+static struct snd_ice1712_card_info *card_tables[] = {
 	snd_vt1724_revo_cards,
 	snd_vt1724_amp_cards,
 	snd_vt1724_aureon_cards,
@@ -2257,6 +2257,7 @@
 	snd_vt1724_se_cards,
 	snd_vt1724_qtet_cards,
 	snd_vt1724_ooaoo_cards,
+	snd_vt1724_psc724_cards,
 	NULL,
 };
 
@@ -2306,8 +2307,8 @@
 	mutex_unlock(&ice->i2c_mutex);
 }
 
-static int __devinit snd_vt1724_read_eeprom(struct snd_ice1712 *ice,
-					    const char *modelname)
+static int snd_vt1724_read_eeprom(struct snd_ice1712 *ice,
+				  const char *modelname)
 {
 	const int dev = 0xa0;		/* EEPROM device address */
 	unsigned int i, size;
@@ -2348,6 +2349,7 @@
 				ice->eeprom.subvendor = c->subvendor;
 			} else if (c->subvendor != ice->eeprom.subvendor)
 				continue;
+			ice->card_info = c;
 			if (!c->eeprom_size || !c->eeprom_data)
 				goto found;
 			/* if the EEPROM is given by the driver, use it */
@@ -2360,6 +2362,10 @@
 	}
 	printk(KERN_WARNING "ice1724: No matching model found for ID 0x%x\n",
 	       ice->eeprom.subvendor);
+#ifdef CONFIG_PM_SLEEP
+	/* assume AC97-only card which can suspend without additional code */
+	ice->pm_suspend_enabled = 1;
+#endif
 
  found:
 	ice->eeprom.size = snd_vt1724_read_i2c(ice, dev, 0x04);
@@ -2371,7 +2377,7 @@
 		return -EIO;
 	}
 	ice->eeprom.version = snd_vt1724_read_i2c(ice, dev, 0x05);
-	if (ice->eeprom.version != 2)
+	if (ice->eeprom.version != 1 && ice->eeprom.version != 2)
 		printk(KERN_WARNING "ice1724: Invalid EEPROM version %i\n",
 		       ice->eeprom.version);
 	size = ice->eeprom.size - 6;
@@ -2424,7 +2430,7 @@
 	return 0;
 }
 
-static int __devinit snd_vt1724_spdif_build_controls(struct snd_ice1712 *ice)
+static int snd_vt1724_spdif_build_controls(struct snd_ice1712 *ice)
 {
 	int err;
 	struct snd_kcontrol *kctl;
@@ -2466,7 +2472,7 @@
 }
 
 
-static int __devinit snd_vt1724_build_controls(struct snd_ice1712 *ice)
+static int snd_vt1724_build_controls(struct snd_ice1712 *ice)
 {
 	int err;
 
@@ -2526,10 +2532,10 @@
 	return snd_vt1724_free(ice);
 }
 
-static int __devinit snd_vt1724_create(struct snd_card *card,
-				       struct pci_dev *pci,
-				       const char *modelname,
-				       struct snd_ice1712 **r_ice1712)
+static int snd_vt1724_create(struct snd_card *card,
+			     struct pci_dev *pci,
+			     const char *modelname,
+			     struct snd_ice1712 **r_ice1712)
 {
 	struct snd_ice1712 *ice;
 	int err;
@@ -2616,8 +2622,8 @@
  *
  */
 
-static int __devinit snd_vt1724_probe(struct pci_dev *pci,
-				      const struct pci_device_id *pci_id)
+static int snd_vt1724_probe(struct pci_dev *pci,
+			    const struct pci_device_id *pci_id)
 {
 	static int dev;
 	struct snd_card *card;
@@ -2786,9 +2792,14 @@
 	return 0;
 }
 
-static void __devexit snd_vt1724_remove(struct pci_dev *pci)
+static void snd_vt1724_remove(struct pci_dev *pci)
 {
-	snd_card_free(pci_get_drvdata(pci));
+	struct snd_card *card = pci_get_drvdata(pci);
+	struct snd_ice1712 *ice = card->private_data;
+
+	if (ice->card_info && ice->card_info->chip_exit)
+		ice->card_info->chip_exit(ice);
+	snd_card_free(card);
 	pci_set_drvdata(pci, NULL);
 }
 
@@ -2889,7 +2900,7 @@
 	.name = KBUILD_MODNAME,
 	.id_table = snd_vt1724_ids,
 	.probe = snd_vt1724_probe,
-	.remove = __devexit_p(snd_vt1724_remove),
+	.remove = snd_vt1724_remove,
 	.driver = {
 		.pm = SND_VT1724_PM_OPS,
 	},
diff --git a/sound/pci/ice1712/juli.c b/sound/pci/ice1712/juli.c
index 14fd536..8855933 100644
--- a/sound/pci/ice1712/juli.c
+++ b/sound/pci/ice1712/juli.c
@@ -23,7 +23,6 @@
  *
  */
 
-#include <asm/io.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
@@ -283,7 +282,7 @@
 };
 
 
-static struct snd_akm4xxx akm_juli_dac __devinitdata = {
+static struct snd_akm4xxx akm_juli_dac = {
 	.type = SND_AK4358,
 	.num_dacs = 8,	/* DAC1 - analog out
 			   DAC2 - analog in monitor
@@ -358,7 +357,7 @@
 	return 0;
 }
 
-static struct snd_kcontrol_new juli_mute_controls[] __devinitdata = {
+static struct snd_kcontrol_new juli_mute_controls[] = {
 	{
 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 		.name = "Master Playback Switch",
@@ -412,7 +411,7 @@
 	},
 };
 
-static char *slave_vols[] __devinitdata = {
+static char *slave_vols[] = {
 	PCM_VOLUME,
 	MONITOR_AN_IN_VOLUME,
 	MONITOR_DIG_IN_VOLUME,
@@ -420,11 +419,11 @@
 	NULL
 };
 
-static __devinitdata
+static
 DECLARE_TLV_DB_SCALE(juli_master_db_scale, -6350, 50, 1);
 
-static struct snd_kcontrol __devinit *ctl_find(struct snd_card *card,
-		const char *name)
+static struct snd_kcontrol *ctl_find(struct snd_card *card,
+				     const char *name)
 {
 	struct snd_ctl_elem_id sid;
 	memset(&sid, 0, sizeof(sid));
@@ -434,8 +433,9 @@
 	return snd_ctl_find_id(card, &sid);
 }
 
-static void __devinit add_slaves(struct snd_card *card,
-				 struct snd_kcontrol *master, char **list)
+static void add_slaves(struct snd_card *card,
+		       struct snd_kcontrol *master,
+		       char * const *list)
 {
 	for (; *list; list++) {
 		struct snd_kcontrol *slave = ctl_find(card, *list);
@@ -447,7 +447,7 @@
 	}
 }
 
-static int __devinit juli_add_controls(struct snd_ice1712 *ice)
+static int juli_add_controls(struct snd_ice1712 *ice)
 {
 	struct juli_spec *spec = ice->spec;
 	int err;
@@ -579,7 +579,7 @@
 	}
 }
 
-static int __devinit juli_init(struct snd_ice1712 *ice)
+static int juli_init(struct snd_ice1712 *ice)
 {
 	static const unsigned char ak4114_init_vals[] = {
 		/* AK4117_REG_PWRDN */	AK4114_RST | AK4114_PWN |
@@ -667,7 +667,7 @@
  * hence the driver needs to sets up it properly.
  */
 
-static unsigned char juli_eeprom[] __devinitdata = {
+static unsigned char juli_eeprom[] = {
 	[ICE_EEP2_SYSCONF]     = 0x2b,	/* clock 512, mpu401, 1xADC, 1xDACs,
 					   SPDIF in */
 	[ICE_EEP2_ACLINK]      = 0x80,	/* I2S */
@@ -686,7 +686,7 @@
 };
 
 /* entry point */
-struct snd_ice1712_card_info snd_vt1724_juli_cards[] __devinitdata = {
+struct snd_ice1712_card_info snd_vt1724_juli_cards[] = {
 	{
 		.subvendor = VT1724_SUBDEVICE_JULI,
 		.name = "ESI Juli@",
diff --git a/sound/pci/ice1712/maya44.c b/sound/pci/ice1712/maya44.c
index 726fd4b..63aa39f 100644
--- a/sound/pci/ice1712/maya44.c
+++ b/sound/pci/ice1712/maya44.c
@@ -24,7 +24,6 @@
 
 #include <linux/init.h>
 #include <linux/slab.h>
-#include <linux/io.h>
 #include <sound/core.h>
 #include <sound/control.h>
 #include <sound/pcm.h>
@@ -358,7 +357,7 @@
 static int maya_rec_src_info(struct snd_kcontrol *kcontrol,
 			     struct snd_ctl_elem_info *uinfo)
 {
-	static char *texts[] = { "Line", "Mic" };
+	static const char * const texts[] = { "Line", "Mic" };
 
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
 	uinfo->count = 1;
@@ -407,7 +406,7 @@
 static int maya_pb_route_info(struct snd_kcontrol *kcontrol,
 			      struct snd_ctl_elem_info *uinfo)
 {
-	static char *texts[] = {
+	static const char * const texts[] = {
 		"PCM Out", /* 0 */
 		"Input 1", "Input 2", "Input 3", "Input 4"
 	};
@@ -455,7 +454,7 @@
  * controls to be added
  */
 
-static struct snd_kcontrol_new maya_controls[] __devinitdata = {
+static struct snd_kcontrol_new maya_controls[] = {
 	{
 		.name = "Crossmix Playback Volume",
 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
@@ -545,7 +544,7 @@
 	},
 };
 
-static int __devinit maya44_add_controls(struct snd_ice1712 *ice)
+static int maya44_add_controls(struct snd_ice1712 *ice)
 {
 	int err, i;
 
@@ -562,8 +561,8 @@
 /*
  * initialize a wm8776 chip
  */
-static void __devinit wm8776_init(struct snd_ice1712 *ice,
-				  struct snd_wm8776 *wm, unsigned int addr)
+static void wm8776_init(struct snd_ice1712 *ice,
+			struct snd_wm8776 *wm, unsigned int addr)
 {
 	static const unsigned short inits_wm8776[] = {
 		0x02, 0x100, /* R2: headphone L+R muted + update */
@@ -693,14 +692,14 @@
 /*
  * chip addresses on I2C bus
  */
-static unsigned char wm8776_addr[2] __devinitdata = {
+static unsigned char wm8776_addr[2] = {
 	0x34, 0x36, /* codec 0 & 1 */
 };
 
 /*
  * initialize the chip
  */
-static int __devinit maya44_init(struct snd_ice1712 *ice)
+static int maya44_init(struct snd_ice1712 *ice)
 {
 	int i;
 	struct snd_maya44 *chip;
@@ -743,7 +742,7 @@
  * hence the driver needs to sets up it properly.
  */
 
-static unsigned char maya44_eeprom[] __devinitdata = {
+static unsigned char maya44_eeprom[] = {
 	[ICE_EEP2_SYSCONF]     = 0x45,
 		/* clock xin1=49.152MHz, mpu401, 2 stereo ADCs+DACs */
 	[ICE_EEP2_ACLINK]      = 0x80,
@@ -765,7 +764,7 @@
 };
 
 /* entry point */
-struct snd_ice1712_card_info snd_vt1724_maya44_cards[] __devinitdata = {
+struct snd_ice1712_card_info snd_vt1724_maya44_cards[] = {
 	{
 		.subvendor = VT1724_SUBDEVICE_MAYA44,
 		.name = "ESI Maya44",
diff --git a/sound/pci/ice1712/phase.c b/sound/pci/ice1712/phase.c
index de29be8..0011e04 100644
--- a/sound/pci/ice1712/phase.c
+++ b/sound/pci/ice1712/phase.c
@@ -42,7 +42,6 @@
  *   Digital receiver: CS8414-CS (supported in this release)
  */
 
-#include <asm/io.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
@@ -103,13 +102,13 @@
 #define WM_VOL_MAX	(sizeof(wm_vol) - 1)
 #define WM_VOL_MUTE	0x8000
 
-static struct snd_akm4xxx akm_phase22 __devinitdata = {
+static struct snd_akm4xxx akm_phase22 = {
 	.type = SND_AK4524,
 	.num_dacs = 2,
 	.num_adcs = 2,
 };
 
-static struct snd_ak4xxx_private akm_phase22_priv __devinitdata = {
+static struct snd_ak4xxx_private akm_phase22_priv = {
 	.caddr =	2,
 	.cif =		1,
 	.data_mask =	1 << 4,
@@ -121,7 +120,7 @@
 	.mask_flags =	0,
 };
 
-static int __devinit phase22_init(struct snd_ice1712 *ice)
+static int phase22_init(struct snd_ice1712 *ice)
 {
 	struct snd_akm4xxx *ak;
 	int err;
@@ -158,7 +157,7 @@
 	return 0;
 }
 
-static int __devinit phase22_add_controls(struct snd_ice1712 *ice)
+static int phase22_add_controls(struct snd_ice1712 *ice)
 {
 	int err = 0;
 
@@ -172,7 +171,7 @@
 	return 0;
 }
 
-static unsigned char phase22_eeprom[] __devinitdata = {
+static unsigned char phase22_eeprom[] = {
 	[ICE_EEP2_SYSCONF]     = 0x28,  /* clock 512, mpu 401,
 					spdif-in/1xADC, 1xDACs */
 	[ICE_EEP2_ACLINK]      = 0x80,	/* I2S */
@@ -189,7 +188,7 @@
 	[ICE_EEP2_GPIO_STATE2] = 0x00,
 };
 
-static unsigned char phase28_eeprom[] __devinitdata = {
+static unsigned char phase28_eeprom[] = {
 	[ICE_EEP2_SYSCONF]     = 0x2b,  /* clock 512, mpu401,
 					spdif-in/1xADC, 4xDACs */
 	[ICE_EEP2_ACLINK]      = 0x80,	/* I2S */
@@ -379,7 +378,7 @@
 	return change;
 }
 
-static int __devinit phase28_init(struct snd_ice1712 *ice)
+static int phase28_init(struct snd_ice1712 *ice)
 {
 	static const unsigned short wm_inits_phase28[] = {
 		/* These come first to reduce init pop noise */
@@ -722,7 +721,7 @@
 static int phase28_oversampling_info(struct snd_kcontrol *k,
 					struct snd_ctl_elem_info *uinfo)
 {
-	static char *texts[2] = { "128x", "64x"	};
+	static const char * const texts[2] = { "128x", "64x"	};
 
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
 	uinfo->count = 1;
@@ -770,7 +769,7 @@
 static const DECLARE_TLV_DB_SCALE(db_scale_wm_dac, -12700, 100, 1);
 static const DECLARE_TLV_DB_SCALE(db_scale_wm_pcm, -6400, 50, 1);
 
-static struct snd_kcontrol_new phase28_dac_controls[] __devinitdata = {
+static struct snd_kcontrol_new phase28_dac_controls[] = {
 	{
 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 		.name = "Master Playback Switch",
@@ -885,7 +884,7 @@
 	}
 };
 
-static struct snd_kcontrol_new wm_controls[] __devinitdata = {
+static struct snd_kcontrol_new wm_controls[] = {
 	{
 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 		.name = "PCM Playback Switch",
@@ -919,7 +918,7 @@
 	}
 };
 
-static int __devinit phase28_add_controls(struct snd_ice1712 *ice)
+static int phase28_add_controls(struct snd_ice1712 *ice)
 {
 	unsigned int i, counts;
 	int err;
@@ -943,7 +942,7 @@
 	return 0;
 }
 
-struct snd_ice1712_card_info snd_vt1724_phase_cards[] __devinitdata = {
+struct snd_ice1712_card_info snd_vt1724_phase_cards[] = {
 	{
 		.subvendor = VT1724_SUBDEVICE_PHASE22,
 		.name = "Terratec PHASE 22",
diff --git a/sound/pci/ice1712/pontis.c b/sound/pci/ice1712/pontis.c
index 92c1160..5555eb4 100644
--- a/sound/pci/ice1712/pontis.c
+++ b/sound/pci/ice1712/pontis.c
@@ -21,7 +21,6 @@
  *
  */
 
-#include <asm/io.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
@@ -550,7 +549,7 @@
  * mixers
  */
 
-static struct snd_kcontrol_new pontis_controls[] __devinitdata = {
+static struct snd_kcontrol_new pontis_controls[] = {
 	{
 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 		.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
@@ -697,7 +696,7 @@
 }
 
 
-static int __devinit pontis_add_controls(struct snd_ice1712 *ice)
+static int pontis_add_controls(struct snd_ice1712 *ice)
 {
 	unsigned int i;
 	int err;
@@ -718,7 +717,7 @@
 /*
  * initialize the chip
  */
-static int __devinit pontis_init(struct snd_ice1712 *ice)
+static int pontis_init(struct snd_ice1712 *ice)
 {
 	static const unsigned short wm_inits[] = {
 		/* These come first to reduce init pop noise */
@@ -805,7 +804,7 @@
  * hence the driver needs to sets up it properly.
  */
 
-static unsigned char pontis_eeprom[] __devinitdata = {
+static unsigned char pontis_eeprom[] = {
 	[ICE_EEP2_SYSCONF]     = 0x08,	/* clock 256, mpu401, spdif-in/ADC, 1DAC */
 	[ICE_EEP2_ACLINK]      = 0x80,	/* I2S */
 	[ICE_EEP2_I2S]         = 0xf8,	/* vol, 96k, 24bit, 192k */
@@ -822,7 +821,7 @@
 };
 
 /* entry point */
-struct snd_ice1712_card_info snd_vt1720_pontis_cards[] __devinitdata = {
+struct snd_ice1712_card_info snd_vt1720_pontis_cards[] = {
 	{
 		.subvendor = VT1720_SUBDEVICE_PONTIS_MS300,
 		.name = "Pontis MS300",
diff --git a/sound/pci/ice1712/prodigy192.c b/sound/pci/ice1712/prodigy192.c
index e36ddb9..e610339 100644
--- a/sound/pci/ice1712/prodigy192.c
+++ b/sound/pci/ice1712/prodigy192.c
@@ -54,7 +54,6 @@
  *
  */      
 
-#include <asm/io.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
@@ -283,7 +282,7 @@
 static int stac9460_mic_sw_info(struct snd_kcontrol *kcontrol,
 	       			struct snd_ctl_elem_info *uinfo)
 {
-	static char *texts[2] = { "Line In", "Mic" };
+	static const char * const texts[2] = { "Line In", "Mic" };
 
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
 	uinfo->count = 1;
@@ -369,7 +368,7 @@
  * mixers
  */
 
-static struct snd_kcontrol_new stac_controls[] __devinitdata = {
+static struct snd_kcontrol_new stac_controls[] = {
 	{
 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 		.name = "Master Playback Switch",
@@ -562,7 +561,7 @@
 static int ak4114_input_sw_info(struct snd_kcontrol *kcontrol,
 	       			struct snd_ctl_elem_info *uinfo)
 {
-	static char *texts[2] = { "Toslink", "Coax" };
+	static const char * const texts[2] = { "Toslink", "Coax" };
 
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
 	uinfo->count = 1;
@@ -607,7 +606,7 @@
 }
 
 
-static struct snd_kcontrol_new ak4114_controls[] __devinitdata = {
+static struct snd_kcontrol_new ak4114_controls[] = {
 	{
 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 		.name = "MIODIO IEC958 Capture Input",
@@ -672,7 +671,7 @@
 }
 
 
-static int __devinit prodigy192_add_controls(struct snd_ice1712 *ice)
+static int prodigy192_add_controls(struct snd_ice1712 *ice)
 {
 	struct prodigy192_spec *spec = ice->spec;
 	unsigned int i;
@@ -728,7 +727,7 @@
 /*
  * initialize the chip
  */
-static int __devinit prodigy192_init(struct snd_ice1712 *ice)
+static int prodigy192_init(struct snd_ice1712 *ice)
 {
 	static const unsigned short stac_inits_prodigy[] = {
 		STAC946X_RESET, 0,
@@ -784,7 +783,7 @@
  * hence the driver needs to sets up it properly.
  */
 
-static unsigned char prodigy71_eeprom[] __devinitdata = {
+static unsigned char prodigy71_eeprom[] = {
 	[ICE_EEP2_SYSCONF]     = 0x6a,	/* 49MHz crystal, mpu401,
 					 * spdif-in+ 1 stereo ADC,
 					 * 3 stereo DACs
@@ -808,7 +807,7 @@
 
 
 /* entry point */
-struct snd_ice1712_card_info snd_vt1724_prodigy192_cards[] __devinitdata = {
+struct snd_ice1712_card_info snd_vt1724_prodigy192_cards[] = {
 	{
 		.subvendor = VT1724_SUBDEVICE_PRODIGY192VE,
 		.name = "Audiotrak Prodigy 192",
diff --git a/sound/pci/ice1712/prodigy_hifi.c b/sound/pci/ice1712/prodigy_hifi.c
index 7bf093c..2261d1e 100644
--- a/sound/pci/ice1712/prodigy_hifi.c
+++ b/sound/pci/ice1712/prodigy_hifi.c
@@ -25,7 +25,6 @@
  */
 
 
-#include <asm/io.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
@@ -299,7 +298,7 @@
 static const DECLARE_TLV_DB_SCALE(db_scale_wm_dac, -12700, 100, 1);
 static const DECLARE_TLV_DB_LINEAR(ak4396_db_scale, TLV_DB_GAIN_MUTE, 0);
 
-static struct snd_kcontrol_new prodigy_hd2_controls[] __devinitdata = {
+static struct snd_kcontrol_new prodigy_hd2_controls[] = {
     {
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
@@ -782,7 +781,7 @@
  * mixers
  */
 
-static struct snd_kcontrol_new prodigy_hifi_controls[] __devinitdata = {
+static struct snd_kcontrol_new prodigy_hifi_controls[] = {
 	{
 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 		.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
@@ -939,7 +938,7 @@
 	}
 }
 
-static int __devinit prodigy_hifi_add_controls(struct snd_ice1712 *ice)
+static int prodigy_hifi_add_controls(struct snd_ice1712 *ice)
 {
 	unsigned int i;
 	int err;
@@ -956,7 +955,7 @@
 	return 0;
 }
 
-static int __devinit prodigy_hd2_add_controls(struct snd_ice1712 *ice)
+static int prodigy_hd2_add_controls(struct snd_ice1712 *ice)
 {
 	unsigned int i;
 	int err;
@@ -977,7 +976,7 @@
 /*
  * initialize the chip
  */
-static int __devinit prodigy_hifi_init(struct snd_ice1712 *ice)
+static int prodigy_hifi_init(struct snd_ice1712 *ice)
 {
 	static unsigned short wm_inits[] = {
 		/* These come first to reduce init pop noise */
@@ -1115,7 +1114,7 @@
 }
 #endif
 
-static int __devinit prodigy_hd2_init(struct snd_ice1712 *ice)
+static int prodigy_hd2_init(struct snd_ice1712 *ice)
 {
 	struct prodigy_hifi_spec *spec;
 
@@ -1152,7 +1151,7 @@
 }
 
 
-static unsigned char prodigy71hifi_eeprom[] __devinitdata = {
+static unsigned char prodigy71hifi_eeprom[] = {
 	0x4b,   /* SYSCONF: clock 512, spdif-in/ADC, 4DACs */
 	0x80,   /* ACLINK: I2S */
 	0xfc,   /* I2S: vol, 96k, 24bit, 192k */
@@ -1168,7 +1167,7 @@
 	0x00,   /* GPIO_STATE2 */
 };
 
-static unsigned char prodigyhd2_eeprom[] __devinitdata = {
+static unsigned char prodigyhd2_eeprom[] = {
 	0x4b,   /* SYSCONF: clock 512, spdif-in/ADC, 4DACs */
 	0x80,   /* ACLINK: I2S */
 	0xfc,   /* I2S: vol, 96k, 24bit, 192k */
@@ -1184,7 +1183,7 @@
 	0x00,   /* GPIO_STATE2 */
 };
 
-static unsigned char fortissimo4_eeprom[] __devinitdata = {
+static unsigned char fortissimo4_eeprom[] = {
 	0x43,   /* SYSCONF: clock 512, ADC, 4DACs */	
 	0x80,   /* ACLINK: I2S */
 	0xfc,   /* I2S: vol, 96k, 24bit, 192k */
@@ -1201,7 +1200,7 @@
 };
 
 /* entry point */
-struct snd_ice1712_card_info snd_vt1724_prodigy_hifi_cards[] __devinitdata = {
+struct snd_ice1712_card_info snd_vt1724_prodigy_hifi_cards[] = {
 	{
 		.subvendor = VT1724_SUBDEVICE_PRODIGY_HIFI,
 		.name = "Audiotrak Prodigy 7.1 HiFi",
diff --git a/sound/pci/ice1712/psc724.c b/sound/pci/ice1712/psc724.c
new file mode 100644
index 0000000..302ac6d
--- /dev/null
+++ b/sound/pci/ice1712/psc724.c
@@ -0,0 +1,464 @@
+/*
+ *   ALSA driver for ICEnsemble VT1724 (Envy24HT)
+ *
+ *   Lowlevel functions for Philips PSC724 Ultimate Edge
+ *
+ *	Copyright (c) 2012 Ondrej Zary <linux@rainbow-software.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., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ *
+ */
+
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <sound/core.h>
+
+#include "ice1712.h"
+#include "envy24ht.h"
+#include "psc724.h"
+#include "wm8766.h"
+#include "wm8776.h"
+
+struct psc724_spec {
+	struct snd_wm8766 wm8766;
+	struct snd_wm8776 wm8776;
+	bool mute_all, jack_detect;
+	struct snd_ice1712 *ice;
+	struct delayed_work hp_work;
+	bool hp_connected;
+};
+
+/****************************************************************************/
+/*  PHILIPS PSC724 ULTIMATE EDGE                                            */
+/****************************************************************************/
+/*
+ *  VT1722 (Envy24GT) - 6 outputs, 4 inputs (only 2 used), 24-bit/96kHz
+ *
+ *  system configuration ICE_EEP2_SYSCONF=0x42
+ *    XIN1 49.152MHz
+ *    no MPU401
+ *    one stereo ADC, no S/PDIF receiver
+ *    three stereo DACs (FRONT, REAR, CENTER+LFE)
+ *
+ *  AC-Link configuration ICE_EEP2_ACLINK=0x80
+ *    use I2S, not AC97
+ *
+ *  I2S converters feature ICE_EEP2_I2S=0x30
+ *    I2S codec has no volume/mute control feature (bug!)
+ *    I2S codec does not support 96KHz or 192KHz (bug!)
+ *    I2S codec 24bits
+ *
+ *  S/PDIF configuration ICE_EEP2_SPDIF=0xc1
+ *    Enable integrated S/PDIF transmitter
+ *    internal S/PDIF out implemented
+ *    No S/PDIF input
+ *    External S/PDIF out implemented
+ *
+ *
+ * ** connected chips **
+ *
+ *  WM8776
+ *     2-channel DAC used for main output and stereo ADC (with 10-channel MUX)
+ *     AIN1: LINE IN, AIN2: CD/VIDEO, AIN3: AUX, AIN4: Front MIC, AIN5: Rear MIC
+ *     Controlled by I2C using VT1722 I2C interface:
+ *          MODE (pin16) -- GND
+ *          CE   (pin17) -- GND  I2C mode (address=0x34)
+ *          DI   (pin18) -- SDA  (VT1722 pin70)
+ *          CL   (pin19) -- SCLK (VT1722 pin71)
+ *
+ *  WM8766
+ *      6-channel DAC used for rear & center/LFE outputs (only 4 channels used)
+ *      Controlled by SPI using VT1722 GPIO pins:
+ *          MODE   (pin 1) -- GPIO19 (VT1722 pin99)
+ *          ML/I2S (pin11) -- GPIO18 (VT1722 pin98)
+ *          MC/IWL (pin12) -- GPIO17 (VT1722 pin97)
+ *          MD/DM  (pin13) -- GPIO16 (VT1722 pin96)
+ *          MUTE   (pin14) -- GPIO20 (VT1722 pin101)
+ *
+ *  GPIO14 is used as input for headphone jack detection (1 = connected)
+ *  GPIO22 is used as MUTE ALL output, grounding all 6 channels
+ *
+ * ** output pins and device names **
+ *
+ *   5.1ch name -- output connector color -- device (-D option)
+ *
+ *      FRONT 2ch                  -- green  -- plughw:0,0
+ *      CENTER(Lch) SUBWOOFER(Rch) -- orange -- plughw:0,2,0
+ *      REAR 2ch                   -- black  -- plughw:0,2,1
+ */
+
+/* codec access low-level functions */
+
+#define GPIO_HP_JACK	(1 << 14)
+#define GPIO_MUTE_SUR	(1 << 20)
+#define GPIO_MUTE_ALL	(1 << 22)
+
+#define JACK_INTERVAL	1000
+
+#define PSC724_SPI_DELAY 1
+
+#define PSC724_SPI_DATA	(1 << 16)
+#define PSC724_SPI_CLK	(1 << 17)
+#define PSC724_SPI_LOAD	(1 << 18)
+#define PSC724_SPI_MASK	(PSC724_SPI_DATA | PSC724_SPI_CLK | PSC724_SPI_LOAD)
+
+static void psc724_wm8766_write(struct snd_wm8766 *wm, u16 addr, u16 data)
+{
+	struct psc724_spec *spec = container_of(wm, struct psc724_spec, wm8766);
+	struct snd_ice1712 *ice = spec->ice;
+	u32 st, bits;
+	int i;
+
+	snd_ice1712_save_gpio_status(ice);
+
+	st = ((addr & 0x7f) << 9) | (data & 0x1ff);
+	snd_ice1712_gpio_set_dir(ice, ice->gpio.direction | PSC724_SPI_MASK);
+	snd_ice1712_gpio_set_mask(ice, ice->gpio.write_mask & ~PSC724_SPI_MASK);
+	bits = snd_ice1712_gpio_read(ice) & ~PSC724_SPI_MASK;
+	snd_ice1712_gpio_write(ice, bits);
+
+	for (i = 0; i < 16; i++) {
+		udelay(PSC724_SPI_DELAY);
+		bits &= ~PSC724_SPI_CLK;
+		/* MSB first */
+		st <<= 1;
+		if (st & 0x10000)
+			bits |= PSC724_SPI_DATA;
+		else
+			bits &= ~PSC724_SPI_DATA;
+		snd_ice1712_gpio_write(ice, bits);
+		/* CLOCK high */
+		udelay(PSC724_SPI_DELAY);
+		bits |= PSC724_SPI_CLK;
+		snd_ice1712_gpio_write(ice, bits);
+	}
+	/* LOAD high */
+	udelay(PSC724_SPI_DELAY);
+	bits |= PSC724_SPI_LOAD;
+	snd_ice1712_gpio_write(ice, bits);
+	/* LOAD low, DATA and CLOCK high */
+	udelay(PSC724_SPI_DELAY);
+	bits |= (PSC724_SPI_DATA | PSC724_SPI_CLK);
+	snd_ice1712_gpio_write(ice, bits);
+
+	snd_ice1712_restore_gpio_status(ice);
+}
+
+static void psc724_wm8776_write(struct snd_wm8776 *wm, u8 addr, u8 data)
+{
+	struct psc724_spec *spec = container_of(wm, struct psc724_spec, wm8776);
+
+	snd_vt1724_write_i2c(spec->ice, 0x34, addr, data);
+}
+
+/* mute all */
+
+static void psc724_set_master_switch(struct snd_ice1712 *ice, bool on)
+{
+	unsigned int bits = snd_ice1712_gpio_read(ice);
+	struct psc724_spec *spec = ice->spec;
+
+	spec->mute_all = !on;
+	if (on)
+		bits &= ~(GPIO_MUTE_ALL | GPIO_MUTE_SUR);
+	else
+		bits |= GPIO_MUTE_ALL | GPIO_MUTE_SUR;
+	snd_ice1712_gpio_write(ice, bits);
+}
+
+static bool psc724_get_master_switch(struct snd_ice1712 *ice)
+{
+	struct psc724_spec *spec = ice->spec;
+
+	return !spec->mute_all;
+}
+
+/* jack detection */
+
+static void psc724_set_jack_state(struct snd_ice1712 *ice, bool hp_connected)
+{
+	struct psc724_spec *spec = ice->spec;
+	struct snd_ctl_elem_id elem_id;
+	struct snd_kcontrol *kctl;
+	u16 power = spec->wm8776.regs[WM8776_REG_PWRDOWN] & ~WM8776_PWR_HPPD;
+
+	psc724_set_master_switch(ice, !hp_connected);
+	if (!hp_connected)
+		power |= WM8776_PWR_HPPD;
+	snd_wm8776_set_power(&spec->wm8776, power);
+	spec->hp_connected = hp_connected;
+	/* notify about master speaker mute change */
+	memset(&elem_id, 0, sizeof(elem_id));
+	elem_id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
+	strncpy(elem_id.name, "Master Speakers Playback Switch",
+						sizeof(elem_id.name));
+	kctl = snd_ctl_find_id(ice->card, &elem_id);
+	snd_ctl_notify(ice->card, SNDRV_CTL_EVENT_MASK_VALUE, &kctl->id);
+	/* and headphone mute change */
+	strncpy(elem_id.name, spec->wm8776.ctl[WM8776_CTL_HP_SW].name,
+						sizeof(elem_id.name));
+	kctl = snd_ctl_find_id(ice->card, &elem_id);
+	snd_ctl_notify(ice->card, SNDRV_CTL_EVENT_MASK_VALUE, &kctl->id);
+}
+
+static void psc724_update_hp_jack_state(struct work_struct *work)
+{
+	struct psc724_spec *spec = container_of(work, struct psc724_spec,
+						hp_work.work);
+	struct snd_ice1712 *ice = spec->ice;
+	bool hp_connected = snd_ice1712_gpio_read(ice) & GPIO_HP_JACK;
+
+	schedule_delayed_work(&spec->hp_work, msecs_to_jiffies(JACK_INTERVAL));
+	if (hp_connected == spec->hp_connected)
+		return;
+	psc724_set_jack_state(ice, hp_connected);
+}
+
+static void psc724_set_jack_detection(struct snd_ice1712 *ice, bool on)
+{
+	struct psc724_spec *spec = ice->spec;
+
+	if (spec->jack_detect == on)
+		return;
+
+	spec->jack_detect = on;
+	if (on) {
+		bool hp_connected = snd_ice1712_gpio_read(ice) & GPIO_HP_JACK;
+		psc724_set_jack_state(ice, hp_connected);
+		schedule_delayed_work(&spec->hp_work,
+					msecs_to_jiffies(JACK_INTERVAL));
+	} else
+		cancel_delayed_work_sync(&spec->hp_work);
+}
+
+static bool psc724_get_jack_detection(struct snd_ice1712 *ice)
+{
+	struct psc724_spec *spec = ice->spec;
+
+	return spec->jack_detect;
+}
+
+/* mixer controls */
+
+struct psc724_control {
+	const char *name;
+	void (*set)(struct snd_ice1712 *ice, bool on);
+	bool (*get)(struct snd_ice1712 *ice);
+};
+
+static const struct psc724_control psc724_cont[] = {
+	{
+		.name = "Master Speakers Playback Switch",
+		.set = psc724_set_master_switch,
+		.get = psc724_get_master_switch,
+	},
+	{
+		.name = "Headphone Jack Detection Playback Switch",
+		.set = psc724_set_jack_detection,
+		.get = psc724_get_jack_detection,
+	},
+};
+
+static int psc724_ctl_get(struct snd_kcontrol *kcontrol,
+				  struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
+	int n = kcontrol->private_value;
+
+	ucontrol->value.integer.value[0] = psc724_cont[n].get(ice);
+
+	return 0;
+}
+
+static int psc724_ctl_put(struct snd_kcontrol *kcontrol,
+				  struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
+	int n = kcontrol->private_value;
+
+	psc724_cont[n].set(ice, ucontrol->value.integer.value[0]);
+
+	return 0;
+}
+
+static const char *front_volume	= "Front Playback Volume";
+static const char *front_switch	= "Front Playback Switch";
+static const char *front_zc	= "Front Zero Cross Detect Playback Switch";
+static const char *front_izd	= "Front Infinite Zero Detect Playback Switch";
+static const char *front_phase	= "Front Phase Invert Playback Switch";
+static const char *front_deemph	= "Front Deemphasis Playback Switch";
+static const char *ain1_switch	= "Line Capture Switch";
+static const char *ain2_switch	= "CD Capture Switch";
+static const char *ain3_switch	= "AUX Capture Switch";
+static const char *ain4_switch	= "Front Mic Capture Switch";
+static const char *ain5_switch	= "Rear Mic Capture Switch";
+static const char *rear_volume	= "Surround Playback Volume";
+static const char *clfe_volume	= "CLFE Playback Volume";
+static const char *rear_switch	= "Surround Playback Switch";
+static const char *clfe_switch	= "CLFE Playback Switch";
+static const char *rear_phase	= "Surround Phase Invert Playback Switch";
+static const char *clfe_phase	= "CLFE Phase Invert Playback Switch";
+static const char *rear_deemph	= "Surround Deemphasis Playback Switch";
+static const char *clfe_deemph	= "CLFE Deemphasis Playback Switch";
+static const char *rear_clfe_izd = "Rear Infinite Zero Detect Playback Switch";
+static const char *rear_clfe_zc	= "Rear Zero Cross Detect Playback Switch";
+
+static int psc724_add_controls(struct snd_ice1712 *ice)
+{
+	struct snd_kcontrol_new cont;
+	struct snd_kcontrol *ctl;
+	int err, i;
+	struct psc724_spec *spec = ice->spec;
+
+	spec->wm8776.ctl[WM8776_CTL_DAC_VOL].name = front_volume;
+	spec->wm8776.ctl[WM8776_CTL_DAC_SW].name = front_switch;
+	spec->wm8776.ctl[WM8776_CTL_DAC_ZC_SW].name = front_zc;
+	spec->wm8776.ctl[WM8776_CTL_AUX_SW].name = NULL;
+	spec->wm8776.ctl[WM8776_CTL_DAC_IZD_SW].name = front_izd;
+	spec->wm8776.ctl[WM8776_CTL_PHASE_SW].name = front_phase;
+	spec->wm8776.ctl[WM8776_CTL_DEEMPH_SW].name = front_deemph;
+	spec->wm8776.ctl[WM8776_CTL_INPUT1_SW].name = ain1_switch;
+	spec->wm8776.ctl[WM8776_CTL_INPUT2_SW].name = ain2_switch;
+	spec->wm8776.ctl[WM8776_CTL_INPUT3_SW].name = ain3_switch;
+	spec->wm8776.ctl[WM8776_CTL_INPUT4_SW].name = ain4_switch;
+	spec->wm8776.ctl[WM8776_CTL_INPUT5_SW].name = ain5_switch;
+	snd_wm8776_build_controls(&spec->wm8776);
+	spec->wm8766.ctl[WM8766_CTL_CH1_VOL].name = rear_volume;
+	spec->wm8766.ctl[WM8766_CTL_CH2_VOL].name = clfe_volume;
+	spec->wm8766.ctl[WM8766_CTL_CH3_VOL].name = NULL;
+	spec->wm8766.ctl[WM8766_CTL_CH1_SW].name = rear_switch;
+	spec->wm8766.ctl[WM8766_CTL_CH2_SW].name = clfe_switch;
+	spec->wm8766.ctl[WM8766_CTL_CH3_SW].name = NULL;
+	spec->wm8766.ctl[WM8766_CTL_PHASE1_SW].name = rear_phase;
+	spec->wm8766.ctl[WM8766_CTL_PHASE2_SW].name = clfe_phase;
+	spec->wm8766.ctl[WM8766_CTL_PHASE3_SW].name = NULL;
+	spec->wm8766.ctl[WM8766_CTL_DEEMPH1_SW].name = rear_deemph;
+	spec->wm8766.ctl[WM8766_CTL_DEEMPH2_SW].name = clfe_deemph;
+	spec->wm8766.ctl[WM8766_CTL_DEEMPH3_SW].name = NULL;
+	spec->wm8766.ctl[WM8766_CTL_IZD_SW].name = rear_clfe_izd;
+	spec->wm8766.ctl[WM8766_CTL_ZC_SW].name = rear_clfe_zc;
+	snd_wm8766_build_controls(&spec->wm8766);
+
+	memset(&cont, 0, sizeof(cont));
+	cont.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
+	for (i = 0; i < ARRAY_SIZE(psc724_cont); i++) {
+		cont.private_value = i;
+		cont.name = psc724_cont[i].name;
+		cont.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
+		cont.info = snd_ctl_boolean_mono_info;
+		cont.get = psc724_ctl_get;
+		cont.put = psc724_ctl_put;
+		ctl = snd_ctl_new1(&cont, ice);
+		if (!ctl)
+			return -ENOMEM;
+		err = snd_ctl_add(ice->card, ctl);
+		if (err < 0)
+			return err;
+	}
+
+	return 0;
+}
+
+static void psc724_set_pro_rate(struct snd_ice1712 *ice, unsigned int rate)
+{
+	struct psc724_spec *spec = ice->spec;
+	/* restore codec volume settings after rate change (PMCLK stop) */
+	snd_wm8776_volume_restore(&spec->wm8776);
+	snd_wm8766_volume_restore(&spec->wm8766);
+}
+
+/* power management */
+
+#ifdef CONFIG_PM_SLEEP
+static int psc724_resume(struct snd_ice1712 *ice)
+{
+	struct psc724_spec *spec = ice->spec;
+
+	snd_wm8776_resume(&spec->wm8776);
+	snd_wm8766_resume(&spec->wm8766);
+
+	return 0;
+}
+#endif
+
+/* init */
+
+static int psc724_init(struct snd_ice1712 *ice)
+{
+	struct psc724_spec *spec;
+
+	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
+	if (!spec)
+		return -ENOMEM;
+	ice->spec = spec;
+	spec->ice = ice;
+
+	ice->num_total_dacs = 6;
+	ice->num_total_adcs = 2;
+	spec->wm8776.ops.write = psc724_wm8776_write;
+	spec->wm8776.card = ice->card;
+	snd_wm8776_init(&spec->wm8776);
+	spec->wm8766.ops.write = psc724_wm8766_write;
+	spec->wm8766.card = ice->card;
+#ifdef CONFIG_PM_SLEEP
+	ice->pm_resume = psc724_resume;
+	ice->pm_suspend_enabled = 1;
+#endif
+	snd_wm8766_init(&spec->wm8766);
+	snd_wm8766_set_if(&spec->wm8766,
+			WM8766_IF_FMT_I2S | WM8766_IF_IWL_24BIT);
+	ice->gpio.set_pro_rate = psc724_set_pro_rate;
+	INIT_DELAYED_WORK(&spec->hp_work, psc724_update_hp_jack_state);
+	psc724_set_jack_detection(ice, true);
+	return 0;
+}
+
+static void psc724_exit(struct snd_ice1712 *ice)
+{
+	struct psc724_spec *spec = ice->spec;
+
+	cancel_delayed_work_sync(&spec->hp_work);
+}
+
+/* PSC724 has buggy EEPROM (no 96&192kHz, all FFh GPIOs), so override it here */
+static unsigned char psc724_eeprom[] = {
+	[ICE_EEP2_SYSCONF]	= 0x42,	/* 49.152MHz, 1 ADC, 3 DACs */
+	[ICE_EEP2_ACLINK]	= 0x80,	/* I2S */
+	[ICE_EEP2_I2S]		= 0xf0,	/* I2S volume, 96kHz, 24bit */
+	[ICE_EEP2_SPDIF]	= 0xc1,	/* spdif out-en, out-int, no input */
+	/* GPIO outputs */
+	[ICE_EEP2_GPIO_DIR2]	= 0x5f, /* MUTE_ALL,WM8766 MUTE/MODE/ML/MC/MD */
+	/* GPIO write enable */
+	[ICE_EEP2_GPIO_MASK]	= 0xff, /* read-only */
+	[ICE_EEP2_GPIO_MASK1]	= 0xff, /* read-only */
+	[ICE_EEP2_GPIO_MASK2]	= 0xa0, /* MUTE_ALL,WM8766 MUTE/MODE/ML/MC/MD */
+	/* GPIO initial state */
+	[ICE_EEP2_GPIO_STATE2]	= 0x20,	/* unmuted, all WM8766 pins low */
+};
+
+struct snd_ice1712_card_info snd_vt1724_psc724_cards[] = {
+	{
+		.subvendor = VT1724_SUBDEVICE_PSC724,
+		.name = "Philips PSC724 Ultimate Edge",
+		.model = "psc724",
+		.chip_init = psc724_init,
+		.chip_exit = psc724_exit,
+		.build_controls = psc724_add_controls,
+		.eeprom_size = sizeof(psc724_eeprom),
+		.eeprom_data = psc724_eeprom,
+	},
+	{} /*terminator*/
+};
diff --git a/sound/pci/ice1712/psc724.h b/sound/pci/ice1712/psc724.h
new file mode 100644
index 0000000..858e5fd
--- /dev/null
+++ b/sound/pci/ice1712/psc724.h
@@ -0,0 +1,13 @@
+#ifndef __SOUND_PSC724_H
+#define __SOUND_PSC724_H
+
+/* ID */
+#define PSC724_DEVICE_DESC	\
+		"{Philips,PSC724 Ultimate Edge},"
+
+#define VT1724_SUBDEVICE_PSC724		0xab170619
+
+/* entry struct */
+extern struct snd_ice1712_card_info snd_vt1724_psc724_cards[];
+
+#endif /* __SOUND_PSC724_H */
diff --git a/sound/pci/ice1712/quartet.c b/sound/pci/ice1712/quartet.c
index 1948632..975e035 100644
--- a/sound/pci/ice1712/quartet.c
+++ b/sound/pci/ice1712/quartet.c
@@ -22,7 +22,6 @@
  *
  */
 
-#include <asm/io.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
@@ -47,7 +46,7 @@
 	unsigned int bit;
 	void (*set_register)(struct snd_ice1712 *ice, unsigned int val);
 	unsigned int (*get_register)(struct snd_ice1712 *ice);
-	unsigned char *texts[2];
+	unsigned char * const texts[2];
 };
 
 enum {
@@ -63,7 +62,7 @@
 	OUT34_MON12,
 };
 
-static char *ext_clock_names[3] = {"IEC958 In", "Word Clock 1xFS",
+static const char * const ext_clock_names[3] = {"IEC958 In", "Word Clock 1xFS",
 	"Word Clock 256xFS"};
 
 /* chip address on I2C bus */
@@ -387,7 +386,7 @@
 	AK_CONTROL(PCM_34_CAPTURE_VOLUME, 2),
 };
 
-static struct snd_akm4xxx akm_qtet_dac __devinitdata = {
+static struct snd_akm4xxx akm_qtet_dac = {
 	.type = SND_AK4620,
 	.num_dacs = 4,	/* DAC1 - Output 12
 	*/
@@ -551,7 +550,8 @@
 static int qtet_ain12_enum_info(struct snd_kcontrol *kcontrol,
 		struct snd_ctl_elem_info *uinfo)
 {
-	static char *texts[3] = {"Line In 1/2", "Mic", "Mic + Low-cut"};
+	static const char * const texts[3] =
+		{"Line In 1/2", "Mic", "Mic + Low-cut"};
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
 	uinfo->count = 1;
 	uinfo->value.enumerated.items = ARRAY_SIZE(texts);
@@ -758,7 +758,7 @@
 	.put = qtet_sw_put,\
 	.private_value = xpriv }
 
-static struct snd_kcontrol_new qtet_controls[] __devinitdata = {
+static struct snd_kcontrol_new qtet_controls[] = {
 	{
 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 		.name = "Master Playback Switch",
@@ -795,17 +795,17 @@
 	QTET_CONTROL("Output 3/4 to Monitor 1/2", sw, OUT34_MON12),
 };
 
-static char *slave_vols[] __devinitdata = {
+static char *slave_vols[] = {
 	PCM_12_PLAYBACK_VOLUME,
 	PCM_34_PLAYBACK_VOLUME,
 	NULL
 };
 
-static __devinitdata
+static
 DECLARE_TLV_DB_SCALE(qtet_master_db_scale, -6350, 50, 1);
 
-static struct snd_kcontrol __devinit *ctl_find(struct snd_card *card,
-		const char *name)
+static struct snd_kcontrol *ctl_find(struct snd_card *card,
+				     const char *name)
 {
 	struct snd_ctl_elem_id sid;
 	memset(&sid, 0, sizeof(sid));
@@ -815,8 +815,8 @@
 	return snd_ctl_find_id(card, &sid);
 }
 
-static void __devinit add_slaves(struct snd_card *card,
-		struct snd_kcontrol *master, char **list)
+static void add_slaves(struct snd_card *card,
+		       struct snd_kcontrol *master, char * const *list)
 {
 	for (; *list; list++) {
 		struct snd_kcontrol *slave = ctl_find(card, *list);
@@ -825,7 +825,7 @@
 	}
 }
 
-static int __devinit qtet_add_controls(struct snd_ice1712 *ice)
+static int qtet_add_controls(struct snd_ice1712 *ice)
 {
 	struct qtet_spec *spec = ice->spec;
 	int err, i;
@@ -1007,7 +1007,7 @@
 /*
  * initialize the chip
  */
-static int __devinit qtet_init(struct snd_ice1712 *ice)
+static int qtet_init(struct snd_ice1712 *ice)
 {
 	static const unsigned char ak4113_init_vals[] = {
 		/* AK4113_REG_PWRDN */	AK4113_RST | AK4113_PWN |
@@ -1095,7 +1095,7 @@
 	return 0;
 }
 
-static unsigned char qtet_eeprom[] __devinitdata = {
+static unsigned char qtet_eeprom[] = {
 	[ICE_EEP2_SYSCONF]     = 0x28,	/* clock 256(24MHz), mpu401, 1xADC,
 					   1xDACs, SPDIF in */
 	[ICE_EEP2_ACLINK]      = 0x80,	/* I2S */
@@ -1116,7 +1116,7 @@
 };
 
 /* entry point */
-struct snd_ice1712_card_info snd_vt1724_qtet_cards[] __devinitdata = {
+struct snd_ice1712_card_info snd_vt1724_qtet_cards[] = {
 	{
 		.subvendor = VT1724_SUBDEVICE_QTET,
 		.name = "Infrasonic Quartet",
diff --git a/sound/pci/ice1712/revo.c b/sound/pci/ice1712/revo.c
index b508bb3..7641080 100644
--- a/sound/pci/ice1712/revo.c
+++ b/sound/pci/ice1712/revo.c
@@ -21,7 +21,6 @@
  *
  */      
 
-#include <asm/io.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
@@ -235,7 +234,7 @@
 	},
 };
 
-static struct snd_akm4xxx akm_revo_front __devinitdata = {
+static struct snd_akm4xxx akm_revo_front = {
 	.type = SND_AK4381,
 	.num_dacs = 2,
 	.ops = {
@@ -244,7 +243,7 @@
 	.dac_info = revo71_front,
 };
 
-static struct snd_ak4xxx_private akm_revo_front_priv __devinitdata = {
+static struct snd_ak4xxx_private akm_revo_front_priv = {
 	.caddr = 1,
 	.cif = 0,
 	.data_mask = VT1724_REVO_CDOUT,
@@ -256,7 +255,7 @@
 	.mask_flags = 0,
 };
 
-static struct snd_akm4xxx akm_revo_surround __devinitdata = {
+static struct snd_akm4xxx akm_revo_surround = {
 	.type = SND_AK4355,
 	.idx_offset = 1,
 	.num_dacs = 6,
@@ -266,7 +265,7 @@
 	.dac_info = revo71_surround,
 };
 
-static struct snd_ak4xxx_private akm_revo_surround_priv __devinitdata = {
+static struct snd_ak4xxx_private akm_revo_surround_priv = {
 	.caddr = 3,
 	.cif = 0,
 	.data_mask = VT1724_REVO_CDOUT,
@@ -278,7 +277,7 @@
 	.mask_flags = 0,
 };
 
-static struct snd_akm4xxx akm_revo51 __devinitdata = {
+static struct snd_akm4xxx akm_revo51 = {
 	.type = SND_AK4358,
 	.num_dacs = 8,
 	.ops = {
@@ -287,7 +286,7 @@
 	.dac_info = revo51_dac,
 };
 
-static struct snd_ak4xxx_private akm_revo51_priv __devinitdata = {
+static struct snd_ak4xxx_private akm_revo51_priv = {
 	.caddr = 2,
 	.cif = 0,
 	.data_mask = VT1724_REVO_CDOUT,
@@ -299,13 +298,13 @@
 	.mask_flags = 0,
 };
 
-static struct snd_akm4xxx akm_revo51_adc __devinitdata = {
+static struct snd_akm4xxx akm_revo51_adc = {
 	.type = SND_AK5365,
 	.num_adcs = 2,
 	.adc_info = revo51_adc,
 };
 
-static struct snd_ak4xxx_private akm_revo51_adc_priv __devinitdata = {
+static struct snd_ak4xxx_private akm_revo51_adc_priv = {
 	.caddr = 2,
 	.cif = 0,
 	.data_mask = VT1724_REVO_CDOUT,
@@ -346,7 +345,7 @@
 	AK_DAC("PCM Playback Volume", 2)
 };
 
-static struct snd_akm4xxx akm_ap192 __devinitdata = {
+static struct snd_akm4xxx akm_ap192 = {
 	.type = SND_AK4358,
 	.num_dacs = 2,
 	.ops = {
@@ -355,7 +354,7 @@
 	.dac_info = ap192_dac,
 };
 
-static struct snd_ak4xxx_private akm_ap192_priv __devinitdata = {
+static struct snd_ak4xxx_private akm_ap192_priv = {
 	.caddr = 2,
 	.cif = 0,
 	.data_mask = VT1724_REVO_CDOUT,
@@ -468,7 +467,7 @@
 	return data;
 }
 
-static int __devinit ap192_ak4114_init(struct snd_ice1712 *ice)
+static int ap192_ak4114_init(struct snd_ice1712 *ice)
 {
 	static const unsigned char ak4114_init_vals[] = {
 		AK4114_RST | AK4114_PWN | AK4114_OCKS0 | AK4114_OCKS1,
@@ -496,7 +495,7 @@
 	return 0; /* error ignored; it's no fatal error */
 }
 
-static int __devinit revo_init(struct snd_ice1712 *ice)
+static int revo_init(struct snd_ice1712 *ice)
 {
 	struct snd_akm4xxx *ak;
 	int err;
@@ -574,7 +573,7 @@
 }
 
 
-static int __devinit revo_add_controls(struct snd_ice1712 *ice)
+static int revo_add_controls(struct snd_ice1712 *ice)
 {
 	struct revo51_spec *spec;
 	int err;
@@ -607,7 +606,7 @@
 }
 
 /* entry point */
-struct snd_ice1712_card_info snd_vt1724_revo_cards[] __devinitdata = {
+struct snd_ice1712_card_info snd_vt1724_revo_cards[] = {
 	{
 		.subvendor = VT1724_SUBDEVICE_REVOLUTION71,
 		.name = "M Audio Revolution-7.1",
diff --git a/sound/pci/ice1712/se.c b/sound/pci/ice1712/se.c
index 69673b9..ffd894b 100644
--- a/sound/pci/ice1712/se.c
+++ b/sound/pci/ice1712/se.c
@@ -22,7 +22,6 @@
  *
  */      
 
-#include <asm/io.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
@@ -114,7 +113,7 @@
 /*  WM8740 interface                                                        */
 /****************************************************************************/
 
-static void __devinit se200pci_WM8740_init(struct snd_ice1712 *ice)
+static void se200pci_WM8740_init(struct snd_ice1712 *ice)
 {
 	/* nothing to do */
 }
@@ -196,7 +195,7 @@
 	}
 }
 
-static void __devinit se200pci_WM8766_init(struct snd_ice1712 *ice)
+static void se200pci_WM8766_init(struct snd_ice1712 *ice)
 {
 	se200pci_WM8766_write(ice, 0x1f, 0x000); /* RESET ALL */
 	udelay(10);
@@ -253,7 +252,7 @@
 	se200pci_WM8776_write(ice, 0x0f, vol2 | 0x100);
 }
 
-static const char *se200pci_sel[] = {
+static const char * const se200pci_sel[] = {
 	"LINE-IN", "CD-IN", "MIC-IN", "ALL-MIX", NULL
 };
 
@@ -278,7 +277,7 @@
 		se200pci_WM8776_write(ice, 0x16, 0x001);
 }
 
-static const char *se200pci_agc[] = {
+static const char * const se200pci_agc[] = {
 	"Off", "LimiterMode", "ALCMode", NULL
 };
 
@@ -300,10 +299,10 @@
 	}
 }
 
-static void __devinit se200pci_WM8776_init(struct snd_ice1712 *ice)
+static void se200pci_WM8776_init(struct snd_ice1712 *ice)
 {
 	int i;
-	static unsigned short __devinitdata default_values[] = {
+	static unsigned short default_values[] = {
 		0x100, 0x100, 0x100,
 		0x100, 0x100, 0x100,
 		0x000, 0x090, 0x000, 0x000,
@@ -352,7 +351,7 @@
 }
 
 struct se200pci_control {
-	char *name;
+	const char *name;
 	enum {
 		WM8766,
 		WM8776in,
@@ -363,7 +362,7 @@
 	} target;
 	enum { VOLUME1, VOLUME2, BOOLEAN, ENUM } type;
 	int ch;
-	const char **member;
+	const char * const *member;
 	const char *comment;
 };
 
@@ -421,7 +420,7 @@
 
 static int se200pci_get_enum_count(int n)
 {
-	const char **member;
+	const char * const *member;
 	int c;
 
 	member = se200pci_cont[n].member;
@@ -600,7 +599,7 @@
 static const DECLARE_TLV_DB_SCALE(db_scale_gain1, -12750, 50, 1);
 static const DECLARE_TLV_DB_SCALE(db_scale_gain2, -10350, 50, 1);
 
-static int __devinit se200pci_add_controls(struct snd_ice1712 *ice)
+static int se200pci_add_controls(struct snd_ice1712 *ice)
 {
 	int i;
 	struct snd_kcontrol_new cont;
@@ -678,7 +677,7 @@
 /*  probe/initialize/setup                                                  */
 /****************************************************************************/
 
-static int __devinit se_init(struct snd_ice1712 *ice)
+static int se_init(struct snd_ice1712 *ice)
 {
 	struct se_spec *spec;
 
@@ -706,7 +705,7 @@
 	return -ENOENT;
 }
 
-static int __devinit se_add_controls(struct snd_ice1712 *ice)
+static int se_add_controls(struct snd_ice1712 *ice)
 {
 	int err;
 
@@ -723,7 +722,7 @@
 /*  entry point                                                             */
 /****************************************************************************/
 
-static unsigned char se200pci_eeprom[] __devinitdata = {
+static unsigned char se200pci_eeprom[] = {
 	[ICE_EEP2_SYSCONF]	= 0x4b,	/* 49.152Hz, spdif-in/ADC, 4DACs */
 	[ICE_EEP2_ACLINK]	= 0x80,	/* I2S */
 	[ICE_EEP2_I2S]		= 0x78,	/* 96k-ok, 24bit, 192k-ok */
@@ -742,7 +741,7 @@
 	[ICE_EEP2_GPIO_STATE2]	= 0x07, /* WM8766 ML/MC/MD */
 };
 
-static unsigned char se90pci_eeprom[] __devinitdata = {
+static unsigned char se90pci_eeprom[] = {
 	[ICE_EEP2_SYSCONF]	= 0x4b,	/* 49.152Hz, spdif-in/ADC, 4DACs */
 	[ICE_EEP2_ACLINK]	= 0x80,	/* I2S */
 	[ICE_EEP2_I2S]		= 0x78,	/* 96k-ok, 24bit, 192k-ok */
@@ -751,7 +750,7 @@
 	/* ALL GPIO bits are in input mode */
 };
 
-struct snd_ice1712_card_info snd_vt1724_se_cards[] __devinitdata = {
+struct snd_ice1712_card_info snd_vt1724_se_cards[] = {
 	{
 		.subvendor = VT1724_SUBDEVICE_SE200PCI,
 		.name = "ONKYO SE200PCI",
diff --git a/sound/pci/ice1712/vt1720_mobo.c b/sound/pci/ice1712/vt1720_mobo.c
index 4c551e1..5dbb867 100644
--- a/sound/pci/ice1712/vt1720_mobo.c
+++ b/sound/pci/ice1712/vt1720_mobo.c
@@ -21,7 +21,6 @@
  *
  */      
 
-#include <asm/io.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
@@ -32,7 +31,7 @@
 #include "vt1720_mobo.h"
 
 
-static int __devinit k8x800_init(struct snd_ice1712 *ice)
+static int k8x800_init(struct snd_ice1712 *ice)
 {
 	ice->vt1720 = 1;
 
@@ -46,7 +45,7 @@
 	return 0;
 }
 
-static int __devinit k8x800_add_controls(struct snd_ice1712 *ice)
+static int k8x800_add_controls(struct snd_ice1712 *ice)
 {
 	/* FIXME: needs some quirks for VT1616? */
 	return 0;
@@ -54,7 +53,7 @@
 
 /* EEPROM image */
 
-static unsigned char k8x800_eeprom[] __devinitdata = {
+static unsigned char k8x800_eeprom[] = {
 	[ICE_EEP2_SYSCONF]     = 0x01,	/* clock 256, 1ADC, 2DACs */
 	[ICE_EEP2_ACLINK]      = 0x02,	/* ACLINK, packed */
 	[ICE_EEP2_I2S]         = 0x00,	/* - */
@@ -70,7 +69,7 @@
 	[ICE_EEP2_GPIO_STATE2] = 0x00,	/* - */
 };
 
-static unsigned char sn25p_eeprom[] __devinitdata = {
+static unsigned char sn25p_eeprom[] = {
 	[ICE_EEP2_SYSCONF]     = 0x01,	/* clock 256, 1ADC, 2DACs */
 	[ICE_EEP2_ACLINK]      = 0x02,	/* ACLINK, packed */
 	[ICE_EEP2_I2S]         = 0x00,	/* - */
@@ -88,7 +87,7 @@
 
 
 /* entry point */
-struct snd_ice1712_card_info snd_vt1720_mobo_cards[] __devinitdata = {
+struct snd_ice1712_card_info snd_vt1720_mobo_cards[] = {
 	{
 		.subvendor = VT1720_SUBDEVICE_K8X800,
 		.name = "Albatron K8X800 Pro II",
diff --git a/sound/pci/ice1712/wm8766.c b/sound/pci/ice1712/wm8766.c
new file mode 100644
index 0000000..8072ade
--- /dev/null
+++ b/sound/pci/ice1712/wm8766.c
@@ -0,0 +1,361 @@
+/*
+ *   ALSA driver for ICEnsemble VT17xx
+ *
+ *   Lowlevel functions for WM8766 codec
+ *
+ *	Copyright (c) 2012 Ondrej Zary <linux@rainbow-software.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., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ *
+ */
+
+#include <linux/delay.h>
+#include <sound/core.h>
+#include <sound/control.h>
+#include <sound/tlv.h>
+#include "wm8766.h"
+
+/* low-level access */
+
+static void snd_wm8766_write(struct snd_wm8766 *wm, u16 addr, u16 data)
+{
+	if (addr < WM8766_REG_RESET)
+		wm->regs[addr] = data;
+	wm->ops.write(wm, addr, data);
+}
+
+/* mixer controls */
+
+static const DECLARE_TLV_DB_SCALE(wm8766_tlv, -12750, 50, 1);
+
+static struct snd_wm8766_ctl snd_wm8766_default_ctl[WM8766_CTL_COUNT] = {
+	[WM8766_CTL_CH1_VOL] = {
+		.name = "Channel 1 Playback Volume",
+		.type = SNDRV_CTL_ELEM_TYPE_INTEGER,
+		.tlv = wm8766_tlv,
+		.reg1 = WM8766_REG_DACL1,
+		.reg2 = WM8766_REG_DACR1,
+		.mask1 = WM8766_VOL_MASK,
+		.mask2 = WM8766_VOL_MASK,
+		.max = 0xff,
+		.flags = WM8766_FLAG_STEREO | WM8766_FLAG_VOL_UPDATE,
+	},
+	[WM8766_CTL_CH2_VOL] = {
+		.name = "Channel 2 Playback Volume",
+		.type = SNDRV_CTL_ELEM_TYPE_INTEGER,
+		.tlv = wm8766_tlv,
+		.reg1 = WM8766_REG_DACL2,
+		.reg2 = WM8766_REG_DACR2,
+		.mask1 = WM8766_VOL_MASK,
+		.mask2 = WM8766_VOL_MASK,
+		.max = 0xff,
+		.flags = WM8766_FLAG_STEREO | WM8766_FLAG_VOL_UPDATE,
+	},
+	[WM8766_CTL_CH3_VOL] = {
+		.name = "Channel 3 Playback Volume",
+		.type = SNDRV_CTL_ELEM_TYPE_INTEGER,
+		.tlv = wm8766_tlv,
+		.reg1 = WM8766_REG_DACL3,
+		.reg2 = WM8766_REG_DACR3,
+		.mask1 = WM8766_VOL_MASK,
+		.mask2 = WM8766_VOL_MASK,
+		.max = 0xff,
+		.flags = WM8766_FLAG_STEREO | WM8766_FLAG_VOL_UPDATE,
+	},
+	[WM8766_CTL_CH1_SW] = {
+		.name = "Channel 1 Playback Switch",
+		.type = SNDRV_CTL_ELEM_TYPE_BOOLEAN,
+		.reg1 = WM8766_REG_DACCTRL2,
+		.mask1 = WM8766_DAC2_MUTE1,
+		.flags = WM8766_FLAG_INVERT,
+	},
+	[WM8766_CTL_CH2_SW] = {
+		.name = "Channel 2 Playback Switch",
+		.type = SNDRV_CTL_ELEM_TYPE_BOOLEAN,
+		.reg1 = WM8766_REG_DACCTRL2,
+		.mask1 = WM8766_DAC2_MUTE2,
+		.flags = WM8766_FLAG_INVERT,
+	},
+	[WM8766_CTL_CH3_SW] = {
+		.name = "Channel 3 Playback Switch",
+		.type = SNDRV_CTL_ELEM_TYPE_BOOLEAN,
+		.reg1 = WM8766_REG_DACCTRL2,
+		.mask1 = WM8766_DAC2_MUTE3,
+		.flags = WM8766_FLAG_INVERT,
+	},
+	[WM8766_CTL_PHASE1_SW] = {
+		.name = "Channel 1 Phase Invert Playback Switch",
+		.type = SNDRV_CTL_ELEM_TYPE_BOOLEAN,
+		.reg1 = WM8766_REG_IFCTRL,
+		.mask1 = WM8766_PHASE_INVERT1,
+	},
+	[WM8766_CTL_PHASE2_SW] = {
+		.name = "Channel 2 Phase Invert Playback Switch",
+		.type = SNDRV_CTL_ELEM_TYPE_BOOLEAN,
+		.reg1 = WM8766_REG_IFCTRL,
+		.mask1 = WM8766_PHASE_INVERT2,
+	},
+	[WM8766_CTL_PHASE3_SW] = {
+		.name = "Channel 3 Phase Invert Playback Switch",
+		.type = SNDRV_CTL_ELEM_TYPE_BOOLEAN,
+		.reg1 = WM8766_REG_IFCTRL,
+		.mask1 = WM8766_PHASE_INVERT3,
+	},
+	[WM8766_CTL_DEEMPH1_SW] = {
+		.name = "Channel 1 Deemphasis Playback Switch",
+		.type = SNDRV_CTL_ELEM_TYPE_BOOLEAN,
+		.reg1 = WM8766_REG_DACCTRL2,
+		.mask1 = WM8766_DAC2_DEEMP1,
+	},
+	[WM8766_CTL_DEEMPH2_SW] = {
+		.name = "Channel 2 Deemphasis Playback Switch",
+		.type = SNDRV_CTL_ELEM_TYPE_BOOLEAN,
+		.reg1 = WM8766_REG_DACCTRL2,
+		.mask1 = WM8766_DAC2_DEEMP2,
+	},
+	[WM8766_CTL_DEEMPH3_SW] = {
+		.name = "Channel 3 Deemphasis Playback Switch",
+		.type = SNDRV_CTL_ELEM_TYPE_BOOLEAN,
+		.reg1 = WM8766_REG_DACCTRL2,
+		.mask1 = WM8766_DAC2_DEEMP3,
+	},
+	[WM8766_CTL_IZD_SW] = {
+		.name = "Infinite Zero Detect Playback Switch",
+		.type = SNDRV_CTL_ELEM_TYPE_BOOLEAN,
+		.reg1 = WM8766_REG_DACCTRL1,
+		.mask1 = WM8766_DAC_IZD,
+	},
+	[WM8766_CTL_ZC_SW] = {
+		.name = "Zero Cross Detect Playback Switch",
+		.type = SNDRV_CTL_ELEM_TYPE_BOOLEAN,
+		.reg1 = WM8766_REG_DACCTRL2,
+		.mask1 = WM8766_DAC2_ZCD,
+		.flags = WM8766_FLAG_INVERT,
+	},
+};
+
+/* exported functions */
+
+void snd_wm8766_init(struct snd_wm8766 *wm)
+{
+	int i;
+	static const u16 default_values[] = {
+		0x000, 0x100,
+		0x120, 0x000,
+		0x000, 0x100, 0x000, 0x100, 0x000,
+		0x000, 0x080,
+	};
+
+	memcpy(wm->ctl, snd_wm8766_default_ctl, sizeof(wm->ctl));
+
+	snd_wm8766_write(wm, WM8766_REG_RESET, 0x00); /* reset */
+	udelay(10);
+	/* load defaults */
+	for (i = 0; i < ARRAY_SIZE(default_values); i++)
+		snd_wm8766_write(wm, i, default_values[i]);
+}
+
+void snd_wm8766_resume(struct snd_wm8766 *wm)
+{
+	int i;
+
+	for (i = 0; i < WM8766_REG_COUNT; i++)
+		snd_wm8766_write(wm, i, wm->regs[i]);
+}
+
+void snd_wm8766_set_if(struct snd_wm8766 *wm, u16 dac)
+{
+	u16 val = wm->regs[WM8766_REG_IFCTRL] & ~WM8766_IF_MASK;
+
+	dac &= WM8766_IF_MASK;
+	snd_wm8766_write(wm, WM8766_REG_IFCTRL, val | dac);
+}
+
+void snd_wm8766_set_master_mode(struct snd_wm8766 *wm, u16 mode)
+{
+	u16 val = wm->regs[WM8766_REG_DACCTRL3] & ~WM8766_DAC3_MSTR_MASK;
+
+	mode &= WM8766_DAC3_MSTR_MASK;
+	snd_wm8766_write(wm, WM8766_REG_DACCTRL3, val | mode);
+}
+
+void snd_wm8766_set_power(struct snd_wm8766 *wm, u16 power)
+{
+	u16 val = wm->regs[WM8766_REG_DACCTRL3] & ~WM8766_DAC3_POWER_MASK;
+
+	power &= WM8766_DAC3_POWER_MASK;
+	snd_wm8766_write(wm, WM8766_REG_DACCTRL3, val | power);
+}
+
+void snd_wm8766_volume_restore(struct snd_wm8766 *wm)
+{
+	u16 val = wm->regs[WM8766_REG_DACR1];
+	/* restore volume after MCLK stopped */
+	snd_wm8766_write(wm, WM8766_REG_DACR1, val | WM8766_VOL_UPDATE);
+}
+
+/* mixer callbacks */
+
+static int snd_wm8766_volume_info(struct snd_kcontrol *kcontrol,
+				   struct snd_ctl_elem_info *uinfo)
+{
+	struct snd_wm8766 *wm = snd_kcontrol_chip(kcontrol);
+	int n = kcontrol->private_value;
+
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+	uinfo->count = (wm->ctl[n].flags & WM8766_FLAG_STEREO) ? 2 : 1;
+	uinfo->value.integer.min = wm->ctl[n].min;
+	uinfo->value.integer.max = wm->ctl[n].max;
+
+	return 0;
+}
+
+static int snd_wm8766_enum_info(struct snd_kcontrol *kcontrol,
+				      struct snd_ctl_elem_info *uinfo)
+{
+	struct snd_wm8766 *wm = snd_kcontrol_chip(kcontrol);
+	int n = kcontrol->private_value;
+
+	return snd_ctl_enum_info(uinfo, 1, wm->ctl[n].max,
+						wm->ctl[n].enum_names);
+}
+
+static int snd_wm8766_ctl_get(struct snd_kcontrol *kcontrol,
+				  struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_wm8766 *wm = snd_kcontrol_chip(kcontrol);
+	int n = kcontrol->private_value;
+	u16 val1, val2;
+
+	if (wm->ctl[n].get)
+		wm->ctl[n].get(wm, &val1, &val2);
+	else {
+		val1 = wm->regs[wm->ctl[n].reg1] & wm->ctl[n].mask1;
+		val1 >>= __ffs(wm->ctl[n].mask1);
+		if (wm->ctl[n].flags & WM8766_FLAG_STEREO) {
+			val2 = wm->regs[wm->ctl[n].reg2] & wm->ctl[n].mask2;
+			val2 >>= __ffs(wm->ctl[n].mask2);
+			if (wm->ctl[n].flags & WM8766_FLAG_VOL_UPDATE)
+				val2 &= ~WM8766_VOL_UPDATE;
+		}
+	}
+	if (wm->ctl[n].flags & WM8766_FLAG_INVERT) {
+		val1 = wm->ctl[n].max - (val1 - wm->ctl[n].min);
+		val2 = wm->ctl[n].max - (val2 - wm->ctl[n].min);
+	}
+	ucontrol->value.integer.value[0] = val1;
+	if (wm->ctl[n].flags & WM8766_FLAG_STEREO)
+		ucontrol->value.integer.value[1] = val2;
+
+	return 0;
+}
+
+static int snd_wm8766_ctl_put(struct snd_kcontrol *kcontrol,
+				  struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_wm8766 *wm = snd_kcontrol_chip(kcontrol);
+	int n = kcontrol->private_value;
+	u16 val, regval1, regval2;
+
+	/* this also works for enum because value is an union */
+	regval1 = ucontrol->value.integer.value[0];
+	regval2 = ucontrol->value.integer.value[1];
+	if (wm->ctl[n].flags & WM8766_FLAG_INVERT) {
+		regval1 = wm->ctl[n].max - (regval1 - wm->ctl[n].min);
+		regval2 = wm->ctl[n].max - (regval2 - wm->ctl[n].min);
+	}
+	if (wm->ctl[n].set)
+		wm->ctl[n].set(wm, regval1, regval2);
+	else {
+		val = wm->regs[wm->ctl[n].reg1] & ~wm->ctl[n].mask1;
+		val |= regval1 << __ffs(wm->ctl[n].mask1);
+		/* both stereo controls in one register */
+		if (wm->ctl[n].flags & WM8766_FLAG_STEREO &&
+				wm->ctl[n].reg1 == wm->ctl[n].reg2) {
+			val &= ~wm->ctl[n].mask2;
+			val |= regval2 << __ffs(wm->ctl[n].mask2);
+		}
+		snd_wm8766_write(wm, wm->ctl[n].reg1, val);
+		/* stereo controls in different registers */
+		if (wm->ctl[n].flags & WM8766_FLAG_STEREO &&
+				wm->ctl[n].reg1 != wm->ctl[n].reg2) {
+			val = wm->regs[wm->ctl[n].reg2] & ~wm->ctl[n].mask2;
+			val |= regval2 << __ffs(wm->ctl[n].mask2);
+			if (wm->ctl[n].flags & WM8766_FLAG_VOL_UPDATE)
+				val |= WM8766_VOL_UPDATE;
+			snd_wm8766_write(wm, wm->ctl[n].reg2, val);
+		}
+	}
+
+	return 0;
+}
+
+static int snd_wm8766_add_control(struct snd_wm8766 *wm, int num)
+{
+	struct snd_kcontrol_new cont;
+	struct snd_kcontrol *ctl;
+
+	memset(&cont, 0, sizeof(cont));
+	cont.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
+	cont.private_value = num;
+	cont.name = wm->ctl[num].name;
+	cont.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
+	if (wm->ctl[num].flags & WM8766_FLAG_LIM ||
+	    wm->ctl[num].flags & WM8766_FLAG_ALC)
+		cont.access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE;
+	cont.tlv.p = NULL;
+	cont.get = snd_wm8766_ctl_get;
+	cont.put = snd_wm8766_ctl_put;
+
+	switch (wm->ctl[num].type) {
+	case SNDRV_CTL_ELEM_TYPE_INTEGER:
+		cont.info = snd_wm8766_volume_info;
+		cont.access |= SNDRV_CTL_ELEM_ACCESS_TLV_READ;
+		cont.tlv.p = wm->ctl[num].tlv;
+		break;
+	case SNDRV_CTL_ELEM_TYPE_BOOLEAN:
+		wm->ctl[num].max = 1;
+		if (wm->ctl[num].flags & WM8766_FLAG_STEREO)
+			cont.info = snd_ctl_boolean_stereo_info;
+		else
+			cont.info = snd_ctl_boolean_mono_info;
+		break;
+	case SNDRV_CTL_ELEM_TYPE_ENUMERATED:
+		cont.info = snd_wm8766_enum_info;
+		break;
+	default:
+		return -EINVAL;
+	}
+	ctl = snd_ctl_new1(&cont, wm);
+	if (!ctl)
+		return -ENOMEM;
+	wm->ctl[num].kctl = ctl;
+
+	return snd_ctl_add(wm->card, ctl);
+}
+
+int snd_wm8766_build_controls(struct snd_wm8766 *wm)
+{
+	int err, i;
+
+	for (i = 0; i < WM8766_CTL_COUNT; i++)
+		if (wm->ctl[i].name) {
+			err = snd_wm8766_add_control(wm, i);
+			if (err < 0)
+				return err;
+		}
+
+	return 0;
+}
diff --git a/sound/pci/ice1712/wm8766.h b/sound/pci/ice1712/wm8766.h
new file mode 100644
index 0000000..c119f84
--- /dev/null
+++ b/sound/pci/ice1712/wm8766.h
@@ -0,0 +1,163 @@
+#ifndef __SOUND_WM8766_H
+#define __SOUND_WM8766_H
+
+/*
+ *   ALSA driver for ICEnsemble VT17xx
+ *
+ *   Lowlevel functions for WM8766 codec
+ *
+ *	Copyright (c) 2012 Ondrej Zary <linux@rainbow-software.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., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ *
+ */
+
+#define WM8766_REG_DACL1	0x00
+#define WM8766_REG_DACR1	0x01
+#define WM8766_VOL_MASK			0x1ff		/* incl. update bit */
+#define WM8766_VOL_UPDATE		(1 << 8)	/* update volume */
+#define WM8766_REG_DACCTRL1	0x02
+#define WM8766_DAC_MUTEALL		(1 << 0)
+#define WM8766_DAC_DEEMPALL		(1 << 1)
+#define WM8766_DAC_PDWN			(1 << 2)
+#define WM8766_DAC_ATC			(1 << 3)
+#define WM8766_DAC_IZD			(1 << 4)
+#define WM8766_DAC_PL_MASK		0x1e0
+#define WM8766_DAC_PL_LL		(1 << 5)	/* L chan: L signal */
+#define WM8766_DAC_PL_LR		(2 << 5)	/* L chan: R signal */
+#define WM8766_DAC_PL_LB		(3 << 5)	/* L chan: both */
+#define WM8766_DAC_PL_RL		(1 << 7)	/* R chan: L signal */
+#define WM8766_DAC_PL_RR		(2 << 7)	/* R chan: R signal */
+#define WM8766_DAC_PL_RB		(3 << 7)	/* R chan: both */
+#define WM8766_REG_IFCTRL	0x03
+#define WM8766_IF_FMT_RIGHTJ		(0 << 0)
+#define WM8766_IF_FMT_LEFTJ		(1 << 0)
+#define WM8766_IF_FMT_I2S		(2 << 0)
+#define WM8766_IF_FMT_DSP		(3 << 0)
+#define WM8766_IF_DSP_LATE		(1 << 2)	/* in DSP mode */
+#define WM8766_IF_LRC_INVERTED		(1 << 2)	/* in other modes */
+#define WM8766_IF_BCLK_INVERTED		(1 << 3)
+#define WM8766_IF_IWL_16BIT		(0 << 4)
+#define WM8766_IF_IWL_20BIT		(1 << 4)
+#define WM8766_IF_IWL_24BIT		(2 << 4)
+#define WM8766_IF_IWL_32BIT		(3 << 4)
+#define WM8766_IF_MASK			0x3f
+#define WM8766_PHASE_INVERT1		(1 << 6)
+#define WM8766_PHASE_INVERT2		(1 << 7)
+#define WM8766_PHASE_INVERT3		(1 << 8)
+#define WM8766_REG_DACL2	0x04
+#define WM8766_REG_DACR2	0x05
+#define WM8766_REG_DACL3	0x06
+#define WM8766_REG_DACR3	0x07
+#define WM8766_REG_MASTDA	0x08
+#define WM8766_REG_DACCTRL2	0x09
+#define WM8766_DAC2_ZCD			(1 << 0)
+#define WM8766_DAC2_ZFLAG_ALL		(0 << 1)
+#define WM8766_DAC2_ZFLAG_1		(1 << 1)
+#define WM8766_DAC2_ZFLAG_2		(2 << 1)
+#define WM8766_DAC2_ZFLAG_3		(3 << 1)
+#define WM8766_DAC2_MUTE1		(1 << 3)
+#define WM8766_DAC2_MUTE2		(1 << 4)
+#define WM8766_DAC2_MUTE3		(1 << 5)
+#define WM8766_DAC2_DEEMP1		(1 << 6)
+#define WM8766_DAC2_DEEMP2		(1 << 7)
+#define WM8766_DAC2_DEEMP3		(1 << 8)
+#define WM8766_REG_DACCTRL3	0x0a
+#define WM8766_DAC3_DACPD1		(1 << 1)
+#define WM8766_DAC3_DACPD2		(1 << 2)
+#define WM8766_DAC3_DACPD3		(1 << 3)
+#define WM8766_DAC3_PWRDNALL		(1 << 4)
+#define WM8766_DAC3_POWER_MASK		0x1e
+#define WM8766_DAC3_MASTER		(1 << 5)
+#define WM8766_DAC3_DAC128FS		(0 << 6)
+#define WM8766_DAC3_DAC192FS		(1 << 6)
+#define WM8766_DAC3_DAC256FS		(2 << 6)
+#define WM8766_DAC3_DAC384FS		(3 << 6)
+#define WM8766_DAC3_DAC512FS		(4 << 6)
+#define WM8766_DAC3_DAC768FS		(5 << 6)
+#define WM8766_DAC3_MSTR_MASK		0x1e0
+#define WM8766_REG_MUTE1	0x0c
+#define WM8766_MUTE1_MPD		(1 << 6)
+#define WM8766_REG_MUTE2	0x0f
+#define WM8766_MUTE2_MPD		(1 << 5)
+#define WM8766_REG_RESET	0x1f
+
+#define WM8766_REG_COUNT	0x10	/* don't cache the RESET register */
+
+struct snd_wm8766;
+
+struct snd_wm8766_ops {
+	void (*write)(struct snd_wm8766 *wm, u16 addr, u16 data);
+};
+
+enum snd_wm8766_ctl_id {
+	WM8766_CTL_CH1_VOL,
+	WM8766_CTL_CH2_VOL,
+	WM8766_CTL_CH3_VOL,
+	WM8766_CTL_CH1_SW,
+	WM8766_CTL_CH2_SW,
+	WM8766_CTL_CH3_SW,
+	WM8766_CTL_PHASE1_SW,
+	WM8766_CTL_PHASE2_SW,
+	WM8766_CTL_PHASE3_SW,
+	WM8766_CTL_DEEMPH1_SW,
+	WM8766_CTL_DEEMPH2_SW,
+	WM8766_CTL_DEEMPH3_SW,
+	WM8766_CTL_IZD_SW,
+	WM8766_CTL_ZC_SW,
+
+	WM8766_CTL_COUNT,
+};
+
+#define WM8766_ENUM_MAX		16
+
+#define WM8766_FLAG_STEREO	(1 << 0)
+#define WM8766_FLAG_VOL_UPDATE	(1 << 1)
+#define WM8766_FLAG_INVERT	(1 << 2)
+#define WM8766_FLAG_LIM		(1 << 3)
+#define WM8766_FLAG_ALC		(1 << 4)
+
+struct snd_wm8766_ctl {
+	struct snd_kcontrol *kctl;
+	const char *name;
+	snd_ctl_elem_type_t type;
+	const char *const enum_names[WM8766_ENUM_MAX];
+	const unsigned int *tlv;
+	u16 reg1, reg2, mask1, mask2, min, max, flags;
+	void (*set)(struct snd_wm8766 *wm, u16 ch1, u16 ch2);
+	void (*get)(struct snd_wm8766 *wm, u16 *ch1, u16 *ch2);
+};
+
+enum snd_wm8766_agc_mode { WM8766_AGC_OFF, WM8766_AGC_LIM, WM8766_AGC_ALC };
+
+struct snd_wm8766 {
+	struct snd_card *card;
+	struct snd_wm8766_ctl ctl[WM8766_CTL_COUNT];
+	enum snd_wm8766_agc_mode agc_mode;
+	struct snd_wm8766_ops ops;
+	u16 regs[WM8766_REG_COUNT];	/* 9-bit registers */
+};
+
+
+
+void snd_wm8766_init(struct snd_wm8766 *wm);
+void snd_wm8766_resume(struct snd_wm8766 *wm);
+void snd_wm8766_set_if(struct snd_wm8766 *wm, u16 dac);
+void snd_wm8766_set_master_mode(struct snd_wm8766 *wm, u16 mode);
+void snd_wm8766_set_power(struct snd_wm8766 *wm, u16 power);
+void snd_wm8766_volume_restore(struct snd_wm8766 *wm);
+int snd_wm8766_build_controls(struct snd_wm8766 *wm);
+
+#endif /* __SOUND_WM8766_H */
diff --git a/sound/pci/ice1712/wm8776.c b/sound/pci/ice1712/wm8776.c
new file mode 100644
index 0000000..a3c05fe
--- /dev/null
+++ b/sound/pci/ice1712/wm8776.c
@@ -0,0 +1,633 @@
+/*
+ *   ALSA driver for ICEnsemble VT17xx
+ *
+ *   Lowlevel functions for WM8776 codec
+ *
+ *	Copyright (c) 2012 Ondrej Zary <linux@rainbow-software.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., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ *
+ */
+
+#include <linux/delay.h>
+#include <sound/core.h>
+#include <sound/control.h>
+#include <sound/tlv.h>
+#include "wm8776.h"
+
+/* low-level access */
+
+static void snd_wm8776_write(struct snd_wm8776 *wm, u16 addr, u16 data)
+{
+	u8 bus_addr = addr << 1 | data >> 8;	/* addr + 9th data bit */
+	u8 bus_data = data & 0xff;		/* remaining 8 data bits */
+
+	if (addr < WM8776_REG_RESET)
+		wm->regs[addr] = data;
+	wm->ops.write(wm, bus_addr, bus_data);
+}
+
+/* register-level functions */
+
+static void snd_wm8776_activate_ctl(struct snd_wm8776 *wm,
+				    const char *ctl_name,
+				    bool active)
+{
+	struct snd_card *card = wm->card;
+	struct snd_kcontrol *kctl;
+	struct snd_kcontrol_volatile *vd;
+	struct snd_ctl_elem_id elem_id;
+	unsigned int index_offset;
+
+	memset(&elem_id, 0, sizeof(elem_id));
+	strncpy(elem_id.name, ctl_name, sizeof(elem_id.name));
+	elem_id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
+	kctl = snd_ctl_find_id(card, &elem_id);
+	if (!kctl)
+		return;
+	index_offset = snd_ctl_get_ioff(kctl, &kctl->id);
+	vd = &kctl->vd[index_offset];
+	if (active)
+		vd->access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
+	else
+		vd->access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE;
+	snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_INFO, &kctl->id);
+}
+
+static void snd_wm8776_update_agc_ctl(struct snd_wm8776 *wm)
+{
+	int i, flags_on = 0, flags_off = 0;
+
+	switch (wm->agc_mode) {
+	case WM8776_AGC_OFF:
+		flags_off = WM8776_FLAG_LIM | WM8776_FLAG_ALC;
+		break;
+	case WM8776_AGC_LIM:
+		flags_off = WM8776_FLAG_ALC;
+		flags_on = WM8776_FLAG_LIM;
+		break;
+	case WM8776_AGC_ALC_R:
+	case WM8776_AGC_ALC_L:
+	case WM8776_AGC_ALC_STEREO:
+		flags_off = WM8776_FLAG_LIM;
+		flags_on = WM8776_FLAG_ALC;
+		break;
+	}
+
+	for (i = 0; i < WM8776_CTL_COUNT; i++)
+		if (wm->ctl[i].flags & flags_off)
+			snd_wm8776_activate_ctl(wm, wm->ctl[i].name, false);
+		else if (wm->ctl[i].flags & flags_on)
+			snd_wm8776_activate_ctl(wm, wm->ctl[i].name, true);
+}
+
+static void snd_wm8776_set_agc(struct snd_wm8776 *wm, u16 agc, u16 nothing)
+{
+	u16 alc1 = wm->regs[WM8776_REG_ALCCTRL1] & ~WM8776_ALC1_LCT_MASK;
+	u16 alc2 = wm->regs[WM8776_REG_ALCCTRL2] & ~WM8776_ALC2_LCEN;
+
+	switch (agc) {
+	case 0:	/* Off */
+		wm->agc_mode = WM8776_AGC_OFF;
+		break;
+	case 1: /* Limiter */
+		alc2 |= WM8776_ALC2_LCEN;
+		wm->agc_mode = WM8776_AGC_LIM;
+		break;
+	case 2: /* ALC Right */
+		alc1 |= WM8776_ALC1_LCSEL_ALCR;
+		alc2 |= WM8776_ALC2_LCEN;
+		wm->agc_mode = WM8776_AGC_ALC_R;
+		break;
+	case 3: /* ALC Left */
+		alc1 |= WM8776_ALC1_LCSEL_ALCL;
+		alc2 |= WM8776_ALC2_LCEN;
+		wm->agc_mode = WM8776_AGC_ALC_L;
+		break;
+	case 4: /* ALC Stereo */
+		alc1 |= WM8776_ALC1_LCSEL_ALCSTEREO;
+		alc2 |= WM8776_ALC2_LCEN;
+		wm->agc_mode = WM8776_AGC_ALC_STEREO;
+		break;
+	}
+	snd_wm8776_write(wm, WM8776_REG_ALCCTRL1, alc1);
+	snd_wm8776_write(wm, WM8776_REG_ALCCTRL2, alc2);
+	snd_wm8776_update_agc_ctl(wm);
+}
+
+static void snd_wm8776_get_agc(struct snd_wm8776 *wm, u16 *mode, u16 *nothing)
+{
+	*mode = wm->agc_mode;
+}
+
+/* mixer controls */
+
+static const DECLARE_TLV_DB_SCALE(wm8776_hp_tlv, -7400, 100, 1);
+static const DECLARE_TLV_DB_SCALE(wm8776_dac_tlv, -12750, 50, 1);
+static const DECLARE_TLV_DB_SCALE(wm8776_adc_tlv, -10350, 50, 1);
+static const DECLARE_TLV_DB_SCALE(wm8776_lct_tlv, -1600, 100, 0);
+static const DECLARE_TLV_DB_SCALE(wm8776_maxgain_tlv, 0, 400, 0);
+static const DECLARE_TLV_DB_SCALE(wm8776_ngth_tlv, -7800, 600, 0);
+static const DECLARE_TLV_DB_SCALE(wm8776_maxatten_lim_tlv, -1200, 100, 0);
+static const DECLARE_TLV_DB_SCALE(wm8776_maxatten_alc_tlv, -2100, 400, 0);
+
+static struct snd_wm8776_ctl snd_wm8776_default_ctl[WM8776_CTL_COUNT] = {
+	[WM8776_CTL_DAC_VOL] = {
+		.name = "Master Playback Volume",
+		.type = SNDRV_CTL_ELEM_TYPE_INTEGER,
+		.tlv = wm8776_dac_tlv,
+		.reg1 = WM8776_REG_DACLVOL,
+		.reg2 = WM8776_REG_DACRVOL,
+		.mask1 = WM8776_DACVOL_MASK,
+		.mask2 = WM8776_DACVOL_MASK,
+		.max = 0xff,
+		.flags = WM8776_FLAG_STEREO | WM8776_FLAG_VOL_UPDATE,
+	},
+	[WM8776_CTL_DAC_SW] = {
+		.name = "Master Playback Switch",
+		.type = SNDRV_CTL_ELEM_TYPE_BOOLEAN,
+		.reg1 = WM8776_REG_DACCTRL1,
+		.reg2 = WM8776_REG_DACCTRL1,
+		.mask1 = WM8776_DAC_PL_LL,
+		.mask2 = WM8776_DAC_PL_RR,
+		.flags = WM8776_FLAG_STEREO,
+	},
+	[WM8776_CTL_DAC_ZC_SW] = {
+		.name = "Master Zero Cross Detect Playback Switch",
+		.type = SNDRV_CTL_ELEM_TYPE_BOOLEAN,
+		.reg1 = WM8776_REG_DACCTRL1,
+		.mask1 = WM8776_DAC_DZCEN,
+	},
+	[WM8776_CTL_HP_VOL] = {
+		.name = "Headphone Playback Volume",
+		.type = SNDRV_CTL_ELEM_TYPE_INTEGER,
+		.tlv = wm8776_hp_tlv,
+		.reg1 = WM8776_REG_HPLVOL,
+		.reg2 = WM8776_REG_HPRVOL,
+		.mask1 = WM8776_HPVOL_MASK,
+		.mask2 = WM8776_HPVOL_MASK,
+		.min = 0x2f,
+		.max = 0x7f,
+		.flags = WM8776_FLAG_STEREO | WM8776_FLAG_VOL_UPDATE,
+	},
+	[WM8776_CTL_HP_SW] = {
+		.name = "Headphone Playback Switch",
+		.type = SNDRV_CTL_ELEM_TYPE_BOOLEAN,
+		.reg1 = WM8776_REG_PWRDOWN,
+		.mask1 = WM8776_PWR_HPPD,
+		.flags = WM8776_FLAG_INVERT,
+	},
+	[WM8776_CTL_HP_ZC_SW] = {
+		.name = "Headphone Zero Cross Detect Playback Switch",
+		.type = SNDRV_CTL_ELEM_TYPE_BOOLEAN,
+		.reg1 = WM8776_REG_HPLVOL,
+		.reg2 = WM8776_REG_HPRVOL,
+		.mask1 = WM8776_VOL_HPZCEN,
+		.mask2 = WM8776_VOL_HPZCEN,
+		.flags = WM8776_FLAG_STEREO,
+	},
+	[WM8776_CTL_AUX_SW] = {
+		.name = "AUX Playback Switch",
+		.type = SNDRV_CTL_ELEM_TYPE_BOOLEAN,
+		.reg1 = WM8776_REG_OUTMUX,
+		.mask1 = WM8776_OUTMUX_AUX,
+	},
+	[WM8776_CTL_BYPASS_SW] = {
+		.name = "Bypass Playback Switch",
+		.type = SNDRV_CTL_ELEM_TYPE_BOOLEAN,
+		.reg1 = WM8776_REG_OUTMUX,
+		.mask1 = WM8776_OUTMUX_BYPASS,
+	},
+	[WM8776_CTL_DAC_IZD_SW] = {
+		.name = "Infinite Zero Detect Playback Switch",
+		.type = SNDRV_CTL_ELEM_TYPE_BOOLEAN,
+		.reg1 = WM8776_REG_DACCTRL1,
+		.mask1 = WM8776_DAC_IZD,
+	},
+	[WM8776_CTL_PHASE_SW] = {
+		.name = "Phase Invert Playback Switch",
+		.type = SNDRV_CTL_ELEM_TYPE_BOOLEAN,
+		.reg1 = WM8776_REG_PHASESWAP,
+		.reg2 = WM8776_REG_PHASESWAP,
+		.mask1 = WM8776_PHASE_INVERTL,
+		.mask2 = WM8776_PHASE_INVERTR,
+		.flags = WM8776_FLAG_STEREO,
+	},
+	[WM8776_CTL_DEEMPH_SW] = {
+		.name = "Deemphasis Playback Switch",
+		.type = SNDRV_CTL_ELEM_TYPE_BOOLEAN,
+		.reg1 = WM8776_REG_DACCTRL2,
+		.mask1 = WM8776_DAC2_DEEMPH,
+	},
+	[WM8776_CTL_ADC_VOL] = {
+		.name = "Input Capture Volume",
+		.type = SNDRV_CTL_ELEM_TYPE_INTEGER,
+		.tlv = wm8776_adc_tlv,
+		.reg1 = WM8776_REG_ADCLVOL,
+		.reg2 = WM8776_REG_ADCRVOL,
+		.mask1 = WM8776_ADC_GAIN_MASK,
+		.mask2 = WM8776_ADC_GAIN_MASK,
+		.max = 0xff,
+		.flags = WM8776_FLAG_STEREO | WM8776_FLAG_VOL_UPDATE,
+	},
+	[WM8776_CTL_ADC_SW] = {
+		.name = "Input Capture Switch",
+		.type = SNDRV_CTL_ELEM_TYPE_BOOLEAN,
+		.reg1 = WM8776_REG_ADCMUX,
+		.reg2 = WM8776_REG_ADCMUX,
+		.mask1 = WM8776_ADC_MUTEL,
+		.mask2 = WM8776_ADC_MUTER,
+		.flags = WM8776_FLAG_STEREO | WM8776_FLAG_INVERT,
+	},
+	[WM8776_CTL_INPUT1_SW] = {
+		.name = "AIN1 Capture Switch",
+		.type = SNDRV_CTL_ELEM_TYPE_BOOLEAN,
+		.reg1 = WM8776_REG_ADCMUX,
+		.mask1 = WM8776_ADC_MUX_AIN1,
+	},
+	[WM8776_CTL_INPUT2_SW] = {
+		.name = "AIN2 Capture Switch",
+		.type = SNDRV_CTL_ELEM_TYPE_BOOLEAN,
+		.reg1 = WM8776_REG_ADCMUX,
+		.mask1 = WM8776_ADC_MUX_AIN2,
+	},
+	[WM8776_CTL_INPUT3_SW] = {
+		.name = "AIN3 Capture Switch",
+		.type = SNDRV_CTL_ELEM_TYPE_BOOLEAN,
+		.reg1 = WM8776_REG_ADCMUX,
+		.mask1 = WM8776_ADC_MUX_AIN3,
+	},
+	[WM8776_CTL_INPUT4_SW] = {
+		.name = "AIN4 Capture Switch",
+		.type = SNDRV_CTL_ELEM_TYPE_BOOLEAN,
+		.reg1 = WM8776_REG_ADCMUX,
+		.mask1 = WM8776_ADC_MUX_AIN4,
+	},
+	[WM8776_CTL_INPUT5_SW] = {
+		.name = "AIN5 Capture Switch",
+		.type = SNDRV_CTL_ELEM_TYPE_BOOLEAN,
+		.reg1 = WM8776_REG_ADCMUX,
+		.mask1 = WM8776_ADC_MUX_AIN5,
+	},
+	[WM8776_CTL_AGC_SEL] = {
+		.name = "AGC Select Capture Enum",
+		.type = SNDRV_CTL_ELEM_TYPE_ENUMERATED,
+		.enum_names = { "Off", "Limiter", "ALC Right", "ALC Left",
+				"ALC Stereo" },
+		.max = 5,	/* .enum_names item count */
+		.set = snd_wm8776_set_agc,
+		.get = snd_wm8776_get_agc,
+	},
+	[WM8776_CTL_LIM_THR] = {
+		.name = "Limiter Threshold Capture Volume",
+		.type = SNDRV_CTL_ELEM_TYPE_INTEGER,
+		.tlv = wm8776_lct_tlv,
+		.reg1 = WM8776_REG_ALCCTRL1,
+		.mask1 = WM8776_ALC1_LCT_MASK,
+		.max = 15,
+		.flags = WM8776_FLAG_LIM,
+	},
+	[WM8776_CTL_LIM_ATK] = {
+		.name = "Limiter Attack Time Capture Enum",
+		.type = SNDRV_CTL_ELEM_TYPE_ENUMERATED,
+		.enum_names = { "0.25 ms", "0.5 ms", "1 ms", "2 ms", "4 ms",
+			"8 ms", "16 ms", "32 ms", "64 ms", "128 ms", "256 ms" },
+		.max = 11,	/* .enum_names item count */
+		.reg1 = WM8776_REG_ALCCTRL3,
+		.mask1 = WM8776_ALC3_ATK_MASK,
+		.flags = WM8776_FLAG_LIM,
+	},
+	[WM8776_CTL_LIM_DCY] = {
+		.name = "Limiter Decay Time Capture Enum",
+		.type = SNDRV_CTL_ELEM_TYPE_ENUMERATED,
+		.enum_names = {	"1.2 ms", "2.4 ms", "4.8 ms", "9.6 ms",
+			"19.2 ms", "38.4 ms", "76.8 ms", "154 ms", "307 ms",
+			"614 ms", "1.23 s" },
+		.max = 11,	/* .enum_names item count */
+		.reg1 = WM8776_REG_ALCCTRL3,
+		.mask1 = WM8776_ALC3_DCY_MASK,
+		.flags = WM8776_FLAG_LIM,
+	},
+	[WM8776_CTL_LIM_TRANWIN] = {
+		.name = "Limiter Transient Window Capture Enum",
+		.type = SNDRV_CTL_ELEM_TYPE_ENUMERATED,
+		.enum_names = {	"0 us", "62.5 us", "125 us", "250 us", "500 us",
+			"1 ms", "2 ms", "4 ms" },
+		.max = 8,	/* .enum_names item count */
+		.reg1 = WM8776_REG_LIMITER,
+		.mask1 = WM8776_LIM_TRANWIN_MASK,
+		.flags = WM8776_FLAG_LIM,
+	},
+	[WM8776_CTL_LIM_MAXATTN] = {
+		.name = "Limiter Maximum Attenuation Capture Volume",
+		.type = SNDRV_CTL_ELEM_TYPE_INTEGER,
+		.tlv = wm8776_maxatten_lim_tlv,
+		.reg1 = WM8776_REG_LIMITER,
+		.mask1 = WM8776_LIM_MAXATTEN_MASK,
+		.min = 3,
+		.max = 12,
+		.flags = WM8776_FLAG_LIM | WM8776_FLAG_INVERT,
+	},
+	[WM8776_CTL_ALC_TGT] = {
+		.name = "ALC Target Level Capture Volume",
+		.type = SNDRV_CTL_ELEM_TYPE_INTEGER,
+		.tlv = wm8776_lct_tlv,
+		.reg1 = WM8776_REG_ALCCTRL1,
+		.mask1 = WM8776_ALC1_LCT_MASK,
+		.max = 15,
+		.flags = WM8776_FLAG_ALC,
+	},
+	[WM8776_CTL_ALC_ATK] = {
+		.name = "ALC Attack Time Capture Enum",
+		.type = SNDRV_CTL_ELEM_TYPE_ENUMERATED,
+		.enum_names = { "8.40 ms", "16.8 ms", "33.6 ms", "67.2 ms",
+			"134 ms", "269 ms", "538 ms", "1.08 s",	"2.15 s",
+			"4.3 s", "8.6 s" },
+		.max = 11,	/* .enum_names item count */
+		.reg1 = WM8776_REG_ALCCTRL3,
+		.mask1 = WM8776_ALC3_ATK_MASK,
+		.flags = WM8776_FLAG_ALC,
+	},
+	[WM8776_CTL_ALC_DCY] = {
+		.name = "ALC Decay Time Capture Enum",
+		.type = SNDRV_CTL_ELEM_TYPE_ENUMERATED,
+		.enum_names = {	"33.5 ms", "67.0 ms", "134 ms", "268 ms",
+			"536 ms", "1.07 s", "2.14 s", "4.29 s",	"8.58 s",
+			"17.2 s", "34.3 s" },
+		.max = 11,	/* .enum_names item count */
+		.reg1 = WM8776_REG_ALCCTRL3,
+		.mask1 = WM8776_ALC3_DCY_MASK,
+		.flags = WM8776_FLAG_ALC,
+	},
+	[WM8776_CTL_ALC_MAXGAIN] = {
+		.name = "ALC Maximum Gain Capture Volume",
+		.type = SNDRV_CTL_ELEM_TYPE_INTEGER,
+		.tlv = wm8776_maxgain_tlv,
+		.reg1 = WM8776_REG_ALCCTRL1,
+		.mask1 = WM8776_ALC1_MAXGAIN_MASK,
+		.min = 1,
+		.max = 7,
+		.flags = WM8776_FLAG_ALC,
+	},
+	[WM8776_CTL_ALC_MAXATTN] = {
+		.name = "ALC Maximum Attenuation Capture Volume",
+		.type = SNDRV_CTL_ELEM_TYPE_INTEGER,
+		.tlv = wm8776_maxatten_alc_tlv,
+		.reg1 = WM8776_REG_LIMITER,
+		.mask1 = WM8776_LIM_MAXATTEN_MASK,
+		.min = 10,
+		.max = 15,
+		.flags = WM8776_FLAG_ALC | WM8776_FLAG_INVERT,
+	},
+	[WM8776_CTL_ALC_HLD] = {
+		.name = "ALC Hold Time Capture Enum",
+		.type = SNDRV_CTL_ELEM_TYPE_ENUMERATED,
+		.enum_names = {	"0 ms", "2.67 ms", "5.33 ms", "10.6 ms",
+			"21.3 ms", "42.7 ms", "85.3 ms", "171 ms", "341 ms",
+			"683 ms", "1.37 s", "2.73 s", "5.46 s", "10.9 s",
+			"21.8 s", "43.7 s" },
+		.max = 16,	/* .enum_names item count */
+		.reg1 = WM8776_REG_ALCCTRL2,
+		.mask1 = WM8776_ALC2_HOLD_MASK,
+		.flags = WM8776_FLAG_ALC,
+	},
+	[WM8776_CTL_NGT_SW] = {
+		.name = "Noise Gate Capture Switch",
+		.type = SNDRV_CTL_ELEM_TYPE_BOOLEAN,
+		.reg1 = WM8776_REG_NOISEGATE,
+		.mask1 = WM8776_NGAT_ENABLE,
+		.flags = WM8776_FLAG_ALC,
+	},
+	[WM8776_CTL_NGT_THR] = {
+		.name = "Noise Gate Threshold Capture Volume",
+		.type = SNDRV_CTL_ELEM_TYPE_INTEGER,
+		.tlv = wm8776_ngth_tlv,
+		.reg1 = WM8776_REG_NOISEGATE,
+		.mask1 = WM8776_NGAT_THR_MASK,
+		.max = 7,
+		.flags = WM8776_FLAG_ALC,
+	},
+};
+
+/* exported functions */
+
+void snd_wm8776_init(struct snd_wm8776 *wm)
+{
+	int i;
+	static const u16 default_values[] = {
+		0x000, 0x100, 0x000,
+		0x000, 0x100, 0x000,
+		0x000, 0x090, 0x000, 0x000,
+		0x022, 0x022, 0x022,
+		0x008, 0x0cf, 0x0cf, 0x07b, 0x000,
+		0x032, 0x000, 0x0a6, 0x001, 0x001
+	};
+
+	memcpy(wm->ctl, snd_wm8776_default_ctl, sizeof(wm->ctl));
+
+	snd_wm8776_write(wm, WM8776_REG_RESET, 0x00); /* reset */
+	udelay(10);
+	/* load defaults */
+	for (i = 0; i < ARRAY_SIZE(default_values); i++)
+		snd_wm8776_write(wm, i, default_values[i]);
+}
+
+void snd_wm8776_resume(struct snd_wm8776 *wm)
+{
+	int i;
+
+	for (i = 0; i < WM8776_REG_COUNT; i++)
+		snd_wm8776_write(wm, i, wm->regs[i]);
+}
+
+void snd_wm8776_set_dac_if(struct snd_wm8776 *wm, u16 dac)
+{
+	snd_wm8776_write(wm, WM8776_REG_DACIFCTRL, dac);
+}
+
+void snd_wm8776_set_adc_if(struct snd_wm8776 *wm, u16 adc)
+{
+	snd_wm8776_write(wm, WM8776_REG_ADCIFCTRL, adc);
+}
+
+void snd_wm8776_set_master_mode(struct snd_wm8776 *wm, u16 mode)
+{
+	snd_wm8776_write(wm, WM8776_REG_MSTRCTRL, mode);
+}
+
+void snd_wm8776_set_power(struct snd_wm8776 *wm, u16 power)
+{
+	snd_wm8776_write(wm, WM8776_REG_PWRDOWN, power);
+}
+
+void snd_wm8776_volume_restore(struct snd_wm8776 *wm)
+{
+	u16 val = wm->regs[WM8776_REG_DACRVOL];
+	/* restore volume after MCLK stopped */
+	snd_wm8776_write(wm, WM8776_REG_DACRVOL, val | WM8776_VOL_UPDATE);
+}
+
+/* mixer callbacks */
+
+static int snd_wm8776_volume_info(struct snd_kcontrol *kcontrol,
+				   struct snd_ctl_elem_info *uinfo)
+{
+	struct snd_wm8776 *wm = snd_kcontrol_chip(kcontrol);
+	int n = kcontrol->private_value;
+
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+	uinfo->count = (wm->ctl[n].flags & WM8776_FLAG_STEREO) ? 2 : 1;
+	uinfo->value.integer.min = wm->ctl[n].min;
+	uinfo->value.integer.max = wm->ctl[n].max;
+
+	return 0;
+}
+
+static int snd_wm8776_enum_info(struct snd_kcontrol *kcontrol,
+				      struct snd_ctl_elem_info *uinfo)
+{
+	struct snd_wm8776 *wm = snd_kcontrol_chip(kcontrol);
+	int n = kcontrol->private_value;
+
+	return snd_ctl_enum_info(uinfo, 1, wm->ctl[n].max,
+						wm->ctl[n].enum_names);
+}
+
+static int snd_wm8776_ctl_get(struct snd_kcontrol *kcontrol,
+				  struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_wm8776 *wm = snd_kcontrol_chip(kcontrol);
+	int n = kcontrol->private_value;
+	u16 val1, val2;
+
+	if (wm->ctl[n].get)
+		wm->ctl[n].get(wm, &val1, &val2);
+	else {
+		val1 = wm->regs[wm->ctl[n].reg1] & wm->ctl[n].mask1;
+		val1 >>= __ffs(wm->ctl[n].mask1);
+		if (wm->ctl[n].flags & WM8776_FLAG_STEREO) {
+			val2 = wm->regs[wm->ctl[n].reg2] & wm->ctl[n].mask2;
+			val2 >>= __ffs(wm->ctl[n].mask2);
+			if (wm->ctl[n].flags & WM8776_FLAG_VOL_UPDATE)
+				val2 &= ~WM8776_VOL_UPDATE;
+		}
+	}
+	if (wm->ctl[n].flags & WM8776_FLAG_INVERT) {
+		val1 = wm->ctl[n].max - (val1 - wm->ctl[n].min);
+		val2 = wm->ctl[n].max - (val2 - wm->ctl[n].min);
+	}
+	ucontrol->value.integer.value[0] = val1;
+	if (wm->ctl[n].flags & WM8776_FLAG_STEREO)
+		ucontrol->value.integer.value[1] = val2;
+
+	return 0;
+}
+
+static int snd_wm8776_ctl_put(struct snd_kcontrol *kcontrol,
+				  struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_wm8776 *wm = snd_kcontrol_chip(kcontrol);
+	int n = kcontrol->private_value;
+	u16 val, regval1, regval2;
+
+	/* this also works for enum because value is an union */
+	regval1 = ucontrol->value.integer.value[0];
+	regval2 = ucontrol->value.integer.value[1];
+	if (wm->ctl[n].flags & WM8776_FLAG_INVERT) {
+		regval1 = wm->ctl[n].max - (regval1 - wm->ctl[n].min);
+		regval2 = wm->ctl[n].max - (regval2 - wm->ctl[n].min);
+	}
+	if (wm->ctl[n].set)
+		wm->ctl[n].set(wm, regval1, regval2);
+	else {
+		val = wm->regs[wm->ctl[n].reg1] & ~wm->ctl[n].mask1;
+		val |= regval1 << __ffs(wm->ctl[n].mask1);
+		/* both stereo controls in one register */
+		if (wm->ctl[n].flags & WM8776_FLAG_STEREO &&
+				wm->ctl[n].reg1 == wm->ctl[n].reg2) {
+			val &= ~wm->ctl[n].mask2;
+			val |= regval2 << __ffs(wm->ctl[n].mask2);
+		}
+		snd_wm8776_write(wm, wm->ctl[n].reg1, val);
+		/* stereo controls in different registers */
+		if (wm->ctl[n].flags & WM8776_FLAG_STEREO &&
+				wm->ctl[n].reg1 != wm->ctl[n].reg2) {
+			val = wm->regs[wm->ctl[n].reg2] & ~wm->ctl[n].mask2;
+			val |= regval2 << __ffs(wm->ctl[n].mask2);
+			if (wm->ctl[n].flags & WM8776_FLAG_VOL_UPDATE)
+				val |= WM8776_VOL_UPDATE;
+			snd_wm8776_write(wm, wm->ctl[n].reg2, val);
+		}
+	}
+
+	return 0;
+}
+
+static int snd_wm8776_add_control(struct snd_wm8776 *wm, int num)
+{
+	struct snd_kcontrol_new cont;
+	struct snd_kcontrol *ctl;
+
+	memset(&cont, 0, sizeof(cont));
+	cont.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
+	cont.private_value = num;
+	cont.name = wm->ctl[num].name;
+	cont.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
+	if (wm->ctl[num].flags & WM8776_FLAG_LIM ||
+	    wm->ctl[num].flags & WM8776_FLAG_ALC)
+		cont.access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE;
+	cont.tlv.p = NULL;
+	cont.get = snd_wm8776_ctl_get;
+	cont.put = snd_wm8776_ctl_put;
+
+	switch (wm->ctl[num].type) {
+	case SNDRV_CTL_ELEM_TYPE_INTEGER:
+		cont.info = snd_wm8776_volume_info;
+		cont.access |= SNDRV_CTL_ELEM_ACCESS_TLV_READ;
+		cont.tlv.p = wm->ctl[num].tlv;
+		break;
+	case SNDRV_CTL_ELEM_TYPE_BOOLEAN:
+		wm->ctl[num].max = 1;
+		if (wm->ctl[num].flags & WM8776_FLAG_STEREO)
+			cont.info = snd_ctl_boolean_stereo_info;
+		else
+			cont.info = snd_ctl_boolean_mono_info;
+		break;
+	case SNDRV_CTL_ELEM_TYPE_ENUMERATED:
+		cont.info = snd_wm8776_enum_info;
+		break;
+	default:
+		return -EINVAL;
+	}
+	ctl = snd_ctl_new1(&cont, wm);
+	if (!ctl)
+		return -ENOMEM;
+
+	return snd_ctl_add(wm->card, ctl);
+}
+
+int snd_wm8776_build_controls(struct snd_wm8776 *wm)
+{
+	int err, i;
+
+	for (i = 0; i < WM8776_CTL_COUNT; i++)
+		if (wm->ctl[i].name) {
+			err = snd_wm8776_add_control(wm, i);
+			if (err < 0)
+				return err;
+		}
+
+	return 0;
+}
diff --git a/sound/pci/ice1712/wm8776.h b/sound/pci/ice1712/wm8776.h
new file mode 100644
index 0000000..93a2d69
--- /dev/null
+++ b/sound/pci/ice1712/wm8776.h
@@ -0,0 +1,226 @@
+#ifndef __SOUND_WM8776_H
+#define __SOUND_WM8776_H
+
+/*
+ *   ALSA driver for ICEnsemble VT17xx
+ *
+ *   Lowlevel functions for WM8776 codec
+ *
+ *	Copyright (c) 2012 Ondrej Zary <linux@rainbow-software.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., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ *
+ */
+
+#define WM8776_REG_HPLVOL	0x00
+#define WM8776_REG_HPRVOL	0x01
+#define WM8776_REG_HPMASTER	0x02
+#define WM8776_HPVOL_MASK		0x17f		/* incl. update bit */
+#define WM8776_VOL_HPZCEN		(1 << 7)	/* zero cross detect */
+#define WM8776_VOL_UPDATE		(1 << 8)	/* update volume */
+#define WM8776_REG_DACLVOL	0x03
+#define WM8776_REG_DACRVOL	0x04
+#define WM8776_REG_DACMASTER	0x05
+#define WM8776_DACVOL_MASK		0x1ff		/* incl. update bit */
+#define WM8776_REG_PHASESWAP	0x06
+#define WM8776_PHASE_INVERTL		(1 << 0)
+#define WM8776_PHASE_INVERTR		(1 << 1)
+#define WM8776_REG_DACCTRL1	0x07
+#define WM8776_DAC_DZCEN		(1 << 0)
+#define WM8776_DAC_ATC			(1 << 1)
+#define WM8776_DAC_IZD			(1 << 2)
+#define WM8776_DAC_TOD			(1 << 3)
+#define WM8776_DAC_PL_MASK		0xf0
+#define WM8776_DAC_PL_LL		(1 << 4)	/* L chan: L signal */
+#define WM8776_DAC_PL_LR		(2 << 4)	/* L chan: R signal */
+#define WM8776_DAC_PL_LB		(3 << 4)	/* L chan: both */
+#define WM8776_DAC_PL_RL		(1 << 6)	/* R chan: L signal */
+#define WM8776_DAC_PL_RR		(2 << 6)	/* R chan: R signal */
+#define WM8776_DAC_PL_RB		(3 << 6)	/* R chan: both */
+#define WM8776_REG_DACMUTE	0x08
+#define WM8776_DACMUTE			(1 << 0)
+#define WM8776_REG_DACCTRL2	0x09
+#define WM8776_DAC2_DEEMPH		(1 << 0)
+#define WM8776_DAC2_ZFLAG_DISABLE	(0 << 1)
+#define WM8776_DAC2_ZFLAG_OWN		(1 << 1)
+#define WM8776_DAC2_ZFLAG_BOTH		(2 << 1)
+#define WM8776_DAC2_ZFLAG_EITHER	(3 << 1)
+#define WM8776_REG_DACIFCTRL	0x0a
+#define WM8776_FMT_RIGHTJ		(0 << 0)
+#define WM8776_FMT_LEFTJ		(1 << 0)
+#define WM8776_FMT_I2S			(2 << 0)
+#define WM8776_FMT_DSP			(3 << 0)
+#define WM8776_FMT_DSP_LATE		(1 << 2)	/* in DSP mode */
+#define WM8776_FMT_LRC_INVERTED		(1 << 2)	/* in other modes */
+#define WM8776_FMT_BCLK_INVERTED	(1 << 3)
+#define WM8776_FMT_16BIT		(0 << 4)
+#define WM8776_FMT_20BIT		(1 << 4)
+#define WM8776_FMT_24BIT		(2 << 4)
+#define WM8776_FMT_32BIT		(3 << 4)
+#define WM8776_REG_ADCIFCTRL	0x0b
+#define WM8776_FMT_ADCMCLK_INVERTED	(1 << 6)
+#define WM8776_FMT_ADCHPD		(1 << 8)
+#define WM8776_REG_MSTRCTRL	0x0c
+#define WM8776_IF_ADC256FS		(2 << 0)
+#define WM8776_IF_ADC384FS		(3 << 0)
+#define WM8776_IF_ADC512FS		(4 << 0)
+#define WM8776_IF_ADC768FS		(5 << 0)
+#define WM8776_IF_OVERSAMP64		(1 << 3)
+#define WM8776_IF_DAC128FS		(0 << 4)
+#define WM8776_IF_DAC192FS		(1 << 4)
+#define WM8776_IF_DAC256FS		(2 << 4)
+#define WM8776_IF_DAC384FS		(3 << 4)
+#define WM8776_IF_DAC512FS		(4 << 4)
+#define WM8776_IF_DAC768FS		(5 << 4)
+#define WM8776_IF_DAC_MASTER		(1 << 7)
+#define WM8776_IF_ADC_MASTER		(1 << 8)
+#define WM8776_REG_PWRDOWN	0x0d
+#define WM8776_PWR_PDWN			(1 << 0)
+#define WM8776_PWR_ADCPD		(1 << 1)
+#define WM8776_PWR_DACPD		(1 << 2)
+#define WM8776_PWR_HPPD			(1 << 3)
+#define WM8776_PWR_AINPD		(1 << 6)
+#define WM8776_REG_ADCLVOL	0x0e
+#define WM8776_REG_ADCRVOL	0x0f
+#define WM8776_ADC_GAIN_MASK		0xff
+#define WM8776_ADC_ZCEN			(1 << 8)
+#define WM8776_REG_ALCCTRL1	0x10
+#define WM8776_ALC1_LCT_MASK		0x0f	/* 0=-16dB, 1=-15dB..15=-1dB */
+#define WM8776_ALC1_MAXGAIN_MASK	0x70	/* 0,1=0dB, 2=+4dB...7=+24dB */
+#define WM8776_ALC1_LCSEL_MASK		0x180
+#define WM8776_ALC1_LCSEL_LIMITER	(0 << 7)
+#define WM8776_ALC1_LCSEL_ALCR		(1 << 7)
+#define WM8776_ALC1_LCSEL_ALCL		(2 << 7)
+#define WM8776_ALC1_LCSEL_ALCSTEREO	(3 << 7)
+#define WM8776_REG_ALCCTRL2	0x11
+#define WM8776_ALC2_HOLD_MASK		0x0f	/*0=0ms, 1=2.67ms, 2=5.33ms.. */
+#define WM8776_ALC2_ZCEN		(1 << 7)
+#define WM8776_ALC2_LCEN		(1 << 8)
+#define WM8776_REG_ALCCTRL3	0x12
+#define WM8776_ALC3_ATK_MASK		0x0f
+#define WM8776_ALC3_DCY_MASK		0xf0
+#define WM8776_ALC3_FDECAY		(1 << 8)
+#define WM8776_REG_NOISEGATE	0x13
+#define WM8776_NGAT_ENABLE		(1 << 0)
+#define WM8776_NGAT_THR_MASK		0x1c	/*0=-78dB, 1=-72dB...7=-36dB */
+#define WM8776_REG_LIMITER	0x14
+#define WM8776_LIM_MAXATTEN_MASK	0x0f
+#define WM8776_LIM_TRANWIN_MASK		0x70	/*0=0us, 1=62.5us, 2=125us.. */
+#define WM8776_REG_ADCMUX	0x15
+#define WM8776_ADC_MUX_AIN1		(1 << 0)
+#define WM8776_ADC_MUX_AIN2		(1 << 1)
+#define WM8776_ADC_MUX_AIN3		(1 << 2)
+#define WM8776_ADC_MUX_AIN4		(1 << 3)
+#define WM8776_ADC_MUX_AIN5		(1 << 4)
+#define WM8776_ADC_MUTER		(1 << 6)
+#define WM8776_ADC_MUTEL		(1 << 7)
+#define WM8776_ADC_LRBOTH		(1 << 8)
+#define WM8776_REG_OUTMUX	0x16
+#define WM8776_OUTMUX_DAC		(1 << 0)
+#define WM8776_OUTMUX_AUX		(1 << 1)
+#define WM8776_OUTMUX_BYPASS		(1 << 2)
+#define WM8776_REG_RESET	0x17
+
+#define WM8776_REG_COUNT	0x17	/* don't cache the RESET register */
+
+struct snd_wm8776;
+
+struct snd_wm8776_ops {
+	void (*write)(struct snd_wm8776 *wm, u8 addr, u8 data);
+};
+
+enum snd_wm8776_ctl_id {
+	WM8776_CTL_DAC_VOL,
+	WM8776_CTL_DAC_SW,
+	WM8776_CTL_DAC_ZC_SW,
+	WM8776_CTL_HP_VOL,
+	WM8776_CTL_HP_SW,
+	WM8776_CTL_HP_ZC_SW,
+	WM8776_CTL_AUX_SW,
+	WM8776_CTL_BYPASS_SW,
+	WM8776_CTL_DAC_IZD_SW,
+	WM8776_CTL_PHASE_SW,
+	WM8776_CTL_DEEMPH_SW,
+	WM8776_CTL_ADC_VOL,
+	WM8776_CTL_ADC_SW,
+	WM8776_CTL_INPUT1_SW,
+	WM8776_CTL_INPUT2_SW,
+	WM8776_CTL_INPUT3_SW,
+	WM8776_CTL_INPUT4_SW,
+	WM8776_CTL_INPUT5_SW,
+	WM8776_CTL_AGC_SEL,
+	WM8776_CTL_LIM_THR,
+	WM8776_CTL_LIM_ATK,
+	WM8776_CTL_LIM_DCY,
+	WM8776_CTL_LIM_TRANWIN,
+	WM8776_CTL_LIM_MAXATTN,
+	WM8776_CTL_ALC_TGT,
+	WM8776_CTL_ALC_ATK,
+	WM8776_CTL_ALC_DCY,
+	WM8776_CTL_ALC_MAXGAIN,
+	WM8776_CTL_ALC_MAXATTN,
+	WM8776_CTL_ALC_HLD,
+	WM8776_CTL_NGT_SW,
+	WM8776_CTL_NGT_THR,
+
+	WM8776_CTL_COUNT,
+};
+
+#define WM8776_ENUM_MAX		16
+
+#define WM8776_FLAG_STEREO	(1 << 0)
+#define WM8776_FLAG_VOL_UPDATE	(1 << 1)
+#define WM8776_FLAG_INVERT	(1 << 2)
+#define WM8776_FLAG_LIM		(1 << 3)
+#define WM8776_FLAG_ALC		(1 << 4)
+
+struct snd_wm8776_ctl {
+	const char *name;
+	snd_ctl_elem_type_t type;
+	const char *const enum_names[WM8776_ENUM_MAX];
+	const unsigned int *tlv;
+	u16 reg1, reg2, mask1, mask2, min, max, flags;
+	void (*set)(struct snd_wm8776 *wm, u16 ch1, u16 ch2);
+	void (*get)(struct snd_wm8776 *wm, u16 *ch1, u16 *ch2);
+};
+
+enum snd_wm8776_agc_mode {
+	WM8776_AGC_OFF,
+	WM8776_AGC_LIM,
+	WM8776_AGC_ALC_R,
+	WM8776_AGC_ALC_L,
+	WM8776_AGC_ALC_STEREO
+};
+
+struct snd_wm8776 {
+	struct snd_card *card;
+	struct snd_wm8776_ctl ctl[WM8776_CTL_COUNT];
+	enum snd_wm8776_agc_mode agc_mode;
+	struct snd_wm8776_ops ops;
+	u16 regs[WM8776_REG_COUNT];	/* 9-bit registers */
+};
+
+
+
+void snd_wm8776_init(struct snd_wm8776 *wm);
+void snd_wm8776_resume(struct snd_wm8776 *wm);
+void snd_wm8776_set_dac_if(struct snd_wm8776 *wm, u16 dac);
+void snd_wm8776_set_adc_if(struct snd_wm8776 *wm, u16 adc);
+void snd_wm8776_set_master_mode(struct snd_wm8776 *wm, u16 mode);
+void snd_wm8776_set_power(struct snd_wm8776 *wm, u16 power);
+void snd_wm8776_volume_restore(struct snd_wm8776 *wm);
+int snd_wm8776_build_controls(struct snd_wm8776 *wm);
+
+#endif /* __SOUND_WM8776_H */
diff --git a/sound/pci/ice1712/wtm.c b/sound/pci/ice1712/wtm.c
index e618f78..bcf30a3 100644
--- a/sound/pci/ice1712/wtm.c
+++ b/sound/pci/ice1712/wtm.c
@@ -25,7 +25,6 @@
 
 
 
-#include <linux/io.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
@@ -384,7 +383,7 @@
 /*
  * Control tabs
  */
-static struct snd_kcontrol_new stac9640_controls[] __devinitdata = {
+static struct snd_kcontrol_new stac9640_controls[] = {
 	{
 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 		.name = "Master Playback Switch",
@@ -448,7 +447,7 @@
 
 
 /*INIT*/
-static int __devinit wtm_add_controls(struct snd_ice1712 *ice)
+static int wtm_add_controls(struct snd_ice1712 *ice)
 {
 	unsigned int i;
 	int err;
@@ -462,7 +461,7 @@
 	return 0;
 }
 
-static int __devinit wtm_init(struct snd_ice1712 *ice)
+static int wtm_init(struct snd_ice1712 *ice)
 {
 	static unsigned short stac_inits_prodigy[] = {
 		STAC946X_RESET, 0,
@@ -485,7 +484,7 @@
 }
 
 
-static unsigned char wtm_eeprom[] __devinitdata = {
+static unsigned char wtm_eeprom[] = {
 	0x47,	/*SYSCONF: clock 192KHz, 4ADC, 8DAC */
 	0x80,	/* ACLINK : I2S */
 	0xf8,	/* I2S: vol; 96k, 24bit, 192k */
@@ -503,7 +502,7 @@
 
 
 /*entry point*/
-struct snd_ice1712_card_info snd_vt1724_wtm_cards[] __devinitdata = {
+struct snd_ice1712_card_info snd_vt1724_wtm_cards[] = {
 	{
 		.subvendor = VT1724_SUBDEVICE_WTM,
 		.name = "ESI Waveterminal 192M",
diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c
index ea4b706..3b9be75 100644
--- a/sound/pci/intel8x0.c
+++ b/sound/pci/intel8x0.c
@@ -592,8 +592,8 @@
 	return res;
 }
 
-static void __devinit snd_intel8x0_codec_read_test(struct intel8x0 *chip,
-						   unsigned int codec)
+static void snd_intel8x0_codec_read_test(struct intel8x0 *chip,
+					 unsigned int codec)
 {
 	unsigned int tmp;
 
@@ -1507,8 +1507,8 @@
 	int ac97_idx;
 };
 
-static int __devinit snd_intel8x0_pcm1(struct intel8x0 *chip, int device,
-				       struct ich_pcm_table *rec)
+static int snd_intel8x0_pcm1(struct intel8x0 *chip, int device,
+			     struct ich_pcm_table *rec)
 {
 	struct snd_pcm *pcm;
 	int err;
@@ -1564,7 +1564,7 @@
 	return 0;
 }
 
-static struct ich_pcm_table intel_pcms[] __devinitdata = {
+static struct ich_pcm_table intel_pcms[] = {
 	{
 		.playback_ops = &snd_intel8x0_playback_ops,
 		.capture_ops = &snd_intel8x0_capture_ops,
@@ -1601,7 +1601,7 @@
 	},
 };
 
-static struct ich_pcm_table nforce_pcms[] __devinitdata = {
+static struct ich_pcm_table nforce_pcms[] = {
 	{
 		.playback_ops = &snd_intel8x0_playback_ops,
 		.capture_ops = &snd_intel8x0_capture_ops,
@@ -1624,7 +1624,7 @@
 	},
 };
 
-static struct ich_pcm_table ali_pcms[] __devinitdata = {
+static struct ich_pcm_table ali_pcms[] = {
 	{
 		.playback_ops = &snd_intel8x0_ali_playback_ops,
 		.capture_ops = &snd_intel8x0_ali_capture_ops,
@@ -1656,7 +1656,7 @@
 #endif
 };
 
-static int __devinit snd_intel8x0_pcm(struct intel8x0 *chip)
+static int snd_intel8x0_pcm(struct intel8x0 *chip)
 {
 	int i, tblsize, device, err;
 	struct ich_pcm_table *tbl, *rec;
@@ -1719,7 +1719,7 @@
 	chip->ac97[ac97->num] = NULL;
 }
 
-static struct ac97_pcm ac97_pcm_defs[] __devinitdata = {
+static struct ac97_pcm ac97_pcm_defs[] = {
 	/* front PCM */
 	{
 		.exclusive = 1,
@@ -1789,7 +1789,7 @@
 	},
 };
 
-static struct ac97_quirk ac97_quirks[] __devinitdata = {
+static struct ac97_quirk ac97_quirks[] = {
         {
 		.subvendor = 0x0e11,
 		.subdevice = 0x000e,
@@ -2196,8 +2196,8 @@
 	{ } /* terminator */
 };
 
-static int __devinit snd_intel8x0_mixer(struct intel8x0 *chip, int ac97_clock,
-					const char *quirk_override)
+static int snd_intel8x0_mixer(struct intel8x0 *chip, int ac97_clock,
+			      const char *quirk_override)
 {
 	struct snd_ac97_bus *pbus;
 	struct snd_ac97_template ac97;
@@ -2765,7 +2765,7 @@
 
 #define INTEL8X0_TESTBUF_SIZE	32768	/* enough large for one shot */
 
-static void __devinit intel8x0_measure_ac97_clock(struct intel8x0 *chip)
+static void intel8x0_measure_ac97_clock(struct intel8x0 *chip)
 {
 	struct snd_pcm_substream *subs;
 	struct ichdev *ichdev;
@@ -2883,7 +2883,7 @@
 	snd_ac97_update_power(chip->ac97[0], AC97_PCM_FRONT_DAC_RATE, 0);
 }
 
-static struct snd_pci_quirk intel8x0_clock_list[] __devinitdata = {
+static struct snd_pci_quirk intel8x0_clock_list[] = {
 	SND_PCI_QUIRK(0x0e11, 0x008a, "AD1885", 41000),
 	SND_PCI_QUIRK(0x1028, 0x00be, "AD1885", 44100),
 	SND_PCI_QUIRK(0x1028, 0x0177, "AD1980", 48000),
@@ -2892,7 +2892,7 @@
 	{ }	/* terminator */
 };
 
-static int __devinit intel8x0_in_clock_list(struct intel8x0 *chip)
+static int intel8x0_in_clock_list(struct intel8x0 *chip)
 {
 	struct pci_dev *pci = chip->pci;
 	const struct snd_pci_quirk *wl;
@@ -2941,7 +2941,7 @@
 			chip->ac97_sdin[2]);
 }
 
-static void __devinit snd_intel8x0_proc_init(struct intel8x0 * chip)
+static void snd_intel8x0_proc_init(struct intel8x0 *chip)
 {
 	struct snd_info_entry *entry;
 
@@ -2970,7 +2970,7 @@
 	ICH_PCR, ICH_SCR, ICH_SIS_TCR
 };
 
-static int __devinit snd_intel8x0_inside_vm(struct pci_dev *pci)
+static int snd_intel8x0_inside_vm(struct pci_dev *pci)
 {
 	int result  = inside_vm;
 	char *msg   = NULL;
@@ -3009,10 +3009,10 @@
 	return result;
 }
 
-static int __devinit snd_intel8x0_create(struct snd_card *card,
-					 struct pci_dev *pci,
-					 unsigned long device_type,
-					 struct intel8x0 ** r_intel8x0)
+static int snd_intel8x0_create(struct snd_card *card,
+			       struct pci_dev *pci,
+			       unsigned long device_type,
+			       struct intel8x0 **r_intel8x0)
 {
 	struct intel8x0 *chip;
 	int err;
@@ -3227,7 +3227,7 @@
 static struct shortname_table {
 	unsigned int id;
 	const char *s;
-} shortnames[] __devinitdata = {
+} shortnames[] = {
 	{ PCI_DEVICE_ID_INTEL_82801AA_5, "Intel 82801AA-ICH" },
 	{ PCI_DEVICE_ID_INTEL_82801AB_5, "Intel 82901AB-ICH0" },
 	{ PCI_DEVICE_ID_INTEL_82801BA_4, "Intel 82801BA-ICH2" },
@@ -3253,13 +3253,13 @@
 	{ 0, NULL },
 };
 
-static struct snd_pci_quirk spdif_aclink_defaults[] __devinitdata = {
+static struct snd_pci_quirk spdif_aclink_defaults[] = {
 	SND_PCI_QUIRK(0x147b, 0x1c1a, "ASUS KN8", 1),
 	{ } /* end */
 };
 
 /* look up white/black list for SPDIF over ac-link */
-static int __devinit check_default_spdif_aclink(struct pci_dev *pci)
+static int check_default_spdif_aclink(struct pci_dev *pci)
 {
 	const struct snd_pci_quirk *w;
 
@@ -3276,8 +3276,8 @@
 	return 0;
 }
 
-static int __devinit snd_intel8x0_probe(struct pci_dev *pci,
-					const struct pci_device_id *pci_id)
+static int snd_intel8x0_probe(struct pci_dev *pci,
+			      const struct pci_device_id *pci_id)
 {
 	struct snd_card *card;
 	struct intel8x0 *chip;
@@ -3359,7 +3359,7 @@
 	return 0;
 }
 
-static void __devexit snd_intel8x0_remove(struct pci_dev *pci)
+static void snd_intel8x0_remove(struct pci_dev *pci)
 {
 	snd_card_free(pci_get_drvdata(pci));
 	pci_set_drvdata(pci, NULL);
@@ -3369,7 +3369,7 @@
 	.name = KBUILD_MODNAME,
 	.id_table = snd_intel8x0_ids,
 	.probe = snd_intel8x0_probe,
-	.remove = __devexit_p(snd_intel8x0_remove),
+	.remove = snd_intel8x0_remove,
 	.driver = {
 		.pm = INTEL8X0_PM_OPS,
 	},
diff --git a/sound/pci/intel8x0m.c b/sound/pci/intel8x0m.c
index 4d55173..fea09e8 100644
--- a/sound/pci/intel8x0m.c
+++ b/sound/pci/intel8x0m.c
@@ -710,8 +710,8 @@
 	int ac97_idx;
 };
 
-static int __devinit snd_intel8x0m_pcm1(struct intel8x0m *chip, int device,
-				       struct ich_pcm_table *rec)
+static int snd_intel8x0m_pcm1(struct intel8x0m *chip, int device,
+			      struct ich_pcm_table *rec)
 {
 	struct snd_pcm *pcm;
 	int err;
@@ -749,7 +749,7 @@
 	return 0;
 }
 
-static struct ich_pcm_table intel_pcms[] __devinitdata = {
+static struct ich_pcm_table intel_pcms[] = {
 	{
 		.suffix = "Modem",
 		.playback_ops = &snd_intel8x0m_playback_ops,
@@ -759,7 +759,7 @@
 	},
 };
 
-static int __devinit snd_intel8x0m_pcm(struct intel8x0m *chip)
+static int snd_intel8x0m_pcm(struct intel8x0m *chip)
 {
 	int i, tblsize, device, err;
 	struct ich_pcm_table *tbl, *rec;
@@ -819,7 +819,7 @@
 }
 
 
-static int __devinit snd_intel8x0m_mixer(struct intel8x0m *chip, int ac97_clock)
+static int snd_intel8x0m_mixer(struct intel8x0m *chip, int ac97_clock)
 {
 	struct snd_ac97_bus *pbus;
 	struct snd_ac97_template ac97;
@@ -1090,7 +1090,7 @@
 			(tmp & (ICH_PCR | ICH_SCR | ICH_TCR)) == 0 ? " none" : "");
 }
 
-static void __devinit snd_intel8x0m_proc_init(struct intel8x0m * chip)
+static void snd_intel8x0m_proc_init(struct intel8x0m *chip)
 {
 	struct snd_info_entry *entry;
 
@@ -1113,10 +1113,10 @@
 	unsigned int offset;
 };
 
-static int __devinit snd_intel8x0m_create(struct snd_card *card,
-					 struct pci_dev *pci,
-					 unsigned long device_type,
-					 struct intel8x0m **r_intel8x0m)
+static int snd_intel8x0m_create(struct snd_card *card,
+				struct pci_dev *pci,
+				unsigned long device_type,
+				struct intel8x0m **r_intel8x0m)
 {
 	struct intel8x0m *chip;
 	int err;
@@ -1252,7 +1252,7 @@
 static struct shortname_table {
 	unsigned int id;
 	const char *s;
-} shortnames[] __devinitdata = {
+} shortnames[] = {
 	{ PCI_DEVICE_ID_INTEL_82801AA_6, "Intel 82801AA-ICH" },
 	{ PCI_DEVICE_ID_INTEL_82801AB_6, "Intel 82901AB-ICH0" },
 	{ PCI_DEVICE_ID_INTEL_82801BA_6, "Intel 82801BA-ICH2" },
@@ -1275,8 +1275,8 @@
 	{ 0 },
 };
 
-static int __devinit snd_intel8x0m_probe(struct pci_dev *pci,
-					const struct pci_device_id *pci_id)
+static int snd_intel8x0m_probe(struct pci_dev *pci,
+			       const struct pci_device_id *pci_id)
 {
 	struct snd_card *card;
 	struct intel8x0m *chip;
@@ -1325,7 +1325,7 @@
 	return 0;
 }
 
-static void __devexit snd_intel8x0m_remove(struct pci_dev *pci)
+static void snd_intel8x0m_remove(struct pci_dev *pci)
 {
 	snd_card_free(pci_get_drvdata(pci));
 	pci_set_drvdata(pci, NULL);
@@ -1335,7 +1335,7 @@
 	.name = KBUILD_MODNAME,
 	.id_table = snd_intel8x0m_ids,
 	.probe = snd_intel8x0m_probe,
-	.remove = __devexit_p(snd_intel8x0m_remove),
+	.remove = snd_intel8x0m_remove,
 	.driver = {
 		.pm = INTEL8X0M_PM_OPS,
 	},
diff --git a/sound/pci/korg1212/korg1212.c b/sound/pci/korg1212/korg1212.c
index 8a67ce95..43b4228 100644
--- a/sound/pci/korg1212/korg1212.c
+++ b/sound/pci/korg1212/korg1212.c
@@ -2083,7 +2083,7 @@
         snd_iprintf(buffer, "    Error count: %ld\n", korg1212->totalerrorcnt);
 }
 
-static void __devinit snd_korg1212_proc_init(struct snd_korg1212 *korg1212)
+static void snd_korg1212_proc_init(struct snd_korg1212 *korg1212)
 {
 	struct snd_info_entry *entry;
 
@@ -2154,8 +2154,8 @@
 	return snd_korg1212_free(korg1212);
 }
 
-static int __devinit snd_korg1212_create(struct snd_card *card, struct pci_dev *pci,
-                                         struct snd_korg1212 ** rchip)
+static int snd_korg1212_create(struct snd_card *card, struct pci_dev *pci,
+			       struct snd_korg1212 **rchip)
 
 {
         int err, rc;
@@ -2429,7 +2429,7 @@
  * Card initialisation
  */
 
-static int __devinit
+static int
 snd_korg1212_probe(struct pci_dev *pci,
 		const struct pci_device_id *pci_id)
 {
@@ -2470,7 +2470,7 @@
 	return 0;
 }
 
-static void __devexit snd_korg1212_remove(struct pci_dev *pci)
+static void snd_korg1212_remove(struct pci_dev *pci)
 {
 	snd_card_free(pci_get_drvdata(pci));
 	pci_set_drvdata(pci, NULL);
@@ -2480,7 +2480,7 @@
 	.name = KBUILD_MODNAME,
 	.id_table = snd_korg1212_ids,
 	.probe = snd_korg1212_probe,
-	.remove = __devexit_p(snd_korg1212_remove),
+	.remove = snd_korg1212_remove,
 };
 
 module_pci_driver(korg1212_driver);
diff --git a/sound/pci/lola/lola.c b/sound/pci/lola/lola.c
index ac15166..322b638 100644
--- a/sound/pci/lola/lola.c
+++ b/sound/pci/lola/lola.c
@@ -445,7 +445,7 @@
 	lola_setup_all_analog_gains(chip, PLAY, false); /* output, update */
 }
 
-static int __devinit lola_parse_tree(struct lola *chip)
+static int lola_parse_tree(struct lola *chip)
 {
 	unsigned int val;
 	int nid, err;
@@ -568,8 +568,8 @@
 	return 0;
 }
 
-static int __devinit lola_create(struct snd_card *card, struct pci_dev *pci,
-				 int dev, struct lola **rchip)
+static int lola_create(struct snd_card *card, struct pci_dev *pci,
+		       int dev, struct lola **rchip)
 {
 	struct lola *chip;
 	int err;
@@ -702,8 +702,8 @@
 	return err;
 }
 
-static int __devinit lola_probe(struct pci_dev *pci,
-				const struct pci_device_id *pci_id)
+static int lola_probe(struct pci_dev *pci,
+		      const struct pci_device_id *pci_id)
 {
 	static int dev;
 	struct snd_card *card;
@@ -756,7 +756,7 @@
 	return err;
 }
 
-static void __devexit lola_remove(struct pci_dev *pci)
+static void lola_remove(struct pci_dev *pci)
 {
 	snd_card_free(pci_get_drvdata(pci));
 	pci_set_drvdata(pci, NULL);
@@ -774,7 +774,7 @@
 	.name = KBUILD_MODNAME,
 	.id_table = lola_ids,
 	.probe = lola_probe,
-	.remove = __devexit_p(lola_remove),
+	.remove = lola_remove,
 };
 
 module_pci_driver(lola_driver);
diff --git a/sound/pci/lola/lola_clock.c b/sound/pci/lola/lola_clock.c
index 72f8ef0..eb1d6b9 100644
--- a/sound/pci/lola/lola_clock.c
+++ b/sound/pci/lola/lola_clock.c
@@ -120,7 +120,7 @@
  * Clock widget handling
  */
 
-int __devinit lola_init_clock_widget(struct lola *chip, int nid)
+int lola_init_clock_widget(struct lola *chip, int nid)
 {
 	unsigned int val;
 	int i, j, nitems, nb_verbs, idx, idx_list;
diff --git a/sound/pci/lola/lola_mixer.c b/sound/pci/lola/lola_mixer.c
index 6b8d648..52c8d6b 100644
--- a/sound/pci/lola/lola_mixer.c
+++ b/sound/pci/lola/lola_mixer.c
@@ -28,8 +28,8 @@
 #include <sound/tlv.h>
 #include "lola.h"
 
-static int __devinit lola_init_pin(struct lola *chip, struct lola_pin *pin,
-				   int dir, int nid)
+static int lola_init_pin(struct lola *chip, struct lola_pin *pin,
+			 int dir, int nid)
 {
 	unsigned int val;
 	int err;
@@ -91,7 +91,7 @@
 	return 0;
 }
 
-int __devinit lola_init_pins(struct lola *chip, int dir, int *nidp)
+int lola_init_pins(struct lola *chip, int dir, int *nidp)
 {
 	int i, err, nid;
 	nid = *nidp;
@@ -112,7 +112,7 @@
 		vfree(chip->mixer.array_saved);
 }
 
-int __devinit lola_init_mixer_widget(struct lola *chip, int nid)
+int lola_init_mixer_widget(struct lola *chip, int nid)
 {
 	unsigned int val;
 	int err;
@@ -579,7 +579,7 @@
 	return 0;
 }
 
-static struct snd_kcontrol_new lola_analog_mixer __devinitdata = {
+static struct snd_kcontrol_new lola_analog_mixer = {
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
 		   SNDRV_CTL_ELEM_ACCESS_TLV_READ |
@@ -590,7 +590,7 @@
 	.tlv.c = lola_analog_vol_tlv,
 };
 
-static int __devinit create_analog_mixer(struct lola *chip, int dir, char *name)
+static int create_analog_mixer(struct lola *chip, int dir, char *name)
 {
 	if (!chip->pin[dir].num_pins)
 		return 0;
@@ -644,7 +644,7 @@
 	return lola_set_src_config(chip, mask, true);
 }
 
-static struct snd_kcontrol_new lola_input_src_mixer __devinitdata = {
+static struct snd_kcontrol_new lola_input_src_mixer = {
 	.name = "Digital SRC Capture Switch",
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.info = lola_input_src_info,
@@ -656,7 +656,7 @@
  * Lola16161 or Lola881 can have Hardware sample rate converters
  * on its digital input pins
  */
-static int __devinit create_input_src_mixer(struct lola *chip)
+static int create_input_src_mixer(struct lola *chip)
 {
 	if (!chip->input_src_caps_mask)
 		return 0;
@@ -726,7 +726,7 @@
 /* raw value: 0 = -84dB, 336 = 0dB, 408=18dB, incremented 1 for mute */
 static const DECLARE_TLV_DB_SCALE(lola_src_gain_tlv, -8425, 25, 1);
 
-static struct snd_kcontrol_new lola_src_gain_mixer __devinitdata = {
+static struct snd_kcontrol_new lola_src_gain_mixer = {
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
 		   SNDRV_CTL_ELEM_ACCESS_TLV_READ),
@@ -736,8 +736,8 @@
 	.tlv.p = lola_src_gain_tlv,
 };
 
-static int __devinit create_src_gain_mixer(struct lola *chip,
-					   int num, int ofs, char *name)
+static int create_src_gain_mixer(struct lola *chip,
+				 int num, int ofs, char *name)
 {
 	lola_src_gain_mixer.name = name;
 	lola_src_gain_mixer.private_value = ofs + (num << 8);
@@ -813,7 +813,7 @@
 
 static const DECLARE_TLV_DB_SCALE(lola_dest_gain_tlv, -8425, 25, 1);
 
-static struct snd_kcontrol_new lola_dest_gain_mixer __devinitdata = {
+static struct snd_kcontrol_new lola_dest_gain_mixer = {
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
 		   SNDRV_CTL_ELEM_ACCESS_TLV_READ),
@@ -823,9 +823,9 @@
 	.tlv.p = lola_dest_gain_tlv,
 };
 
-static int __devinit create_dest_gain_mixer(struct lola *chip,
-					    int src_num, int src_ofs,
-					    int num, int ofs, char *name)
+static int create_dest_gain_mixer(struct lola *chip,
+				  int src_num, int src_ofs,
+				  int num, int ofs, char *name)
 {
 	lola_dest_gain_mixer.count = num;
 	lola_dest_gain_mixer.name = name;
@@ -838,7 +838,7 @@
 
 /*
  */
-int __devinit lola_create_mixer(struct lola *chip)
+int lola_create_mixer(struct lola *chip)
 {
 	int err;
 
diff --git a/sound/pci/lola/lola_pcm.c b/sound/pci/lola/lola_pcm.c
index c44db68..5ea85e8 100644
--- a/sound/pci/lola/lola_pcm.c
+++ b/sound/pci/lola/lola_pcm.c
@@ -597,7 +597,7 @@
 	.page = snd_pcm_sgbuf_ops_page,
 };
 
-int __devinit lola_create_pcm(struct lola *chip)
+int lola_create_pcm(struct lola *chip)
 {
 	struct snd_pcm *pcm;
 	int i, err;
@@ -690,7 +690,7 @@
 	return 0;
 }
 
-int __devinit lola_init_pcm(struct lola *chip, int dir, int *nidp)
+int lola_init_pcm(struct lola *chip, int dir, int *nidp)
 {
 	struct lola_pcm *pcm = &chip->pcm[dir];
 	int i, nid, err;
diff --git a/sound/pci/lola/lola_proc.c b/sound/pci/lola/lola_proc.c
index 9d7daf8..04df83d 100644
--- a/sound/pci/lola/lola_proc.c
+++ b/sound/pci/lola/lola_proc.c
@@ -206,7 +206,7 @@
 	}
 }
 
-void __devinit lola_proc_debug_new(struct lola *chip)
+void lola_proc_debug_new(struct lola *chip)
 {
 	struct snd_info_entry *entry;
 
diff --git a/sound/pci/lx6464es/lx6464es.c b/sound/pci/lx6464es/lx6464es.c
index 5579b08..298bc9b 100644
--- a/sound/pci/lx6464es/lx6464es.c
+++ b/sound/pci/lx6464es/lx6464es.c
@@ -578,7 +578,7 @@
 }
 
 /* reset the dsp during initialization */
-static int __devinit lx_init_xilinx_reset(struct lx6464es *chip)
+static int lx_init_xilinx_reset(struct lx6464es *chip)
 {
 	int i;
 	u32 plx_reg = lx_plx_reg_read(chip, ePLX_CHIPSC);
@@ -620,7 +620,7 @@
 	return 0;
 }
 
-static int __devinit lx_init_xilinx_test(struct lx6464es *chip)
+static int lx_init_xilinx_test(struct lx6464es *chip)
 {
 	u32 reg;
 
@@ -650,7 +650,7 @@
 }
 
 /* initialize ethersound */
-static int __devinit lx_init_ethersound_config(struct lx6464es *chip)
+static int lx_init_ethersound_config(struct lx6464es *chip)
 {
 	int i;
 	u32 orig_conf_es = lx_dsp_reg_read(chip, eReg_CONFES);
@@ -690,7 +690,7 @@
 	return 0;
 }
 
-static int __devinit lx_init_get_version_features(struct lx6464es *chip)
+static int lx_init_get_version_features(struct lx6464es *chip)
 {
 	u32 dsp_version;
 
@@ -759,7 +759,7 @@
 }
 
 /* initialize and test the xilinx dsp chip */
-static int __devinit lx_init_dsp(struct lx6464es *chip)
+static int lx_init_dsp(struct lx6464es *chip)
 {
 	int err;
 	int i;
@@ -835,7 +835,7 @@
 	.pointer   = lx_pcm_stream_pointer,
 };
 
-static int __devinit lx_pcm_create(struct lx6464es *chip)
+static int lx_pcm_create(struct lx6464es *chip)
 {
 	int err;
 	struct snd_pcm *pcm;
@@ -907,7 +907,7 @@
 	return changed;
 }
 
-static struct snd_kcontrol_new lx_control_playback_switch __devinitdata = {
+static struct snd_kcontrol_new lx_control_playback_switch = {
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name = "PCM Playback Switch",
 	.index = 0,
@@ -954,7 +954,7 @@
 	snd_iprintf(buffer, "\n");
 }
 
-static int __devinit lx_proc_create(struct snd_card *card, struct lx6464es *chip)
+static int lx_proc_create(struct snd_card *card, struct lx6464es *chip)
 {
 	struct snd_info_entry *entry;
 	int err = snd_card_proc_new(card, "levels", &entry);
@@ -966,9 +966,9 @@
 }
 
 
-static int __devinit snd_lx6464es_create(struct snd_card *card,
-					 struct pci_dev *pci,
-					 struct lx6464es **rchip)
+static int snd_lx6464es_create(struct snd_card *card,
+			       struct pci_dev *pci,
+			       struct lx6464es **rchip)
 {
 	struct lx6464es *chip;
 	int err;
@@ -1082,8 +1082,8 @@
 	return err;
 }
 
-static int __devinit snd_lx6464es_probe(struct pci_dev *pci,
-					const struct pci_device_id *pci_id)
+static int snd_lx6464es_probe(struct pci_dev *pci,
+			      const struct pci_device_id *pci_id)
 {
 	static int dev;
 	struct snd_card *card;
@@ -1136,7 +1136,7 @@
 
 }
 
-static void __devexit snd_lx6464es_remove(struct pci_dev *pci)
+static void snd_lx6464es_remove(struct pci_dev *pci)
 {
 	snd_card_free(pci_get_drvdata(pci));
 	pci_set_drvdata(pci, NULL);
@@ -1147,7 +1147,7 @@
 	.name =     KBUILD_MODNAME,
 	.id_table = snd_lx6464es_ids,
 	.probe =    snd_lx6464es_probe,
-	.remove = __devexit_p(snd_lx6464es_remove),
+	.remove = snd_lx6464es_remove,
 };
 
 module_pci_driver(lx6464es_driver);
diff --git a/sound/pci/lx6464es/lx_core.c b/sound/pci/lx6464es/lx_core.c
index 8c3e7fc..633c860 100644
--- a/sound/pci/lx6464es/lx_core.c
+++ b/sound/pci/lx6464es/lx_core.c
@@ -385,7 +385,7 @@
 
 
 /* low-level dsp access */
-int __devinit lx_dsp_get_version(struct lx6464es *chip, u32 *rdsp_version)
+int lx_dsp_get_version(struct lx6464es *chip, u32 *rdsp_version)
 {
 	u16 ret;
 	unsigned long flags;
diff --git a/sound/pci/lx6464es/lx_core.h b/sound/pci/lx6464es/lx_core.h
index 4d7ff79..5ec5e04 100644
--- a/sound/pci/lx6464es/lx_core.h
+++ b/sound/pci/lx6464es/lx_core.h
@@ -109,7 +109,7 @@
 
 
 /* low-level dsp access */
-int __devinit lx_dsp_get_version(struct lx6464es *chip, u32 *rdsp_version);
+int lx_dsp_get_version(struct lx6464es *chip, u32 *rdsp_version);
 int lx_dsp_get_clock_frequency(struct lx6464es *chip, u32 *rfreq);
 int lx_dsp_set_granularity(struct lx6464es *chip, u32 gran);
 int lx_dsp_read_async_events(struct lx6464es *chip, u32 *data);
diff --git a/sound/pci/maestro3.c b/sound/pci/maestro3.c
index eb3cd3a..9387533 100644
--- a/sound/pci/maestro3.c
+++ b/sound/pci/maestro3.c
@@ -822,7 +822,7 @@
 
 MODULE_DEVICE_TABLE(pci, snd_m3_ids);
 
-static struct snd_pci_quirk m3_amp_quirk_list[] __devinitdata = {
+static struct snd_pci_quirk m3_amp_quirk_list[] = {
 	SND_PCI_QUIRK(0x0E11, 0x0094, "Compaq Evo N600c", 0x0c),
 	SND_PCI_QUIRK(0x10f7, 0x833e, "Panasonic CF-28", 0x0d),
 	SND_PCI_QUIRK(0x10f7, 0x833d, "Panasonic CF-72", 0x0d),
@@ -831,7 +831,7 @@
 	{ } /* END */
 };
 
-static struct snd_pci_quirk m3_irda_quirk_list[] __devinitdata = {
+static struct snd_pci_quirk m3_irda_quirk_list[] = {
 	SND_PCI_QUIRK(0x1028, 0x00b0, "Dell Inspiron 4000", 1),
 	SND_PCI_QUIRK(0x1028, 0x00a4, "Dell Inspiron 8000", 1),
 	SND_PCI_QUIRK(0x1028, 0x00e6, "Dell Inspiron 8100", 1),
@@ -839,7 +839,7 @@
 };
 
 /* hardware volume quirks */
-static struct snd_pci_quirk m3_hv_quirk_list[] __devinitdata = {
+static struct snd_pci_quirk m3_hv_quirk_list[] = {
 	/* Allegro chips */
 	SND_PCI_QUIRK(0x0E11, 0x002E, NULL, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD),
 	SND_PCI_QUIRK(0x0E11, 0x0094, NULL, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD),
@@ -917,7 +917,7 @@
 };
 
 /* HP Omnibook quirks */
-static struct snd_pci_quirk m3_omnibook_quirk_list[] __devinitdata = {
+static struct snd_pci_quirk m3_omnibook_quirk_list[] = {
 	SND_PCI_QUIRK_ID(0x103c, 0x0010), /* HP OmniBook 6000 */
 	SND_PCI_QUIRK_ID(0x103c, 0x0011), /* HP OmniBook 500 */
 	{ } /* END */
@@ -1856,7 +1856,7 @@
 	.pointer =	snd_m3_pcm_pointer,
 };
 
-static int __devinit
+static int
 snd_m3_pcm(struct snd_m3 * chip, int device)
 {
 	struct snd_pcm *pcm;
@@ -2031,7 +2031,7 @@
 #endif
 }
 
-static int __devinit snd_m3_mixer(struct snd_m3 *chip)
+static int snd_m3_mixer(struct snd_m3 *chip)
 {
 	struct snd_ac97_bus *pbus;
 	struct snd_ac97_template ac97;
@@ -2173,7 +2173,7 @@
 }
 
 
-static int __devinit snd_m3_assp_client_init(struct snd_m3 *chip, struct m3_dma *s, int index)
+static int snd_m3_assp_client_init(struct snd_m3 *chip, struct m3_dma *s, int index)
 {
 	int data_bytes = 2 * ( MINISRC_TMP_BUFFER_SIZE / 2 + 
 			       MINISRC_IN_BUFFER_SIZE / 2 +
@@ -2488,7 +2488,7 @@
 #endif /* CONFIG_PM_SLEEP */
 
 #ifdef CONFIG_SND_MAESTRO3_INPUT
-static int __devinit snd_m3_input_register(struct snd_m3 *chip)
+static int snd_m3_input_register(struct snd_m3 *chip)
 {
 	struct input_dev *input_dev;
 	int err;
@@ -2532,7 +2532,7 @@
 	return snd_m3_free(chip);
 }
 
-static int __devinit
+static int
 snd_m3_create(struct snd_card *card, struct pci_dev *pci,
 	      int enable_amp,
 	      int amp_gpio,
@@ -2700,7 +2700,7 @@
 
 /*
  */
-static int __devinit
+static int
 snd_m3_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
 {
 	static int dev;
@@ -2770,7 +2770,7 @@
 	return 0;
 }
 
-static void __devexit snd_m3_remove(struct pci_dev *pci)
+static void snd_m3_remove(struct pci_dev *pci)
 {
 	snd_card_free(pci_get_drvdata(pci));
 	pci_set_drvdata(pci, NULL);
@@ -2780,7 +2780,7 @@
 	.name = KBUILD_MODNAME,
 	.id_table = snd_m3_ids,
 	.probe = snd_m3_probe,
-	.remove = __devexit_p(snd_m3_remove),
+	.remove = snd_m3_remove,
 	.driver = {
 		.pm = M3_PM_OPS,
 	},
diff --git a/sound/pci/mixart/mixart.c b/sound/pci/mixart/mixart.c
index 0762610..01f7f37 100644
--- a/sound/pci/mixart/mixart.c
+++ b/sound/pci/mixart/mixart.c
@@ -1004,7 +1004,7 @@
 
 /*
  */
-static int __devinit snd_mixart_create(struct mixart_mgr *mgr, struct snd_card *card, int idx)
+static int snd_mixart_create(struct mixart_mgr *mgr, struct snd_card *card, int idx)
 {
 	int err;
 	struct snd_mixart *chip;
@@ -1180,7 +1180,7 @@
 	} /* endif elf loaded */
 }
 
-static void __devinit snd_mixart_proc_init(struct snd_mixart *chip)
+static void snd_mixart_proc_init(struct snd_mixart *chip)
 {
 	struct snd_info_entry *entry;
 
@@ -1209,8 +1209,8 @@
 /*
  *    probe function - creates the card manager
  */
-static int __devinit snd_mixart_probe(struct pci_dev *pci,
-				      const struct pci_device_id *pci_id)
+static int snd_mixart_probe(struct pci_dev *pci,
+			    const struct pci_device_id *pci_id)
 {
 	static int dev;
 	struct mixart_mgr *mgr;
@@ -1374,7 +1374,7 @@
 	return 0;
 }
 
-static void __devexit snd_mixart_remove(struct pci_dev *pci)
+static void snd_mixart_remove(struct pci_dev *pci)
 {
 	snd_mixart_free(pci_get_drvdata(pci));
 	pci_set_drvdata(pci, NULL);
@@ -1384,7 +1384,7 @@
 	.name = KBUILD_MODNAME,
 	.id_table = snd_mixart_ids,
 	.probe = snd_mixart_probe,
-	.remove = __devexit_p(snd_mixart_remove),
+	.remove = snd_mixart_remove,
 };
 
 module_pci_driver(mixart_driver);
diff --git a/sound/pci/mixart/mixart_hwdep.c b/sound/pci/mixart/mixart_hwdep.c
index e0f4d875..ece1f83 100644
--- a/sound/pci/mixart/mixart_hwdep.c
+++ b/sound/pci/mixart/mixart_hwdep.c
@@ -546,14 +546,6 @@
 }
 
 
-#if defined(CONFIG_FW_LOADER) || defined(CONFIG_FW_LOADER_MODULE)
-#if !defined(CONFIG_USE_MIXARTLOADER) && !defined(CONFIG_SND_MIXART) /* built-in kernel */
-#define SND_MIXART_FW_LOADER	/* use the standard firmware loader */
-#endif
-#endif
-
-#ifdef SND_MIXART_FW_LOADER
-
 int snd_mixart_setup_firmware(struct mixart_mgr *mgr)
 {
 	static char *fw_files[3] = {
@@ -583,71 +575,3 @@
 MODULE_FIRMWARE("mixart/miXart8.xlx");
 MODULE_FIRMWARE("mixart/miXart8.elf");
 MODULE_FIRMWARE("mixart/miXart8AES.xlx");
-
-#else /* old style firmware loading */
-
-/* miXart hwdep interface id string */
-#define SND_MIXART_HWDEP_ID       "miXart Loader"
-
-static int mixart_hwdep_dsp_status(struct snd_hwdep *hw,
-				   struct snd_hwdep_dsp_status *info)
-{
-	struct mixart_mgr *mgr = hw->private_data;
-
-	strcpy(info->id, "miXart");
-        info->num_dsps = MIXART_HARDW_FILES_MAX_INDEX;
-
-	if (mgr->dsp_loaded & (1 <<  MIXART_MOTHERBOARD_ELF_INDEX))
-		info->chip_ready = 1;
-
-	info->version = MIXART_DRIVER_VERSION;
-	return 0;
-}
-
-static int mixart_hwdep_dsp_load(struct snd_hwdep *hw,
-				 struct snd_hwdep_dsp_image *dsp)
-{
-	struct mixart_mgr* mgr = hw->private_data;
-	struct firmware fw;
-	int err;
-
-	fw.size = dsp->length;
-	fw.data = vmalloc(dsp->length);
-	if (! fw.data) {
-		snd_printk(KERN_ERR "miXart: cannot allocate image size %d\n",
-			   (int)dsp->length);
-		return -ENOMEM;
-	}
-	if (copy_from_user((void *) fw.data, dsp->image, dsp->length)) {
-		vfree(fw.data);
-		return -EFAULT;
-	}
-	err = mixart_dsp_load(mgr, dsp->index, &fw);
-	vfree(fw.data);
-	if (err < 0)
-		return err;
-	mgr->dsp_loaded |= 1 << dsp->index;
-	return err;
-}
-
-int snd_mixart_setup_firmware(struct mixart_mgr *mgr)
-{
-	int err;
-	struct snd_hwdep *hw;
-
-	/* only create hwdep interface for first cardX (see "index" module parameter)*/
-	if ((err = snd_hwdep_new(mgr->chip[0]->card, SND_MIXART_HWDEP_ID, 0, &hw)) < 0)
-		return err;
-
-	hw->iface = SNDRV_HWDEP_IFACE_MIXART;
-	hw->private_data = mgr;
-	hw->ops.dsp_status = mixart_hwdep_dsp_status;
-	hw->ops.dsp_load = mixart_hwdep_dsp_load;
-	hw->exclusive = 1;
-	sprintf(hw->name,  SND_MIXART_HWDEP_ID);
-	mgr->dsp_loaded = 0;
-
-	return snd_card_register(mgr->chip[0]->card);
-}
-
-#endif /* SND_MIXART_FW_LOADER */
diff --git a/sound/pci/nm256/nm256.c b/sound/pci/nm256/nm256.c
index e80e9a1..563a193 100644
--- a/sound/pci/nm256/nm256.c
+++ b/sound/pci/nm256/nm256.c
@@ -928,7 +928,7 @@
 	.mmap =		snd_pcm_lib_mmap_iomem,
 };
 
-static int __devinit
+static int
 snd_nm256_pcm(struct nm256 *chip, int device)
 {
 	struct snd_pcm *pcm;
@@ -1295,7 +1295,7 @@
 }
 
 /* create an ac97 mixer interface */
-static int __devinit
+static int
 snd_nm256_mixer(struct nm256 *chip)
 {
 	struct snd_ac97_bus *pbus;
@@ -1336,7 +1336,7 @@
  * RAM.
  */
 
-static int __devinit
+static int
 snd_nm256_peek_for_sig(struct nm256 *chip)
 {
 	/* The signature is located 1K below the end of video RAM.  */
@@ -1472,7 +1472,7 @@
 	return snd_nm256_free(chip);
 }
 
-static int __devinit
+static int
 snd_nm256_create(struct snd_card *card, struct pci_dev *pci,
 		 struct nm256 **chip_ret)
 {
@@ -1639,7 +1639,7 @@
 
 enum { NM_BLACKLISTED, NM_RESET_WORKAROUND, NM_RESET_WORKAROUND_2 };
 
-static struct snd_pci_quirk nm256_quirks[] __devinitdata = {
+static struct snd_pci_quirk nm256_quirks[] = {
 	/* HP omnibook 4150 has cs4232 codec internally */
 	SND_PCI_QUIRK(0x103c, 0x0007, "HP omnibook 4150", NM_BLACKLISTED),
 	/* Reset workarounds to avoid lock-ups */
@@ -1650,8 +1650,8 @@
 };
 
 
-static int __devinit snd_nm256_probe(struct pci_dev *pci,
-				     const struct pci_device_id *pci_id)
+static int snd_nm256_probe(struct pci_dev *pci,
+			   const struct pci_device_id *pci_id)
 {
 	struct snd_card *card;
 	struct nm256 *chip;
@@ -1742,7 +1742,7 @@
 	return 0;
 }
 
-static void __devexit snd_nm256_remove(struct pci_dev *pci)
+static void snd_nm256_remove(struct pci_dev *pci)
 {
 	snd_card_free(pci_get_drvdata(pci));
 	pci_set_drvdata(pci, NULL);
@@ -1753,7 +1753,7 @@
 	.name = KBUILD_MODNAME,
 	.id_table = snd_nm256_ids,
 	.probe = snd_nm256_probe,
-	.remove = __devexit_p(snd_nm256_remove),
+	.remove = snd_nm256_remove,
 	.driver = {
 		.pm = NM256_PM_OPS,
 	},
diff --git a/sound/pci/oxygen/oxygen.c b/sound/pci/oxygen/oxygen.c
index 2becae1..ada6c25 100644
--- a/sound/pci/oxygen/oxygen.c
+++ b/sound/pci/oxygen/oxygen.c
@@ -756,8 +756,8 @@
 	.adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
 };
 
-static int __devinit get_oxygen_model(struct oxygen *chip,
-				      const struct pci_device_id *id)
+static int get_oxygen_model(struct oxygen *chip,
+			    const struct pci_device_id *id)
 {
 	static const char *const names[] = {
 		[MODEL_MERIDIAN]	= "AuzenTech X-Meridian",
@@ -848,8 +848,8 @@
 	return 0;
 }
 
-static int __devinit generic_oxygen_probe(struct pci_dev *pci,
-					  const struct pci_device_id *pci_id)
+static int generic_oxygen_probe(struct pci_dev *pci,
+				const struct pci_device_id *pci_id)
 {
 	static int dev;
 	int err;
@@ -871,7 +871,7 @@
 	.name = KBUILD_MODNAME,
 	.id_table = oxygen_ids,
 	.probe = generic_oxygen_probe,
-	.remove = __devexit_p(oxygen_pci_remove),
+	.remove = oxygen_pci_remove,
 #ifdef CONFIG_PM_SLEEP
 	.driver = {
 		.pm = &oxygen_pci_pm,
diff --git a/sound/pci/oxygen/virtuoso.c b/sound/pci/oxygen/virtuoso.c
index 3d71423..64b9fda 100644
--- a/sound/pci/oxygen/virtuoso.c
+++ b/sound/pci/oxygen/virtuoso.c
@@ -52,13 +52,14 @@
 	{ OXYGEN_PCI_SUBID(0x1043, 0x835d) },
 	{ OXYGEN_PCI_SUBID(0x1043, 0x835e) },
 	{ OXYGEN_PCI_SUBID(0x1043, 0x838e) },
+	{ OXYGEN_PCI_SUBID(0x1043, 0x8522) },
 	{ OXYGEN_PCI_SUBID_BROKEN_EEPROM },
 	{ }
 };
 MODULE_DEVICE_TABLE(pci, xonar_ids);
 
-static int __devinit get_xonar_model(struct oxygen *chip,
-				     const struct pci_device_id *id)
+static int get_xonar_model(struct oxygen *chip,
+			   const struct pci_device_id *id)
 {
 	if (get_xonar_pcm179x_model(chip, id) >= 0)
 		return 0;
@@ -69,8 +70,8 @@
 	return -EINVAL;
 }
 
-static int __devinit xonar_probe(struct pci_dev *pci,
-				 const struct pci_device_id *pci_id)
+static int xonar_probe(struct pci_dev *pci,
+		       const struct pci_device_id *pci_id)
 {
 	static int dev;
 	int err;
@@ -92,7 +93,7 @@
 	.name = KBUILD_MODNAME,
 	.id_table = xonar_ids,
 	.probe = xonar_probe,
-	.remove = __devexit_p(oxygen_pci_remove),
+	.remove = oxygen_pci_remove,
 #ifdef CONFIG_PM_SLEEP
 	.driver = {
 		.pm = &oxygen_pci_pm,
diff --git a/sound/pci/oxygen/xonar_cs43xx.c b/sound/pci/oxygen/xonar_cs43xx.c
index c8febf4..d231b93 100644
--- a/sound/pci/oxygen/xonar_cs43xx.c
+++ b/sound/pci/oxygen/xonar_cs43xx.c
@@ -431,8 +431,8 @@
 	.adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
 };
 
-int __devinit get_xonar_cs43xx_model(struct oxygen *chip,
-				     const struct pci_device_id *id)
+int get_xonar_cs43xx_model(struct oxygen *chip,
+			   const struct pci_device_id *id)
 {
 	switch (id->subdevice) {
 	case 0x834f:
diff --git a/sound/pci/oxygen/xonar_pcm179x.c b/sound/pci/oxygen/xonar_pcm179x.c
index 8433aa7..c8c7f2c 100644
--- a/sound/pci/oxygen/xonar_pcm179x.c
+++ b/sound/pci/oxygen/xonar_pcm179x.c
@@ -1087,8 +1087,8 @@
 	.adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
 };
 
-int __devinit get_xonar_pcm179x_model(struct oxygen *chip,
-				      const struct pci_device_id *id)
+int get_xonar_pcm179x_model(struct oxygen *chip,
+			    const struct pci_device_id *id)
 {
 	switch (id->subdevice) {
 	case 0x8269:
diff --git a/sound/pci/oxygen/xonar_wm87x6.c b/sound/pci/oxygen/xonar_wm87x6.c
index 63cff90..6ce6860 100644
--- a/sound/pci/oxygen/xonar_wm87x6.c
+++ b/sound/pci/oxygen/xonar_wm87x6.c
@@ -1255,7 +1255,6 @@
 }
 
 static const struct oxygen_model model_xonar_ds = {
-	.shortname = "Xonar DS",
 	.longname = "Asus Virtuoso 66",
 	.chip = "AV200",
 	.init = xonar_ds_init,
@@ -1321,12 +1320,17 @@
 	.adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
 };
 
-int __devinit get_xonar_wm87x6_model(struct oxygen *chip,
-				     const struct pci_device_id *id)
+int get_xonar_wm87x6_model(struct oxygen *chip,
+			   const struct pci_device_id *id)
 {
 	switch (id->subdevice) {
 	case 0x838e:
 		chip->model = model_xonar_ds;
+		chip->model.shortname = "Xonar DS";
+		break;
+	case 0x8522:
+		chip->model = model_xonar_ds;
+		chip->model.shortname = "Xonar DSX";
 		break;
 	case 0x835e:
 		chip->model = model_xonar_hdav_slim;
diff --git a/sound/pci/pcxhr/pcxhr.c b/sound/pci/pcxhr/pcxhr.c
index be4f145..b97384a 100644
--- a/sound/pci/pcxhr/pcxhr.c
+++ b/sound/pci/pcxhr/pcxhr.c
@@ -1203,8 +1203,8 @@
 
 /*
  */
-static int __devinit pcxhr_create(struct pcxhr_mgr *mgr,
-				  struct snd_card *card, int idx)
+static int pcxhr_create(struct pcxhr_mgr *mgr,
+			struct snd_card *card, int idx)
 {
 	int err;
 	struct snd_pcxhr *chip;
@@ -1453,7 +1453,7 @@
 	}
 }
 
-static void __devinit pcxhr_proc_init(struct snd_pcxhr *chip)
+static void pcxhr_proc_init(struct snd_pcxhr *chip)
 {
 	struct snd_info_entry *entry;
 
@@ -1513,8 +1513,8 @@
 /*
  *    probe function - creates the card manager
  */
-static int __devinit pcxhr_probe(struct pci_dev *pci,
-				 const struct pci_device_id *pci_id)
+static int pcxhr_probe(struct pci_dev *pci,
+		       const struct pci_device_id *pci_id)
 {
 	static int dev;
 	struct pcxhr_mgr *mgr;
@@ -1688,7 +1688,7 @@
 	return 0;
 }
 
-static void __devexit pcxhr_remove(struct pci_dev *pci)
+static void pcxhr_remove(struct pci_dev *pci)
 {
 	pcxhr_free(pci_get_drvdata(pci));
 	pci_set_drvdata(pci, NULL);
@@ -1698,7 +1698,7 @@
 	.name = KBUILD_MODNAME,
 	.id_table = pcxhr_ids,
 	.probe = pcxhr_probe,
-	.remove = __devexit_p(pcxhr_remove),
+	.remove = pcxhr_remove,
 };
 
 module_pci_driver(pcxhr_driver);
diff --git a/sound/pci/pcxhr/pcxhr_hwdep.c b/sound/pci/pcxhr/pcxhr_hwdep.c
index bf207e3..d995175 100644
--- a/sound/pci/pcxhr/pcxhr_hwdep.c
+++ b/sound/pci/pcxhr/pcxhr_hwdep.c
@@ -35,13 +35,6 @@
 #include "pcxhr_mix22.h"
 
 
-#if defined(CONFIG_FW_LOADER) || defined(CONFIG_FW_LOADER_MODULE)
-#if !defined(CONFIG_USE_PCXHRLOADER) && !defined(CONFIG_SND_PCXHR) /* built-in kernel */
-#define SND_PCXHR_FW_LOADER	/* use the standard firmware loader */
-#endif
-#endif
-
-
 static int pcxhr_sub_init(struct pcxhr_mgr *mgr);
 /*
  * get basic information and init pcxhr card
@@ -362,8 +355,6 @@
 /*
  * fw loader entry
  */
-#ifdef SND_PCXHR_FW_LOADER
-
 int pcxhr_setup_firmware(struct pcxhr_mgr *mgr)
 {
 	static char *fw_files[][5] = {
@@ -424,80 +415,3 @@
 MODULE_FIRMWARE("pcxhr/dspe924.e56");
 MODULE_FIRMWARE("pcxhr/dspb924.b56");
 MODULE_FIRMWARE("pcxhr/dspd222.d56");
-
-
-#else /* old style firmware loading */
-
-/* pcxhr hwdep interface id string */
-#define PCXHR_HWDEP_ID       "pcxhr loader"
-
-
-static int pcxhr_hwdep_dsp_status(struct snd_hwdep *hw,
-				  struct snd_hwdep_dsp_status *info)
-{
-	struct pcxhr_mgr *mgr = hw->private_data;
-	sprintf(info->id, "pcxhr%d", mgr->fw_file_set);
-        info->num_dsps = PCXHR_FIRMWARE_FILES_MAX_INDEX;
-
-	if (hw->dsp_loaded & (1 << PCXHR_FIRMWARE_DSP_MAIN_INDEX))
-		info->chip_ready = 1;
-
-	info->version = PCXHR_DRIVER_VERSION;
-	return 0;
-}
-
-static int pcxhr_hwdep_dsp_load(struct snd_hwdep *hw,
-				struct snd_hwdep_dsp_image *dsp)
-{
-	struct pcxhr_mgr *mgr = hw->private_data;
-	int err;
-	struct firmware fw;
-
-	fw.size = dsp->length;
-	fw.data = vmalloc(fw.size);
-	if (! fw.data) {
-		snd_printk(KERN_ERR "pcxhr: cannot allocate dsp image "
-			   "(%lu bytes)\n", (unsigned long)fw.size);
-		return -ENOMEM;
-	}
-	if (copy_from_user((void *)fw.data, dsp->image, dsp->length)) {
-		vfree(fw.data);
-		return -EFAULT;
-	}
-	err = pcxhr_dsp_load(mgr, dsp->index, &fw);
-	vfree(fw.data);
-	if (err < 0)
-		return err;
-	mgr->dsp_loaded |= 1 << dsp->index;
-	return 0;
-}
-
-int pcxhr_setup_firmware(struct pcxhr_mgr *mgr)
-{
-	int err;
-	struct snd_hwdep *hw;
-
-	/* only create hwdep interface for first cardX
-	 * (see "index" module parameter)
-	 */
-	err = snd_hwdep_new(mgr->chip[0]->card, PCXHR_HWDEP_ID, 0, &hw);
-	if (err < 0)
-		return err;
-
-	hw->iface = SNDRV_HWDEP_IFACE_PCXHR;
-	hw->private_data = mgr;
-	hw->ops.dsp_status = pcxhr_hwdep_dsp_status;
-	hw->ops.dsp_load = pcxhr_hwdep_dsp_load;
-	hw->exclusive = 1;
-	/* stereo cards don't need fw_file_0 -> dsp_loaded = 1 */
-	hw->dsp_loaded = mgr->is_hr_stereo ? 1 : 0;
-	mgr->dsp_loaded = 0;
-	sprintf(hw->name, PCXHR_HWDEP_ID);
-
-	err = snd_card_register(mgr->chip[0]->card);
-	if (err < 0)
-		return err;
-	return 0;
-}
-
-#endif /* SND_PCXHR_FW_LOADER */
diff --git a/sound/pci/riptide/riptide.c b/sound/pci/riptide/riptide.c
index 7d29154..63c1c80 100644
--- a/sound/pci/riptide/riptide.c
+++ b/sound/pci/riptide/riptide.c
@@ -1706,7 +1706,7 @@
 	.pointer = snd_riptide_pointer,
 };
 
-static int __devinit
+static int
 snd_riptide_pcm(struct snd_riptide *chip, int device, struct snd_pcm **rpcm)
 {
 	struct snd_pcm *pcm;
@@ -1857,7 +1857,7 @@
 	return snd_riptide_free(chip);
 }
 
-static int __devinit
+static int
 snd_riptide_create(struct snd_card *card, struct pci_dev *pci,
 		   struct snd_riptide **rchip)
 {
@@ -1993,7 +1993,7 @@
 	snd_iprintf(buffer, "\n");
 }
 
-static void __devinit snd_riptide_proc_init(struct snd_riptide *chip)
+static void snd_riptide_proc_init(struct snd_riptide *chip)
 {
 	struct snd_info_entry *entry;
 
@@ -2001,7 +2001,7 @@
 		snd_info_set_text_ops(entry, chip, snd_riptide_proc_read);
 }
 
-static int __devinit snd_riptide_mixer(struct snd_riptide *chip)
+static int snd_riptide_mixer(struct snd_riptide *chip)
 {
 	struct snd_ac97_bus *pbus;
 	struct snd_ac97_template ac97;
@@ -2027,7 +2027,7 @@
 
 #ifdef SUPPORT_JOYSTICK
 
-static int __devinit
+static int
 snd_riptide_joystick_probe(struct pci_dev *pci, const struct pci_device_id *id)
 {
 	static int dev;
@@ -2060,7 +2060,7 @@
 	return 0;
 }
 
-static void __devexit snd_riptide_joystick_remove(struct pci_dev *pci)
+static void snd_riptide_joystick_remove(struct pci_dev *pci)
 {
 	struct gameport *gameport = pci_get_drvdata(pci);
 	if (gameport) {
@@ -2071,7 +2071,7 @@
 }
 #endif
 
-static int __devinit
+static int
 snd_card_riptide_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
 {
 	static int dev;
@@ -2176,7 +2176,7 @@
 	return err;
 }
 
-static void __devexit snd_card_riptide_remove(struct pci_dev *pci)
+static void snd_card_riptide_remove(struct pci_dev *pci)
 {
 	snd_card_free(pci_get_drvdata(pci));
 	pci_set_drvdata(pci, NULL);
@@ -2186,7 +2186,7 @@
 	.name = KBUILD_MODNAME,
 	.id_table = snd_riptide_ids,
 	.probe = snd_card_riptide_probe,
-	.remove = __devexit_p(snd_card_riptide_remove),
+	.remove = snd_card_riptide_remove,
 	.driver = {
 		.pm = RIPTIDE_PM_OPS,
 	},
@@ -2197,7 +2197,7 @@
 	.name = KBUILD_MODNAME "-joystick",
 	.id_table = snd_riptide_joystick_ids,
 	.probe = snd_riptide_joystick_probe,
-	.remove = __devexit_p(snd_riptide_joystick_remove),
+	.remove = snd_riptide_joystick_remove,
 };
 #endif
 
diff --git a/sound/pci/rme32.c b/sound/pci/rme32.c
index 46b3629..2450663 100644
--- a/sound/pci/rme32.c
+++ b/sound/pci/rme32.c
@@ -1332,7 +1332,7 @@
 	rme32->adat_pcm = NULL;
 }
 
-static int __devinit snd_rme32_create(struct rme32 * rme32)
+static int snd_rme32_create(struct rme32 *rme32)
 {
 	struct pci_dev *pci = rme32->pci;
 	int err;
@@ -1554,7 +1554,7 @@
 	}
 }
 
-static void __devinit snd_rme32_proc_init(struct rme32 * rme32)
+static void snd_rme32_proc_init(struct rme32 *rme32)
 {
 	struct snd_info_entry *entry;
 
@@ -1922,7 +1922,7 @@
 	snd_rme32_free(card->private_data);
 }
 
-static int __devinit
+static int
 snd_rme32_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
 {
 	static int dev;
@@ -1978,7 +1978,7 @@
 	return 0;
 }
 
-static void __devexit snd_rme32_remove(struct pci_dev *pci)
+static void snd_rme32_remove(struct pci_dev *pci)
 {
 	snd_card_free(pci_get_drvdata(pci));
 	pci_set_drvdata(pci, NULL);
@@ -1988,7 +1988,7 @@
 	.name =		KBUILD_MODNAME,
 	.id_table =	snd_rme32_ids,
 	.probe =	snd_rme32_probe,
-	.remove =	__devexit_p(snd_rme32_remove),
+	.remove =	snd_rme32_remove,
 };
 
 module_pci_driver(rme32_driver);
diff --git a/sound/pci/rme96.c b/sound/pci/rme96.c
index 9b98dc4..5fb88ac 100644
--- a/sound/pci/rme96.c
+++ b/sound/pci/rme96.c
@@ -270,8 +270,7 @@
 static snd_pcm_uframes_t
 snd_rme96_capture_pointer(struct snd_pcm_substream *substream);
 
-static void __devinit 
-snd_rme96_proc_init(struct rme96 *rme96);
+static void snd_rme96_proc_init(struct rme96 *rme96);
 
 static int
 snd_rme96_create_switches(struct snd_card *card,
@@ -1538,7 +1537,7 @@
 	rme96->adat_pcm = NULL;
 }
 
-static int __devinit
+static int
 snd_rme96_create(struct rme96 *rme96)
 {
 	struct pci_dev *pci = rme96->pci;
@@ -1786,8 +1785,7 @@
 	}
 }
 
-static void __devinit 
-snd_rme96_proc_init(struct rme96 *rme96)
+static void snd_rme96_proc_init(struct rme96 *rme96)
 {
 	struct snd_info_entry *entry;
 
@@ -2326,7 +2324,7 @@
 	snd_rme96_free(card->private_data);
 }
 
-static int __devinit
+static int
 snd_rme96_probe(struct pci_dev *pci,
 		const struct pci_device_id *pci_id)
 {
@@ -2389,7 +2387,7 @@
 	return 0;
 }
 
-static void __devexit snd_rme96_remove(struct pci_dev *pci)
+static void snd_rme96_remove(struct pci_dev *pci)
 {
 	snd_card_free(pci_get_drvdata(pci));
 	pci_set_drvdata(pci, NULL);
@@ -2399,7 +2397,7 @@
 	.name = KBUILD_MODNAME,
 	.id_table = snd_rme96_ids,
 	.probe = snd_rme96_probe,
-	.remove = __devexit_p(snd_rme96_remove),
+	.remove = snd_rme96_remove,
 };
 
 module_pci_driver(rme96_driver);
diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c
index 0d6930c..4fae81f 100644
--- a/sound/pci/rme9652/hdsp.c
+++ b/sound/pci/rme9652/hdsp.c
@@ -28,6 +28,7 @@
 #include <linux/firmware.h>
 #include <linux/module.h>
 #include <linux/math64.h>
+#include <linux/vmalloc.h>
 
 #include <sound/core.h>
 #include <sound/control.h>
@@ -59,13 +60,11 @@
 MODULE_SUPPORTED_DEVICE("{{RME Hammerfall-DSP},"
 	        "{RME HDSP-9652},"
 		"{RME HDSP-9632}}");
-#ifdef HDSP_FW_LOADER
 MODULE_FIRMWARE("rpm_firmware.bin");
 MODULE_FIRMWARE("multiface_firmware.bin");
 MODULE_FIRMWARE("multiface_firmware_rev11.bin");
 MODULE_FIRMWARE("digiface_firmware.bin");
 MODULE_FIRMWARE("digiface_firmware_rev11.bin");
-#endif
 
 #define HDSP_MAX_CHANNELS        26
 #define HDSP_MAX_DS_CHANNELS     14
@@ -423,12 +422,7 @@
 #define HDSP_DMA_AREA_BYTES ((HDSP_MAX_CHANNELS+1) * HDSP_CHANNEL_BUFFER_BYTES)
 #define HDSP_DMA_AREA_KILOBYTES (HDSP_DMA_AREA_BYTES/1024)
 
-/* use hotplug firmware loader? */
-#if defined(CONFIG_FW_LOADER) || defined(CONFIG_FW_LOADER_MODULE)
-#if !defined(HDSP_USE_HWDEP_LOADER)
-#define HDSP_FW_LOADER
-#endif
-#endif
+#define HDSP_FIRMWARE_SIZE	(24413 * 4)
 
 struct hdsp_9632_meters {
     u32 input_peak[16];
@@ -475,7 +469,8 @@
 	enum HDSP_IO_Type     io_type;               /* ditto, but for code use */
         unsigned short        firmware_rev;
 	unsigned short	      state;		     /* stores state bits */
-	u32		      firmware_cache[24413]; /* this helps recover from accidental iobox power failure */
+	const struct firmware *firmware;
+	u32                  *fw_uploaded;
 	size_t                period_bytes; 	     /* guess what this is */
 	unsigned char	      max_channels;
 	unsigned char	      qs_in_channels;	     /* quad speed mode for H9632 */
@@ -712,6 +707,17 @@
 
 	int i;
 	unsigned long flags;
+	const u32 *cache;
+
+	if (hdsp->fw_uploaded)
+		cache = hdsp->fw_uploaded;
+	else {
+		if (!hdsp->firmware)
+			return -ENODEV;
+		cache = (u32 *)hdsp->firmware->data;
+		if (!cache)
+			return -ENODEV;
+	}
 
 	if ((hdsp_read (hdsp, HDSP_statusRegister) & HDSP_DllError) != 0) {
 
@@ -727,8 +733,8 @@
 
 		hdsp_write (hdsp, HDSP_control2Reg, HDSP_S_LOAD);
 
-		for (i = 0; i < 24413; ++i) {
-			hdsp_write(hdsp, HDSP_fifoData, hdsp->firmware_cache[i]);
+		for (i = 0; i < HDSP_FIRMWARE_SIZE / 4; ++i) {
+			hdsp_write(hdsp, HDSP_fifoData, cache[i]);
 			if (hdsp_fifo_wait (hdsp, 127, HDSP_LONG_WAIT)) {
 				snd_printk ("Hammerfall-DSP: timeout during firmware loading\n");
 				return -EIO;
@@ -798,9 +804,7 @@
 }
 
 
-#ifdef HDSP_FW_LOADER
 static int hdsp_request_fw_loader(struct hdsp *hdsp);
-#endif
 
 static int hdsp_check_for_firmware (struct hdsp *hdsp, int load_on_demand)
 {
@@ -813,10 +817,8 @@
 		snd_printk(KERN_ERR "Hammerfall-DSP: firmware not present.\n");
 		/* try to load firmware */
 		if (! (hdsp->state & HDSP_FirmwareCached)) {
-#ifdef HDSP_FW_LOADER
 			if (! hdsp_request_fw_loader(hdsp))
 				return 0;
-#endif
 			snd_printk(KERN_ERR
 				   "Hammerfall-DSP: No firmware loaded nor "
 				   "cached, please upload firmware.\n");
@@ -3673,9 +3675,7 @@
 			}
 		} else {
 			int err = -EINVAL;
-#ifdef HDSP_FW_LOADER
 			err = hdsp_request_fw_loader(hdsp);
-#endif
 			if (err < 0) {
 				snd_iprintf(buffer,
 					    "No firmware loaded nor cached, "
@@ -4020,7 +4020,7 @@
 	snd_hammerfall_free_buffer(&hdsp->playback_dma_buf, hdsp->pci);
 }
 
-static int __devinit snd_hdsp_initialize_memory(struct hdsp *hdsp)
+static int snd_hdsp_initialize_memory(struct hdsp *hdsp)
 {
 	unsigned long pb_bus, cb_bus;
 
@@ -5100,8 +5100,18 @@
 		if (hdsp_check_for_iobox (hdsp))
 			return -EIO;
 
-		if (copy_from_user(hdsp->firmware_cache, firmware_data, sizeof(hdsp->firmware_cache)) != 0)
+		if (!hdsp->fw_uploaded) {
+			hdsp->fw_uploaded = vmalloc(HDSP_FIRMWARE_SIZE);
+			if (!hdsp->fw_uploaded)
+				return -ENOMEM;
+		}
+
+		if (copy_from_user(hdsp->fw_uploaded, firmware_data,
+				   HDSP_FIRMWARE_SIZE)) {
+			vfree(hdsp->fw_uploaded);
+			hdsp->fw_uploaded = NULL;
 			return -EFAULT;
+		}
 
 		hdsp->state |= HDSP_FirmwareCached;
 
@@ -5330,7 +5340,6 @@
 	return 0;
 }
 
-#ifdef HDSP_FW_LOADER
 /* load firmware via hotplug fw loader */
 static int hdsp_request_fw_loader(struct hdsp *hdsp)
 {
@@ -5373,16 +5382,13 @@
 		snd_printk(KERN_ERR "Hammerfall-DSP: cannot load firmware %s\n", fwfile);
 		return -ENOENT;
 	}
-	if (fw->size < sizeof(hdsp->firmware_cache)) {
+	if (fw->size < HDSP_FIRMWARE_SIZE) {
 		snd_printk(KERN_ERR "Hammerfall-DSP: too short firmware size %d (expected %d)\n",
-			   (int)fw->size, (int)sizeof(hdsp->firmware_cache));
-		release_firmware(fw);
+			   (int)fw->size, HDSP_FIRMWARE_SIZE);
 		return -EINVAL;
 	}
 
-	memcpy(hdsp->firmware_cache, fw->data, sizeof(hdsp->firmware_cache));
-
-	release_firmware(fw);
+	hdsp->firmware = fw;
 
 	hdsp->state |= HDSP_FirmwareCached;
 
@@ -5406,10 +5412,9 @@
 	}
 	return 0;
 }
-#endif
 
-static int __devinit snd_hdsp_create(struct snd_card *card,
-				     struct hdsp *hdsp)
+static int snd_hdsp_create(struct snd_card *card,
+			   struct hdsp *hdsp)
 {
 	struct pci_dev *pci = hdsp->pci;
 	int err;
@@ -5504,7 +5509,6 @@
 			return err;
 
 		if ((hdsp_read (hdsp, HDSP_statusRegister) & HDSP_DllError) != 0) {
-#ifdef HDSP_FW_LOADER
 			if ((err = hdsp_request_fw_loader(hdsp)) < 0)
 				/* we don't fail as this can happen
 				   if userspace is not ready for
@@ -5514,7 +5518,6 @@
 			else
 				/* init is complete, we return */
 				return 0;
-#endif
 			/* we defer initialization */
 			snd_printk(KERN_INFO "Hammerfall-DSP: card initialization pending : waiting for firmware\n");
 			if ((err = snd_hdsp_create_hwdep(card, hdsp)) < 0)
@@ -5568,6 +5571,10 @@
 
 	snd_hdsp_free_buffers(hdsp);
 
+	if (hdsp->firmware)
+		release_firmware(hdsp->firmware);
+	vfree(hdsp->fw_uploaded);
+
 	if (hdsp->iobase)
 		iounmap(hdsp->iobase);
 
@@ -5586,8 +5593,8 @@
 		snd_hdsp_free(hdsp);
 }
 
-static int __devinit snd_hdsp_probe(struct pci_dev *pci,
-				    const struct pci_device_id *pci_id)
+static int snd_hdsp_probe(struct pci_dev *pci,
+			  const struct pci_device_id *pci_id)
 {
 	static int dev;
 	struct hdsp *hdsp;
@@ -5630,7 +5637,7 @@
 	return 0;
 }
 
-static void __devexit snd_hdsp_remove(struct pci_dev *pci)
+static void snd_hdsp_remove(struct pci_dev *pci)
 {
 	snd_card_free(pci_get_drvdata(pci));
 	pci_set_drvdata(pci, NULL);
@@ -5640,7 +5647,7 @@
 	.name =     KBUILD_MODNAME,
 	.id_table = snd_hdsp_ids,
 	.probe =    snd_hdsp_probe,
-	.remove = __devexit_p(snd_hdsp_remove),
+	.remove = snd_hdsp_remove,
 };
 
 module_pci_driver(hdsp_driver);
diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c
index 748e36c..6e02e06 100644
--- a/sound/pci/rme9652/hdspm.c
+++ b/sound/pci/rme9652/hdspm.c
@@ -962,10 +962,10 @@
 MODULE_DEVICE_TABLE(pci, snd_hdspm_ids);
 
 /* prototypes */
-static int __devinit snd_hdspm_create_alsa_devices(struct snd_card *card,
-						   struct hdspm * hdspm);
-static int __devinit snd_hdspm_create_pcm(struct snd_card *card,
-					  struct hdspm * hdspm);
+static int snd_hdspm_create_alsa_devices(struct snd_card *card,
+					 struct hdspm *hdspm);
+static int snd_hdspm_create_pcm(struct snd_card *card,
+				struct hdspm *hdspm);
 
 static inline void snd_hdspm_initialize_midi_flush(struct hdspm *hdspm);
 static int hdspm_update_simple_mixer_controls(struct hdspm *hdspm);
@@ -1845,8 +1845,8 @@
 	.trigger =	snd_hdspm_midi_input_trigger,
 };
 
-static int __devinit snd_hdspm_create_midi (struct snd_card *card,
-					    struct hdspm *hdspm, int id)
+static int snd_hdspm_create_midi(struct snd_card *card,
+				 struct hdspm *hdspm, int id)
 {
 	int err;
 	char buf[32];
@@ -2887,106 +2887,50 @@
 	return 0;
 }
 
-
-#define HDSPM_LINE_OUT(xname, xindex) \
+#define HDSPM_TOGGLE_SETTING(xname, xindex) \
 {	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
 	.name = xname, \
-	.index = xindex, \
-	.info = snd_hdspm_info_line_out, \
-	.get = snd_hdspm_get_line_out, \
-	.put = snd_hdspm_put_line_out \
+	.private_value = xindex, \
+	.info = snd_hdspm_info_toggle_setting, \
+	.get = snd_hdspm_get_toggle_setting, \
+	.put = snd_hdspm_put_toggle_setting \
 }
 
-static int hdspm_line_out(struct hdspm * hdspm)
+static int hdspm_toggle_setting(struct hdspm *hdspm, u32 regmask)
 {
-	return (hdspm->control_register & HDSPM_LineOut) ? 1 : 0;
+	return (hdspm->control_register & regmask) ? 1 : 0;
 }
 
-
-static int hdspm_set_line_output(struct hdspm * hdspm, int out)
+static int hdspm_set_toggle_setting(struct hdspm *hdspm, u32 regmask, int out)
 {
 	if (out)
-		hdspm->control_register |= HDSPM_LineOut;
+		hdspm->control_register |= regmask;
 	else
-		hdspm->control_register &= ~HDSPM_LineOut;
+		hdspm->control_register &= ~regmask;
 	hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register);
 
 	return 0;
 }
 
-#define snd_hdspm_info_line_out		snd_ctl_boolean_mono_info
+#define snd_hdspm_info_toggle_setting		snd_ctl_boolean_mono_info
 
-static int snd_hdspm_get_line_out(struct snd_kcontrol *kcontrol,
-				  struct snd_ctl_elem_value *ucontrol)
-{
-	struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
-
-	spin_lock_irq(&hdspm->lock);
-	ucontrol->value.integer.value[0] = hdspm_line_out(hdspm);
-	spin_unlock_irq(&hdspm->lock);
-	return 0;
-}
-
-static int snd_hdspm_put_line_out(struct snd_kcontrol *kcontrol,
-				  struct snd_ctl_elem_value *ucontrol)
-{
-	struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
-	int change;
-	unsigned int val;
-
-	if (!snd_hdspm_use_is_exclusive(hdspm))
-		return -EBUSY;
-	val = ucontrol->value.integer.value[0] & 1;
-	spin_lock_irq(&hdspm->lock);
-	change = (int) val != hdspm_line_out(hdspm);
-	hdspm_set_line_output(hdspm, val);
-	spin_unlock_irq(&hdspm->lock);
-	return change;
-}
-
-
-#define HDSPM_TX_64(xname, xindex) \
-{	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
-	.name = xname, \
-	.index = xindex, \
-	.info = snd_hdspm_info_tx_64, \
-	.get = snd_hdspm_get_tx_64, \
-	.put = snd_hdspm_put_tx_64 \
-}
-
-static int hdspm_tx_64(struct hdspm * hdspm)
-{
-	return (hdspm->control_register & HDSPM_TX_64ch) ? 1 : 0;
-}
-
-static int hdspm_set_tx_64(struct hdspm * hdspm, int out)
-{
-	if (out)
-		hdspm->control_register |= HDSPM_TX_64ch;
-	else
-		hdspm->control_register &= ~HDSPM_TX_64ch;
-	hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register);
-
-	return 0;
-}
-
-#define snd_hdspm_info_tx_64		snd_ctl_boolean_mono_info
-
-static int snd_hdspm_get_tx_64(struct snd_kcontrol *kcontrol,
+static int snd_hdspm_get_toggle_setting(struct snd_kcontrol *kcontrol,
 			       struct snd_ctl_elem_value *ucontrol)
 {
 	struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
+	u32 regmask = kcontrol->private_value;
 
 	spin_lock_irq(&hdspm->lock);
-	ucontrol->value.integer.value[0] = hdspm_tx_64(hdspm);
+	ucontrol->value.integer.value[0] = hdspm_toggle_setting(hdspm, regmask);
 	spin_unlock_irq(&hdspm->lock);
 	return 0;
 }
 
-static int snd_hdspm_put_tx_64(struct snd_kcontrol *kcontrol,
+static int snd_hdspm_put_toggle_setting(struct snd_kcontrol *kcontrol,
 			       struct snd_ctl_elem_value *ucontrol)
 {
 	struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
+	u32 regmask = kcontrol->private_value;
 	int change;
 	unsigned int val;
 
@@ -2994,288 +2938,8 @@
 		return -EBUSY;
 	val = ucontrol->value.integer.value[0] & 1;
 	spin_lock_irq(&hdspm->lock);
-	change = (int) val != hdspm_tx_64(hdspm);
-	hdspm_set_tx_64(hdspm, val);
-	spin_unlock_irq(&hdspm->lock);
-	return change;
-}
-
-
-#define HDSPM_C_TMS(xname, xindex) \
-{	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
-	.name = xname, \
-	.index = xindex, \
-	.info = snd_hdspm_info_c_tms, \
-	.get = snd_hdspm_get_c_tms, \
-	.put = snd_hdspm_put_c_tms \
-}
-
-static int hdspm_c_tms(struct hdspm * hdspm)
-{
-	return (hdspm->control_register & HDSPM_clr_tms) ? 1 : 0;
-}
-
-static int hdspm_set_c_tms(struct hdspm * hdspm, int out)
-{
-	if (out)
-		hdspm->control_register |= HDSPM_clr_tms;
-	else
-		hdspm->control_register &= ~HDSPM_clr_tms;
-	hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register);
-
-	return 0;
-}
-
-#define snd_hdspm_info_c_tms		snd_ctl_boolean_mono_info
-
-static int snd_hdspm_get_c_tms(struct snd_kcontrol *kcontrol,
-			       struct snd_ctl_elem_value *ucontrol)
-{
-	struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
-
-	spin_lock_irq(&hdspm->lock);
-	ucontrol->value.integer.value[0] = hdspm_c_tms(hdspm);
-	spin_unlock_irq(&hdspm->lock);
-	return 0;
-}
-
-static int snd_hdspm_put_c_tms(struct snd_kcontrol *kcontrol,
-			       struct snd_ctl_elem_value *ucontrol)
-{
-	struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
-	int change;
-	unsigned int val;
-
-	if (!snd_hdspm_use_is_exclusive(hdspm))
-		return -EBUSY;
-	val = ucontrol->value.integer.value[0] & 1;
-	spin_lock_irq(&hdspm->lock);
-	change = (int) val != hdspm_c_tms(hdspm);
-	hdspm_set_c_tms(hdspm, val);
-	spin_unlock_irq(&hdspm->lock);
-	return change;
-}
-
-
-#define HDSPM_SAFE_MODE(xname, xindex) \
-{	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
-	.name = xname, \
-	.index = xindex, \
-	.info = snd_hdspm_info_safe_mode, \
-	.get = snd_hdspm_get_safe_mode, \
-	.put = snd_hdspm_put_safe_mode \
-}
-
-static int hdspm_safe_mode(struct hdspm * hdspm)
-{
-	return (hdspm->control_register & HDSPM_AutoInp) ? 1 : 0;
-}
-
-static int hdspm_set_safe_mode(struct hdspm * hdspm, int out)
-{
-	if (out)
-		hdspm->control_register |= HDSPM_AutoInp;
-	else
-		hdspm->control_register &= ~HDSPM_AutoInp;
-	hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register);
-
-	return 0;
-}
-
-#define snd_hdspm_info_safe_mode	snd_ctl_boolean_mono_info
-
-static int snd_hdspm_get_safe_mode(struct snd_kcontrol *kcontrol,
-				   struct snd_ctl_elem_value *ucontrol)
-{
-	struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
-
-	spin_lock_irq(&hdspm->lock);
-	ucontrol->value.integer.value[0] = hdspm_safe_mode(hdspm);
-	spin_unlock_irq(&hdspm->lock);
-	return 0;
-}
-
-static int snd_hdspm_put_safe_mode(struct snd_kcontrol *kcontrol,
-				   struct snd_ctl_elem_value *ucontrol)
-{
-	struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
-	int change;
-	unsigned int val;
-
-	if (!snd_hdspm_use_is_exclusive(hdspm))
-		return -EBUSY;
-	val = ucontrol->value.integer.value[0] & 1;
-	spin_lock_irq(&hdspm->lock);
-	change = (int) val != hdspm_safe_mode(hdspm);
-	hdspm_set_safe_mode(hdspm, val);
-	spin_unlock_irq(&hdspm->lock);
-	return change;
-}
-
-
-#define HDSPM_EMPHASIS(xname, xindex) \
-{	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
-	.name = xname, \
-	.index = xindex, \
-	.info = snd_hdspm_info_emphasis, \
-	.get = snd_hdspm_get_emphasis, \
-	.put = snd_hdspm_put_emphasis \
-}
-
-static int hdspm_emphasis(struct hdspm * hdspm)
-{
-	return (hdspm->control_register & HDSPM_Emphasis) ? 1 : 0;
-}
-
-static int hdspm_set_emphasis(struct hdspm * hdspm, int emp)
-{
-	if (emp)
-		hdspm->control_register |= HDSPM_Emphasis;
-	else
-		hdspm->control_register &= ~HDSPM_Emphasis;
-	hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register);
-
-	return 0;
-}
-
-#define snd_hdspm_info_emphasis		snd_ctl_boolean_mono_info
-
-static int snd_hdspm_get_emphasis(struct snd_kcontrol *kcontrol,
-				  struct snd_ctl_elem_value *ucontrol)
-{
-	struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
-
-	spin_lock_irq(&hdspm->lock);
-	ucontrol->value.enumerated.item[0] = hdspm_emphasis(hdspm);
-	spin_unlock_irq(&hdspm->lock);
-	return 0;
-}
-
-static int snd_hdspm_put_emphasis(struct snd_kcontrol *kcontrol,
-				  struct snd_ctl_elem_value *ucontrol)
-{
-	struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
-	int change;
-	unsigned int val;
-
-	if (!snd_hdspm_use_is_exclusive(hdspm))
-		return -EBUSY;
-	val = ucontrol->value.integer.value[0] & 1;
-	spin_lock_irq(&hdspm->lock);
-	change = (int) val != hdspm_emphasis(hdspm);
-	hdspm_set_emphasis(hdspm, val);
-	spin_unlock_irq(&hdspm->lock);
-	return change;
-}
-
-
-#define HDSPM_DOLBY(xname, xindex) \
-{	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
-	.name = xname, \
-	.index = xindex, \
-	.info = snd_hdspm_info_dolby, \
-	.get = snd_hdspm_get_dolby, \
-	.put = snd_hdspm_put_dolby \
-}
-
-static int hdspm_dolby(struct hdspm * hdspm)
-{
-	return (hdspm->control_register & HDSPM_Dolby) ? 1 : 0;
-}
-
-static int hdspm_set_dolby(struct hdspm * hdspm, int dol)
-{
-	if (dol)
-		hdspm->control_register |= HDSPM_Dolby;
-	else
-		hdspm->control_register &= ~HDSPM_Dolby;
-	hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register);
-
-	return 0;
-}
-
-#define snd_hdspm_info_dolby		snd_ctl_boolean_mono_info
-
-static int snd_hdspm_get_dolby(struct snd_kcontrol *kcontrol,
-			       struct snd_ctl_elem_value *ucontrol)
-{
-	struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
-
-	spin_lock_irq(&hdspm->lock);
-	ucontrol->value.enumerated.item[0] = hdspm_dolby(hdspm);
-	spin_unlock_irq(&hdspm->lock);
-	return 0;
-}
-
-static int snd_hdspm_put_dolby(struct snd_kcontrol *kcontrol,
-			       struct snd_ctl_elem_value *ucontrol)
-{
-	struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
-	int change;
-	unsigned int val;
-
-	if (!snd_hdspm_use_is_exclusive(hdspm))
-		return -EBUSY;
-	val = ucontrol->value.integer.value[0] & 1;
-	spin_lock_irq(&hdspm->lock);
-	change = (int) val != hdspm_dolby(hdspm);
-	hdspm_set_dolby(hdspm, val);
-	spin_unlock_irq(&hdspm->lock);
-	return change;
-}
-
-
-#define HDSPM_PROFESSIONAL(xname, xindex) \
-{	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
-	.name = xname, \
-	.index = xindex, \
-	.info = snd_hdspm_info_professional, \
-	.get = snd_hdspm_get_professional, \
-	.put = snd_hdspm_put_professional \
-}
-
-static int hdspm_professional(struct hdspm * hdspm)
-{
-	return (hdspm->control_register & HDSPM_Professional) ? 1 : 0;
-}
-
-static int hdspm_set_professional(struct hdspm * hdspm, int dol)
-{
-	if (dol)
-		hdspm->control_register |= HDSPM_Professional;
-	else
-		hdspm->control_register &= ~HDSPM_Professional;
-	hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register);
-
-	return 0;
-}
-
-#define snd_hdspm_info_professional	snd_ctl_boolean_mono_info
-
-static int snd_hdspm_get_professional(struct snd_kcontrol *kcontrol,
-				      struct snd_ctl_elem_value *ucontrol)
-{
-	struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
-
-	spin_lock_irq(&hdspm->lock);
-	ucontrol->value.enumerated.item[0] = hdspm_professional(hdspm);
-	spin_unlock_irq(&hdspm->lock);
-	return 0;
-}
-
-static int snd_hdspm_put_professional(struct snd_kcontrol *kcontrol,
-				      struct snd_ctl_elem_value *ucontrol)
-{
-	struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
-	int change;
-	unsigned int val;
-
-	if (!snd_hdspm_use_is_exclusive(hdspm))
-		return -EBUSY;
-	val = ucontrol->value.integer.value[0] & 1;
-	spin_lock_irq(&hdspm->lock);
-	change = (int) val != hdspm_professional(hdspm);
-	hdspm_set_professional(hdspm, val);
+	change = (int) val != hdspm_toggle_setting(hdspm, regmask);
+	hdspm_set_toggle_setting(hdspm, regmask, val);
 	spin_unlock_irq(&hdspm->lock);
 	return change;
 }
@@ -4476,10 +4140,10 @@
 	HDSPM_SYNC_CHECK("MADI SyncCheck", 1),
 	HDSPM_SYNC_CHECK("TCO SyncCheck", 2),
 	HDSPM_SYNC_CHECK("SYNC IN SyncCheck", 3),
-	HDSPM_LINE_OUT("Line Out", 0),
-	HDSPM_TX_64("TX 64 channels mode", 0),
-	HDSPM_C_TMS("Clear Track Marker", 0),
-	HDSPM_SAFE_MODE("Safe Mode", 0),
+	HDSPM_TOGGLE_SETTING("Line Out", HDSPM_LineOut),
+	HDSPM_TOGGLE_SETTING("TX 64 channels mode", HDSPM_TX_64ch),
+	HDSPM_TOGGLE_SETTING("Clear Track Marker", HDSPM_clr_tms),
+	HDSPM_TOGGLE_SETTING("Safe Mode", HDSPM_AutoInp),
 	HDSPM_INPUT_SELECT("Input Select", 0),
 	HDSPM_MADI_SPEEDMODE("MADI Speed Mode", 0)
 };
@@ -4492,9 +4156,9 @@
 	HDSPM_SYSTEM_SAMPLE_RATE("System Sample Rate", 0),
 	HDSPM_AUTOSYNC_SAMPLE_RATE("External Rate", 0),
 	HDSPM_SYNC_CHECK("MADI SyncCheck", 0),
-	HDSPM_TX_64("TX 64 channels mode", 0),
-	HDSPM_C_TMS("Clear Track Marker", 0),
-	HDSPM_SAFE_MODE("Safe Mode", 0),
+	HDSPM_TOGGLE_SETTING("TX 64 channels mode", HDSPM_TX_64ch),
+	HDSPM_TOGGLE_SETTING("Clear Track Marker", HDSPM_clr_tms),
+	HDSPM_TOGGLE_SETTING("Safe Mode", HDSPM_AutoInp),
 	HDSPM_MADI_SPEEDMODE("MADI Speed Mode", 0)
 };
 
@@ -4587,11 +4251,11 @@
 	HDSPM_AUTOSYNC_SAMPLE_RATE("AES8 Frequency", 8),
 	HDSPM_AUTOSYNC_SAMPLE_RATE("TCO Frequency", 9),
 	HDSPM_AUTOSYNC_SAMPLE_RATE("SYNC IN Frequency", 10),
-	HDSPM_LINE_OUT("Line Out", 0),
-	HDSPM_EMPHASIS("Emphasis", 0),
-	HDSPM_DOLBY("Non Audio", 0),
-	HDSPM_PROFESSIONAL("Professional", 0),
-	HDSPM_C_TMS("Clear Track Marker", 0),
+	HDSPM_TOGGLE_SETTING("Line Out", HDSPM_LineOut),
+	HDSPM_TOGGLE_SETTING("Emphasis", HDSPM_Emphasis),
+	HDSPM_TOGGLE_SETTING("Non Audio", HDSPM_Dolby),
+	HDSPM_TOGGLE_SETTING("Professional", HDSPM_Professional),
+	HDSPM_TOGGLE_SETTING("Clear Track Marker", HDSPM_clr_tms),
 	HDSPM_DS_WIRE("Double Speed Wire Mode", 0),
 	HDSPM_QS_WIRE("Quad Speed Wire Mode", 0),
 };
@@ -5233,7 +4897,7 @@
 }
 
 
-static void __devinit snd_hdspm_proc_init(struct hdspm *hdspm)
+static void snd_hdspm_proc_init(struct hdspm *hdspm)
 {
 	struct snd_info_entry *entry;
 
@@ -6266,7 +5930,7 @@
 		info.system_clock_mode = hdspm_system_clock_mode(hdspm);
 		info.clock_source = hdspm_clock_source(hdspm);
 		info.autosync_ref = hdspm_autosync_ref(hdspm);
-		info.line_out = hdspm_line_out(hdspm);
+		info.line_out = hdspm_toggle_setting(hdspm, HDSPM_LineOut);
 		info.passthru = 0;
 		spin_unlock_irq(&hdspm->lock);
 		if (copy_to_user(argp, &info, sizeof(info)))
@@ -6369,8 +6033,8 @@
 	.page = snd_pcm_sgbuf_ops_page,
 };
 
-static int __devinit snd_hdspm_create_hwdep(struct snd_card *card,
-					    struct hdspm * hdspm)
+static int snd_hdspm_create_hwdep(struct snd_card *card,
+				  struct hdspm *hdspm)
 {
 	struct snd_hwdep *hw;
 	int err;
@@ -6395,7 +6059,7 @@
 /*------------------------------------------------------------
    memory interface
  ------------------------------------------------------------*/
-static int __devinit snd_hdspm_preallocate_memory(struct hdspm *hdspm)
+static int snd_hdspm_preallocate_memory(struct hdspm *hdspm)
 {
 	int err;
 	struct snd_pcm *pcm;
@@ -6436,8 +6100,8 @@
 
 
 /* ------------- ALSA Devices ---------------------------- */
-static int __devinit snd_hdspm_create_pcm(struct snd_card *card,
-					  struct hdspm *hdspm)
+static int snd_hdspm_create_pcm(struct snd_card *card,
+				struct hdspm *hdspm)
 {
 	struct snd_pcm *pcm;
 	int err;
@@ -6472,8 +6136,8 @@
 		snd_hdspm_flush_midi_input(hdspm, i);
 }
 
-static int __devinit snd_hdspm_create_alsa_devices(struct snd_card *card,
-						   struct hdspm * hdspm)
+static int snd_hdspm_create_alsa_devices(struct snd_card *card,
+					 struct hdspm *hdspm)
 {
 	int err, i;
 
@@ -6531,8 +6195,9 @@
 	return 0;
 }
 
-static int __devinit snd_hdspm_create(struct snd_card *card,
-		struct hdspm *hdspm) {
+static int snd_hdspm_create(struct snd_card *card,
+			    struct hdspm *hdspm)
+{
 
 	struct pci_dev *pci = hdspm->pci;
 	int err;
@@ -6905,8 +6570,8 @@
 }
 
 
-static int __devinit snd_hdspm_probe(struct pci_dev *pci,
-				     const struct pci_device_id *pci_id)
+static int snd_hdspm_probe(struct pci_dev *pci,
+			   const struct pci_device_id *pci_id)
 {
 	static int dev;
 	struct hdspm *hdspm;
@@ -6964,7 +6629,7 @@
 	return 0;
 }
 
-static void __devexit snd_hdspm_remove(struct pci_dev *pci)
+static void snd_hdspm_remove(struct pci_dev *pci)
 {
 	snd_card_free(pci_get_drvdata(pci));
 	pci_set_drvdata(pci, NULL);
@@ -6974,7 +6639,7 @@
 	.name = KBUILD_MODNAME,
 	.id_table = snd_hdspm_ids,
 	.probe = snd_hdspm_probe,
-	.remove = __devexit_p(snd_hdspm_remove),
+	.remove = snd_hdspm_remove,
 };
 
 module_pci_driver(hdspm_driver);
diff --git a/sound/pci/rme9652/rme9652.c b/sound/pci/rme9652/rme9652.c
index a15fc10..773a67f 100644
--- a/sound/pci/rme9652/rme9652.c
+++ b/sound/pci/rme9652/rme9652.c
@@ -1757,7 +1757,7 @@
 	snd_iprintf(buffer, "\n");
 }
 
-static void __devinit snd_rme9652_proc_init(struct snd_rme9652 *rme9652)
+static void snd_rme9652_proc_init(struct snd_rme9652 *rme9652)
 {
 	struct snd_info_entry *entry;
 
@@ -1788,7 +1788,7 @@
 	return 0;
 }
 
-static int __devinit snd_rme9652_initialize_memory(struct snd_rme9652 *rme9652)
+static int snd_rme9652_initialize_memory(struct snd_rme9652 *rme9652)
 {
 	unsigned long pb_bus, cb_bus;
 
@@ -2414,8 +2414,8 @@
 	.copy =		snd_rme9652_capture_copy,
 };
 
-static int __devinit snd_rme9652_create_pcm(struct snd_card *card,
-					 struct snd_rme9652 *rme9652)
+static int snd_rme9652_create_pcm(struct snd_card *card,
+				  struct snd_rme9652 *rme9652)
 {
 	struct snd_pcm *pcm;
 	int err;
@@ -2438,9 +2438,9 @@
 	return 0;
 }
 
-static int __devinit snd_rme9652_create(struct snd_card *card,
-				     struct snd_rme9652 *rme9652,
-				     int precise_ptr)
+static int snd_rme9652_create(struct snd_card *card,
+			      struct snd_rme9652 *rme9652,
+			      int precise_ptr)
 {
 	struct pci_dev *pci = rme9652->pci;
 	int err;
@@ -2578,8 +2578,8 @@
 		snd_rme9652_free(rme9652);
 }
 
-static int __devinit snd_rme9652_probe(struct pci_dev *pci,
-				       const struct pci_device_id *pci_id)
+static int snd_rme9652_probe(struct pci_dev *pci,
+			     const struct pci_device_id *pci_id)
 {
 	static int dev;
 	struct snd_rme9652 *rme9652;
@@ -2625,7 +2625,7 @@
 	return 0;
 }
 
-static void __devexit snd_rme9652_remove(struct pci_dev *pci)
+static void snd_rme9652_remove(struct pci_dev *pci)
 {
 	snd_card_free(pci_get_drvdata(pci));
 	pci_set_drvdata(pci, NULL);
@@ -2635,7 +2635,7 @@
 	.name	  = KBUILD_MODNAME,
 	.id_table = snd_rme9652_ids,
 	.probe	  = snd_rme9652_probe,
-	.remove	  = __devexit_p(snd_rme9652_remove),
+	.remove	  = snd_rme9652_remove,
 };
 
 module_pci_driver(rme9652_driver);
diff --git a/sound/pci/sis7019.c b/sound/pci/sis7019.c
index 51e4340..d59abe1 100644
--- a/sound/pci/sis7019.c
+++ b/sound/pci/sis7019.c
@@ -894,7 +894,7 @@
 	.pointer = sis_pcm_pointer,
 };
 
-static int __devinit sis_pcm_create(struct sis7019 *sis)
+static int sis_pcm_create(struct sis7019 *sis)
 {
 	struct snd_pcm *pcm;
 	int rc;
@@ -1013,7 +1013,7 @@
 					(reg << 8) | cmd[ac97->num]);
 }
 
-static int __devinit sis_mixer_create(struct sis7019 *sis)
+static int sis_mixer_create(struct sis7019 *sis)
 {
 	struct snd_ac97_bus *bus;
 	struct snd_ac97_template ac97;
@@ -1171,7 +1171,7 @@
 	outl(SIS_DMA_CSR_PCI_SETTINGS, io + SIS_DMA_CSR);
 
 	/* Reset the synchronization groups for all of the channels
-	 * to be asyncronous. If we start doing SPDIF or 5.1 sound, etc.
+	 * to be asynchronous. If we start doing SPDIF or 5.1 sound, etc.
 	 * we'll need to change how we handle these. Until then, we just
 	 * assign sub-mixer 0 to all playback channels, and avoid any
 	 * attenuation on the audio.
@@ -1326,8 +1326,8 @@
 	return 0;
 }
 
-static int __devinit sis_chip_create(struct snd_card *card,
-					struct pci_dev *pci)
+static int sis_chip_create(struct snd_card *card,
+			   struct pci_dev *pci)
 {
 	struct sis7019 *sis = card->private_data;
 	struct voice *voice;
@@ -1417,8 +1417,8 @@
 	return rc;
 }
 
-static int __devinit snd_sis7019_probe(struct pci_dev *pci,
-					const struct pci_device_id *pci_id)
+static int snd_sis7019_probe(struct pci_dev *pci,
+			     const struct pci_device_id *pci_id)
 {
 	struct snd_card *card;
 	struct sis7019 *sis;
@@ -1478,7 +1478,7 @@
 	return rc;
 }
 
-static void __devexit snd_sis7019_remove(struct pci_dev *pci)
+static void snd_sis7019_remove(struct pci_dev *pci)
 {
 	snd_card_free(pci_get_drvdata(pci));
 	pci_set_drvdata(pci, NULL);
@@ -1488,7 +1488,7 @@
 	.name = KBUILD_MODNAME,
 	.id_table = snd_sis7019_ids,
 	.probe = snd_sis7019_probe,
-	.remove = __devexit_p(snd_sis7019_remove),
+	.remove = snd_sis7019_remove,
 	.driver = {
 		.pm = SIS_PM_OPS,
 	},
diff --git a/sound/pci/sonicvibes.c b/sound/pci/sonicvibes.c
index baa9946b..a2e7686 100644
--- a/sound/pci/sonicvibes.c
+++ b/sound/pci/sonicvibes.c
@@ -877,7 +877,8 @@
 	.pointer =	snd_sonicvibes_capture_pointer,
 };
 
-static int __devinit snd_sonicvibes_pcm(struct sonicvibes * sonic, int device, struct snd_pcm ** rpcm)
+static int snd_sonicvibes_pcm(struct sonicvibes *sonic, int device,
+			      struct snd_pcm **rpcm)
 {
 	struct snd_pcm *pcm;
 	int err;
@@ -1087,7 +1088,7 @@
 	return change;
 }
 
-static struct snd_kcontrol_new snd_sonicvibes_controls[] __devinitdata = {
+static struct snd_kcontrol_new snd_sonicvibes_controls[] = {
 SONICVIBES_DOUBLE("Capture Volume", 0, SV_IREG_LEFT_ADC, SV_IREG_RIGHT_ADC, 0, 0, 15, 0),
 SONICVIBES_DOUBLE("Aux Playback Switch", 0, SV_IREG_LEFT_AUX1, SV_IREG_RIGHT_AUX1, 7, 7, 1, 1),
 SONICVIBES_DOUBLE("Aux Playback Volume", 0, SV_IREG_LEFT_AUX1, SV_IREG_RIGHT_AUX1, 0, 0, 31, 1),
@@ -1118,7 +1119,7 @@
 	sonic->master_volume = NULL;
 }
 
-static int __devinit snd_sonicvibes_mixer(struct sonicvibes * sonic)
+static int snd_sonicvibes_mixer(struct sonicvibes *sonic)
 {
 	struct snd_card *card;
 	struct snd_kcontrol *kctl;
@@ -1175,7 +1176,7 @@
 	snd_iprintf(buffer, "MIDI to ext. Tx  : %s\n", tmp & 0x04 ? "on" : "off");
 }
 
-static void __devinit snd_sonicvibes_proc_init(struct sonicvibes * sonic)
+static void snd_sonicvibes_proc_init(struct sonicvibes *sonic)
 {
 	struct snd_info_entry *entry;
 
@@ -1188,10 +1189,10 @@
  */
 
 #ifdef SUPPORT_JOYSTICK
-static struct snd_kcontrol_new snd_sonicvibes_game_control __devinitdata =
+static struct snd_kcontrol_new snd_sonicvibes_game_control =
 SONICVIBES_SINGLE("Joystick Speed", 0, SV_IREG_GAME_PORT, 1, 15, 0);
 
-static int __devinit snd_sonicvibes_create_gameport(struct sonicvibes *sonic)
+static int snd_sonicvibes_create_gameport(struct sonicvibes *sonic)
 {
 	struct gameport *gp;
 
@@ -1246,11 +1247,11 @@
 	return snd_sonicvibes_free(sonic);
 }
 
-static int __devinit snd_sonicvibes_create(struct snd_card *card,
-					struct pci_dev *pci,
-					int reverb,
-					int mge,
-					struct sonicvibes ** rsonic)
+static int snd_sonicvibes_create(struct snd_card *card,
+				 struct pci_dev *pci,
+				 int reverb,
+				 int mge,
+				 struct sonicvibes **rsonic)
 {
 	struct sonicvibes *sonic;
 	unsigned int dmaa, dmac;
@@ -1401,7 +1402,7 @@
  *  MIDI section
  */
 
-static struct snd_kcontrol_new snd_sonicvibes_midi_controls[] __devinitdata = {
+static struct snd_kcontrol_new snd_sonicvibes_midi_controls[] = {
 SONICVIBES_SINGLE("SonicVibes Wave Source RAM", 0, SV_IREG_WAVE_SOURCE, 0, 1, 0),
 SONICVIBES_SINGLE("SonicVibes Wave Source RAM+ROM", 0, SV_IREG_WAVE_SOURCE, 1, 1, 0),
 SONICVIBES_SINGLE("SonicVibes Onboard Synth", 0, SV_IREG_MPU401, 0, 1, 0),
@@ -1422,8 +1423,8 @@
 	outb(sonic->irqmask |= SV_MIDI_MASK, SV_REG(sonic, IRQMASK));
 }
 
-static int __devinit snd_sonicvibes_midi(struct sonicvibes * sonic,
-					 struct snd_rawmidi *rmidi)
+static int snd_sonicvibes_midi(struct sonicvibes *sonic,
+			       struct snd_rawmidi *rmidi)
 {
 	struct snd_mpu401 * mpu = rmidi->private_data;
 	struct snd_card *card = sonic->card;
@@ -1441,8 +1442,8 @@
 	return 0;
 }
 
-static int __devinit snd_sonic_probe(struct pci_dev *pci,
-				     const struct pci_device_id *pci_id)
+static int snd_sonic_probe(struct pci_dev *pci,
+			   const struct pci_device_id *pci_id)
 {
 	static int dev;
 	struct snd_card *card;
@@ -1524,7 +1525,7 @@
 	return 0;
 }
 
-static void __devexit snd_sonic_remove(struct pci_dev *pci)
+static void snd_sonic_remove(struct pci_dev *pci)
 {
 	snd_card_free(pci_get_drvdata(pci));
 	pci_set_drvdata(pci, NULL);
@@ -1534,7 +1535,7 @@
 	.name = KBUILD_MODNAME,
 	.id_table = snd_sonic_ids,
 	.probe = snd_sonic_probe,
-	.remove = __devexit_p(snd_sonic_remove),
+	.remove = snd_sonic_remove,
 };
 
 module_pci_driver(sonicvibes_driver);
diff --git a/sound/pci/trident/trident.c b/sound/pci/trident/trident.c
index 8a6f1f7..1aefd62 100644
--- a/sound/pci/trident/trident.c
+++ b/sound/pci/trident/trident.c
@@ -73,8 +73,8 @@
 
 MODULE_DEVICE_TABLE(pci, snd_trident_ids);
 
-static int __devinit snd_trident_probe(struct pci_dev *pci,
-				       const struct pci_device_id *pci_id)
+static int snd_trident_probe(struct pci_dev *pci,
+			     const struct pci_device_id *pci_id)
 {
 	static int dev;
 	struct snd_card *card;
@@ -166,7 +166,7 @@
 	return 0;
 }
 
-static void __devexit snd_trident_remove(struct pci_dev *pci)
+static void snd_trident_remove(struct pci_dev *pci)
 {
 	snd_card_free(pci_get_drvdata(pci));
 	pci_set_drvdata(pci, NULL);
@@ -176,7 +176,7 @@
 	.name = KBUILD_MODNAME,
 	.id_table = snd_trident_ids,
 	.probe = snd_trident_probe,
-	.remove = __devexit_p(snd_trident_remove),
+	.remove = snd_trident_remove,
 #ifdef CONFIG_PM_SLEEP
 	.driver = {
 		.pm = &snd_trident_pm,
diff --git a/sound/pci/trident/trident_main.c b/sound/pci/trident/trident_main.c
index 06b10d1..fb0e158 100644
--- a/sound/pci/trident/trident_main.c
+++ b/sound/pci/trident/trident_main.c
@@ -2171,8 +2171,8 @@
   
   ---------------------------------------------------------------------------*/
 
-int __devinit snd_trident_pcm(struct snd_trident * trident,
-			      int device, struct snd_pcm ** rpcm)
+int snd_trident_pcm(struct snd_trident *trident,
+		    int device, struct snd_pcm **rpcm)
 {
 	struct snd_pcm *pcm;
 	int err;
@@ -2229,8 +2229,8 @@
   
   ---------------------------------------------------------------------------*/
 
-int __devinit snd_trident_foldback_pcm(struct snd_trident * trident,
-				       int device, struct snd_pcm ** rpcm)
+int snd_trident_foldback_pcm(struct snd_trident *trident,
+			     int device, struct snd_pcm **rpcm)
 {
 	struct snd_pcm *foldback;
 	int err;
@@ -2286,8 +2286,8 @@
   
   ---------------------------------------------------------------------------*/
 
-int __devinit snd_trident_spdif_pcm(struct snd_trident * trident,
-				    int device, struct snd_pcm ** rpcm)
+int snd_trident_spdif_pcm(struct snd_trident *trident,
+			  int device, struct snd_pcm **rpcm)
 {
 	struct snd_pcm *spdif;
 	int err;
@@ -2371,7 +2371,7 @@
 	return change;
 }
 
-static struct snd_kcontrol_new snd_trident_spdif_control __devinitdata =
+static struct snd_kcontrol_new snd_trident_spdif_control =
 {
 	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name =         SNDRV_CTL_NAME_IEC958("",PLAYBACK,SWITCH),
@@ -2434,7 +2434,7 @@
 	return change;
 }
 
-static struct snd_kcontrol_new snd_trident_spdif_default __devinitdata =
+static struct snd_kcontrol_new snd_trident_spdif_default =
 {
 	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,
 	.name =         SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
@@ -2467,7 +2467,7 @@
 	return 0;
 }
 
-static struct snd_kcontrol_new snd_trident_spdif_mask __devinitdata =
+static struct snd_kcontrol_new snd_trident_spdif_mask =
 {
 	.access =	SNDRV_CTL_ELEM_ACCESS_READ,
 	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,
@@ -2529,7 +2529,7 @@
 	return change;
 }
 
-static struct snd_kcontrol_new snd_trident_spdif_stream __devinitdata =
+static struct snd_kcontrol_new snd_trident_spdif_stream =
 {
 	.access =	SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
 	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,
@@ -2579,7 +2579,7 @@
 	return change;
 }
 
-static struct snd_kcontrol_new snd_trident_ac97_rear_control __devinitdata =
+static struct snd_kcontrol_new snd_trident_ac97_rear_control =
 {
 	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name =         "Rear Path",
@@ -2637,7 +2637,7 @@
 	return change;
 }
 
-static struct snd_kcontrol_new snd_trident_vol_music_control __devinitdata =
+static struct snd_kcontrol_new snd_trident_vol_music_control =
 {
 	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name =         "Music Playback Volume",
@@ -2648,7 +2648,7 @@
 	.tlv = { .p = db_scale_gvol },
 };
 
-static struct snd_kcontrol_new snd_trident_vol_wave_control __devinitdata =
+static struct snd_kcontrol_new snd_trident_vol_wave_control =
 {
 	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name =         "Wave Playback Volume",
@@ -2715,7 +2715,7 @@
 	return change;
 }
 
-static struct snd_kcontrol_new snd_trident_pcm_vol_control __devinitdata =
+static struct snd_kcontrol_new snd_trident_pcm_vol_control =
 {
 	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name =         "PCM Front Playback Volume",
@@ -2779,7 +2779,7 @@
 	return change;
 }
 
-static struct snd_kcontrol_new snd_trident_pcm_pan_control __devinitdata =
+static struct snd_kcontrol_new snd_trident_pcm_pan_control =
 {
 	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name =         "PCM Pan Playback Control",
@@ -2836,7 +2836,7 @@
 
 static const DECLARE_TLV_DB_SCALE(db_scale_crvol, -3175, 25, 1);
 
-static struct snd_kcontrol_new snd_trident_pcm_rvol_control __devinitdata =
+static struct snd_kcontrol_new snd_trident_pcm_rvol_control =
 {
 	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name =         "PCM Reverb Playback Volume",
@@ -2892,7 +2892,7 @@
 	return change;
 }
 
-static struct snd_kcontrol_new snd_trident_pcm_cvol_control __devinitdata =
+static struct snd_kcontrol_new snd_trident_pcm_cvol_control =
 {
 	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name =         "PCM Chorus Playback Volume",
@@ -2972,7 +2972,7 @@
   
   ---------------------------------------------------------------------------*/
 
-static int __devinit snd_trident_mixer(struct snd_trident * trident, int pcm_spdif_device)
+static int snd_trident_mixer(struct snd_trident *trident, int pcm_spdif_device)
 {
 	struct snd_ac97_template _ac97;
 	struct snd_card *card = trident->card;
@@ -3191,7 +3191,7 @@
 	}
 }
 
-int __devinit snd_trident_create_gameport(struct snd_trident *chip)
+int snd_trident_create_gameport(struct snd_trident *chip)
 {
 	struct gameport *gp;
 
@@ -3225,7 +3225,7 @@
 	}
 }
 #else
-int __devinit snd_trident_create_gameport(struct snd_trident *chip) { return -ENOSYS; }
+int snd_trident_create_gameport(struct snd_trident *chip) { return -ENOSYS; }
 static inline void snd_trident_free_gameport(struct snd_trident *chip) { }
 #endif /* CONFIG_GAMEPORT */
 
@@ -3329,7 +3329,7 @@
 	}
 }
 
-static void __devinit snd_trident_proc_init(struct snd_trident * trident)
+static void snd_trident_proc_init(struct snd_trident *trident)
 {
 	struct snd_info_entry *entry;
 	const char *s = "trident";
@@ -3358,7 +3358,7 @@
   
   ---------------------------------------------------------------------------*/
 
-static int __devinit snd_trident_tlb_alloc(struct snd_trident *trident)
+static int snd_trident_tlb_alloc(struct snd_trident *trident)
 {
 	int i;
 
@@ -3539,7 +3539,7 @@
   
   ---------------------------------------------------------------------------*/
 
-int __devinit snd_trident_create(struct snd_card *card,
+int snd_trident_create(struct snd_card *card,
 		       struct pci_dev *pci,
 		       int pcm_streams,
 		       int pcm_spdif_device,
diff --git a/sound/pci/via82xx.c b/sound/pci/via82xx.c
index f0b4efd..6442f61 100644
--- a/sound/pci/via82xx.c
+++ b/sound/pci/via82xx.c
@@ -1437,7 +1437,7 @@
 /*
  * create pcm instances for VIA8233, 8233C and 8235 (not 8233A)
  */
-static int __devinit snd_via8233_pcm_new(struct via82xx *chip)
+static int snd_via8233_pcm_new(struct via82xx *chip)
 {
 	struct snd_pcm *pcm;
 	struct snd_pcm_chmap *chmap;
@@ -1505,7 +1505,7 @@
 /*
  * create pcm instances for VIA8233A
  */
-static int __devinit snd_via8233a_pcm_new(struct via82xx *chip)
+static int snd_via8233a_pcm_new(struct via82xx *chip)
 {
 	struct snd_pcm *pcm;
 	struct snd_pcm_chmap *chmap;
@@ -1566,7 +1566,7 @@
 /*
  * create a pcm instance for via686a/b
  */
-static int __devinit snd_via686_pcm_new(struct via82xx *chip)
+static int snd_via686_pcm_new(struct via82xx *chip)
 {
 	struct snd_pcm *pcm;
 	int err;
@@ -1643,7 +1643,7 @@
 	return val != oval;
 }
 
-static struct snd_kcontrol_new snd_via8233_capture_source __devinitdata = {
+static struct snd_kcontrol_new snd_via8233_capture_source = {
 	.name = "Input Source Select",
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.info = snd_via8233_capture_source_info,
@@ -1683,7 +1683,7 @@
 	return 0;
 }
 
-static struct snd_kcontrol_new snd_via8233_dxs3_spdif_control __devinitdata = {
+static struct snd_kcontrol_new snd_via8233_dxs3_spdif_control = {
 	.name = SNDRV_CTL_NAME_IEC958("Output ",NONE,SWITCH),
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.info = snd_via8233_dxs3_spdif_info,
@@ -1772,7 +1772,7 @@
 
 static const DECLARE_TLV_DB_SCALE(db_scale_dxs, -4650, 150, 1);
 
-static struct snd_kcontrol_new snd_via8233_pcmdxs_volume_control __devinitdata = {
+static struct snd_kcontrol_new snd_via8233_pcmdxs_volume_control = {
 	.name = "PCM Playback Volume",
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
@@ -1783,7 +1783,7 @@
 	.tlv = { .p = db_scale_dxs }
 };
 
-static struct snd_kcontrol_new snd_via8233_dxs_volume_control __devinitdata = {
+static struct snd_kcontrol_new snd_via8233_dxs_volume_control = {
 	.iface = SNDRV_CTL_ELEM_IFACE_PCM,
 	.device = 0,
 	/* .subdevice set later */
@@ -1895,7 +1895,7 @@
 	{ } /* terminator */
 };
 
-static int __devinit snd_via82xx_mixer_new(struct via82xx *chip, const char *quirk_override)
+static int snd_via82xx_mixer_new(struct via82xx *chip, const char *quirk_override)
 {
 	struct snd_ac97_template ac97;
 	int err;
@@ -1930,7 +1930,7 @@
 
 #ifdef SUPPORT_JOYSTICK
 #define JOYSTICK_ADDR	0x200
-static int __devinit snd_via686_create_gameport(struct via82xx *chip, unsigned char *legacy)
+static int snd_via686_create_gameport(struct via82xx *chip, unsigned char *legacy)
 {
 	struct gameport *gp;
 	struct resource *r;
@@ -1990,7 +1990,7 @@
  *
  */
 
-static int __devinit snd_via8233_init_misc(struct via82xx *chip)
+static int snd_via8233_init_misc(struct via82xx *chip)
 {
 	int i, err, caps;
 	unsigned char val;
@@ -2047,7 +2047,7 @@
 	return 0;
 }
 
-static int __devinit snd_via686_init_misc(struct via82xx *chip)
+static int snd_via686_init_misc(struct via82xx *chip)
 {
 	unsigned char legacy, legacy_cfg;
 	int rev_h = 0;
@@ -2137,7 +2137,7 @@
 	}
 }
 
-static void __devinit snd_via82xx_proc_init(struct via82xx *chip)
+static void snd_via82xx_proc_init(struct via82xx *chip)
 {
 	struct snd_info_entry *entry;
 
@@ -2370,12 +2370,12 @@
 	return snd_via82xx_free(chip);
 }
 
-static int __devinit snd_via82xx_create(struct snd_card *card,
-					struct pci_dev *pci,
-					int chip_type,
-					int revision,
-					unsigned int ac97_clock,
-					struct via82xx ** r_via)
+static int snd_via82xx_create(struct snd_card *card,
+			      struct pci_dev *pci,
+			      int chip_type,
+			      int revision,
+			      unsigned int ac97_clock,
+			      struct via82xx **r_via)
 {
 	struct via82xx *chip;
 	int err;
@@ -2452,7 +2452,7 @@
 	char *name;
 	int type;
 };
-static struct via823x_info via823x_cards[] __devinitdata = {
+static struct via823x_info via823x_cards[] = {
 	{ VIA_REV_PRE_8233, "VIA 8233-Pre", TYPE_VIA8233 },
 	{ VIA_REV_8233C, "VIA 8233C", TYPE_VIA8233 },
 	{ VIA_REV_8233, "VIA 8233", TYPE_VIA8233 },
@@ -2466,7 +2466,7 @@
  * auto detection of DXS channel supports.
  */
 
-static struct snd_pci_quirk dxs_whitelist[] __devinitdata = {
+static struct snd_pci_quirk dxs_whitelist[] = {
 	SND_PCI_QUIRK(0x1005, 0x4710, "Avance Logic Mobo", VIA_DXS_ENABLE),
 	SND_PCI_QUIRK(0x1019, 0x0996, "ESC Mobo", VIA_DXS_48K),
 	SND_PCI_QUIRK(0x1019, 0x0a81, "ECS K7VTA3 v8.0", VIA_DXS_NO_VRA),
@@ -2510,7 +2510,7 @@
 	{ } /* terminator */
 };
 
-static int __devinit check_dxs_list(struct pci_dev *pci, int revision)
+static int check_dxs_list(struct pci_dev *pci, int revision)
 {
 	const struct snd_pci_quirk *w;
 
@@ -2535,8 +2535,8 @@
 	return VIA_DXS_48K;
 };
 
-static int __devinit snd_via82xx_probe(struct pci_dev *pci,
-				       const struct pci_device_id *pci_id)
+static int snd_via82xx_probe(struct pci_dev *pci,
+			     const struct pci_device_id *pci_id)
 {
 	struct snd_card *card;
 	struct via82xx *chip;
@@ -2643,7 +2643,7 @@
 	return err;
 }
 
-static void __devexit snd_via82xx_remove(struct pci_dev *pci)
+static void snd_via82xx_remove(struct pci_dev *pci)
 {
 	snd_card_free(pci_get_drvdata(pci));
 	pci_set_drvdata(pci, NULL);
@@ -2653,7 +2653,7 @@
 	.name = KBUILD_MODNAME,
 	.id_table = snd_via82xx_ids,
 	.probe = snd_via82xx_probe,
-	.remove = __devexit_p(snd_via82xx_remove),
+	.remove = snd_via82xx_remove,
 	.driver = {
 		.pm = SND_VIA82XX_PM_OPS,
 	},
diff --git a/sound/pci/via82xx_modem.c b/sound/pci/via82xx_modem.c
index 8e0efc4..4f5fd80 100644
--- a/sound/pci/via82xx_modem.c
+++ b/sound/pci/via82xx_modem.c
@@ -836,7 +836,7 @@
 /*
  * create a pcm instance for via686a/b
  */
-static int __devinit snd_via686_pcm_new(struct via82xx_modem *chip)
+static int snd_via686_pcm_new(struct via82xx_modem *chip)
 {
 	struct snd_pcm *pcm;
 	int err;
@@ -885,7 +885,7 @@
 }
 
 
-static int __devinit snd_via82xx_mixer_new(struct via82xx_modem *chip)
+static int snd_via82xx_mixer_new(struct via82xx_modem *chip)
 {
 	struct snd_ac97_template ac97;
 	int err;
@@ -928,7 +928,7 @@
 	}
 }
 
-static void __devinit snd_via82xx_proc_init(struct via82xx_modem *chip)
+static void snd_via82xx_proc_init(struct via82xx_modem *chip)
 {
 	struct snd_info_entry *entry;
 
@@ -1103,12 +1103,12 @@
 	return snd_via82xx_free(chip);
 }
 
-static int __devinit snd_via82xx_create(struct snd_card *card,
-					struct pci_dev *pci,
-					int chip_type,
-					int revision,
-					unsigned int ac97_clock,
-					struct via82xx_modem ** r_via)
+static int snd_via82xx_create(struct snd_card *card,
+			      struct pci_dev *pci,
+			      int chip_type,
+			      int revision,
+			      unsigned int ac97_clock,
+			      struct via82xx_modem **r_via)
 {
 	struct via82xx_modem *chip;
 	int err;
@@ -1168,8 +1168,8 @@
 }
 
 
-static int __devinit snd_via82xx_probe(struct pci_dev *pci,
-				       const struct pci_device_id *pci_id)
+static int snd_via82xx_probe(struct pci_dev *pci,
+			     const struct pci_device_id *pci_id)
 {
 	struct snd_card *card;
 	struct via82xx_modem *chip;
@@ -1224,7 +1224,7 @@
 	return err;
 }
 
-static void __devexit snd_via82xx_remove(struct pci_dev *pci)
+static void snd_via82xx_remove(struct pci_dev *pci)
 {
 	snd_card_free(pci_get_drvdata(pci));
 	pci_set_drvdata(pci, NULL);
@@ -1234,7 +1234,7 @@
 	.name = KBUILD_MODNAME,
 	.id_table = snd_via82xx_modem_ids,
 	.probe = snd_via82xx_probe,
-	.remove = __devexit_p(snd_via82xx_remove),
+	.remove = snd_via82xx_remove,
 	.driver = {
 		.pm = SND_VIA82XX_PM_OPS,
 	},
diff --git a/sound/pci/vx222/vx222.c b/sound/pci/vx222/vx222.c
index fdfbaf857..e2f1ab3 100644
--- a/sound/pci/vx222/vx222.c
+++ b/sound/pci/vx222/vx222.c
@@ -134,9 +134,9 @@
 }
 
 
-static int __devinit snd_vx222_create(struct snd_card *card, struct pci_dev *pci,
-				      struct snd_vx_hardware *hw,
-				      struct snd_vx222 **rchip)
+static int snd_vx222_create(struct snd_card *card, struct pci_dev *pci,
+			    struct snd_vx_hardware *hw,
+			    struct snd_vx222 **rchip)
 {
 	struct vx_core *chip;
 	struct snd_vx222 *vx;
@@ -188,8 +188,8 @@
 }
 
 
-static int __devinit snd_vx222_probe(struct pci_dev *pci,
-				     const struct pci_device_id *pci_id)
+static int snd_vx222_probe(struct pci_dev *pci,
+			   const struct pci_device_id *pci_id)
 {
 	static int dev;
 	struct snd_card *card;
@@ -251,7 +251,7 @@
 	return 0;
 }
 
-static void __devexit snd_vx222_remove(struct pci_dev *pci)
+static void snd_vx222_remove(struct pci_dev *pci)
 {
 	snd_card_free(pci_get_drvdata(pci));
 	pci_set_drvdata(pci, NULL);
@@ -300,7 +300,7 @@
 	.name = KBUILD_MODNAME,
 	.id_table = snd_vx222_ids,
 	.probe = snd_vx222_probe,
-	.remove = __devexit_p(snd_vx222_remove),
+	.remove = snd_vx222_remove,
 	.driver = {
 		.pm = SND_VX222_PM_OPS,
 	},
diff --git a/sound/pci/ymfpci/ymfpci.c b/sound/pci/ymfpci/ymfpci.c
index e01fe34..01c4965 100644
--- a/sound/pci/ymfpci/ymfpci.c
+++ b/sound/pci/ymfpci/ymfpci.c
@@ -79,8 +79,8 @@
 MODULE_DEVICE_TABLE(pci, snd_ymfpci_ids);
 
 #ifdef SUPPORT_JOYSTICK
-static int __devinit snd_ymfpci_create_gameport(struct snd_ymfpci *chip, int dev,
-						int legacy_ctrl, int legacy_ctrl2)
+static int snd_ymfpci_create_gameport(struct snd_ymfpci *chip, int dev,
+				      int legacy_ctrl, int legacy_ctrl2)
 {
 	struct gameport *gp;
 	struct resource *r = NULL;
@@ -167,8 +167,8 @@
 void snd_ymfpci_free_gameport(struct snd_ymfpci *chip) { }
 #endif /* SUPPORT_JOYSTICK */
 
-static int __devinit snd_card_ymfpci_probe(struct pci_dev *pci,
-					   const struct pci_device_id *pci_id)
+static int snd_card_ymfpci_probe(struct pci_dev *pci,
+				 const struct pci_device_id *pci_id)
 {
 	static int dev;
 	struct snd_card *card;
@@ -344,7 +344,7 @@
 	return 0;
 }
 
-static void __devexit snd_card_ymfpci_remove(struct pci_dev *pci)
+static void snd_card_ymfpci_remove(struct pci_dev *pci)
 {
 	snd_card_free(pci_get_drvdata(pci));
 	pci_set_drvdata(pci, NULL);
@@ -354,7 +354,7 @@
 	.name = KBUILD_MODNAME,
 	.id_table = snd_ymfpci_ids,
 	.probe = snd_card_ymfpci_probe,
-	.remove = __devexit_p(snd_card_ymfpci_remove),
+	.remove = snd_card_ymfpci_remove,
 #ifdef CONFIG_PM_SLEEP
 	.driver = {
 		.pm = &snd_ymfpci_pm,
diff --git a/sound/pci/ymfpci/ymfpci_main.c b/sound/pci/ymfpci/ymfpci_main.c
index 3a6f03f..22056c5 100644
--- a/sound/pci/ymfpci/ymfpci_main.c
+++ b/sound/pci/ymfpci/ymfpci_main.c
@@ -25,7 +25,6 @@
 #include <linux/pci.h>
 #include <linux/sched.h>
 #include <linux/slab.h>
-#include <linux/vmalloc.h>
 #include <linux/mutex.h>
 #include <linux/module.h>
 
@@ -598,7 +597,7 @@
 	}
 }
 
-static int __devinit snd_ymfpci_ac3_init(struct snd_ymfpci *chip)
+static int snd_ymfpci_ac3_init(struct snd_ymfpci *chip)
 {
 	if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci),
 				4096, &chip->ac3_tmp_base) < 0)
@@ -1144,7 +1143,7 @@
 	.pointer =		snd_ymfpci_capture_pointer,
 };
 
-int __devinit snd_ymfpci_pcm(struct snd_ymfpci *chip, int device, struct snd_pcm ** rpcm)
+int snd_ymfpci_pcm(struct snd_ymfpci *chip, int device, struct snd_pcm **rpcm)
 {
 	struct snd_pcm *pcm;
 	int err;
@@ -1187,7 +1186,7 @@
 	.pointer =		snd_ymfpci_capture_pointer,
 };
 
-int __devinit snd_ymfpci_pcm2(struct snd_ymfpci *chip, int device, struct snd_pcm ** rpcm)
+int snd_ymfpci_pcm2(struct snd_ymfpci *chip, int device, struct snd_pcm **rpcm)
 {
 	struct snd_pcm *pcm;
 	int err;
@@ -1225,7 +1224,8 @@
 	.pointer =		snd_ymfpci_playback_pointer,
 };
 
-int __devinit snd_ymfpci_pcm_spdif(struct snd_ymfpci *chip, int device, struct snd_pcm ** rpcm)
+int snd_ymfpci_pcm_spdif(struct snd_ymfpci *chip, int device,
+			 struct snd_pcm **rpcm)
 {
 	struct snd_pcm *pcm;
 	int err;
@@ -1270,7 +1270,8 @@
 	{ }
 };
 
-int __devinit snd_ymfpci_pcm_4ch(struct snd_ymfpci *chip, int device, struct snd_pcm ** rpcm)
+int snd_ymfpci_pcm_4ch(struct snd_ymfpci *chip, int device,
+		       struct snd_pcm **rpcm)
 {
 	struct snd_pcm *pcm;
 	int err;
@@ -1339,7 +1340,7 @@
 	return change;
 }
 
-static struct snd_kcontrol_new snd_ymfpci_spdif_default __devinitdata =
+static struct snd_kcontrol_new snd_ymfpci_spdif_default =
 {
 	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,
 	.name =         SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
@@ -1367,7 +1368,7 @@
 	return 0;
 }
 
-static struct snd_kcontrol_new snd_ymfpci_spdif_mask __devinitdata =
+static struct snd_kcontrol_new snd_ymfpci_spdif_mask =
 {
 	.access =	SNDRV_CTL_ELEM_ACCESS_READ,
 	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,
@@ -1414,7 +1415,7 @@
 	return change;
 }
 
-static struct snd_kcontrol_new snd_ymfpci_spdif_stream __devinitdata =
+static struct snd_kcontrol_new snd_ymfpci_spdif_stream =
 {
 	.access =	SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
 	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,
@@ -1462,7 +1463,7 @@
 	return reg != old_reg;
 }
 
-static struct snd_kcontrol_new snd_ymfpci_drec_source __devinitdata = {
+static struct snd_kcontrol_new snd_ymfpci_drec_source = {
 	.access =	SNDRV_CTL_ELEM_ACCESS_READWRITE,
 	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name =		"Direct Recording Source",
@@ -1632,7 +1633,7 @@
 	return change;
 }
 
-static struct snd_kcontrol_new snd_ymfpci_dup4ch __devinitdata = {
+static struct snd_kcontrol_new snd_ymfpci_dup4ch = {
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name = "4ch Duplication",
 	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
@@ -1641,7 +1642,7 @@
 	.put = snd_ymfpci_put_dup4ch,
 };
 
-static struct snd_kcontrol_new snd_ymfpci_controls[] __devinitdata = {
+static struct snd_kcontrol_new snd_ymfpci_controls[] = {
 {
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name = "Wave Playback Volume",
@@ -1735,7 +1736,7 @@
 	return 0;
 }
 
-static struct snd_kcontrol_new snd_ymfpci_rear_shared __devinitdata = {
+static struct snd_kcontrol_new snd_ymfpci_rear_shared = {
 	.name = "Shared Rear/Line-In Switch",
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.info = snd_ymfpci_gpio_sw_info,
@@ -1799,7 +1800,7 @@
 	return 0;
 }
 
-static struct snd_kcontrol_new snd_ymfpci_pcm_volume __devinitdata = {
+static struct snd_kcontrol_new snd_ymfpci_pcm_volume = {
 	.iface = SNDRV_CTL_ELEM_IFACE_PCM,
 	.name = "PCM Playback Volume",
 	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
@@ -1826,7 +1827,7 @@
 	chip->ac97 = NULL;
 }
 
-int __devinit snd_ymfpci_mixer(struct snd_ymfpci *chip, int rear_switch)
+int snd_ymfpci_mixer(struct snd_ymfpci *chip, int rear_switch)
 {
 	struct snd_ac97_template ac97;
 	struct snd_kcontrol *kctl;
@@ -1970,7 +1971,7 @@
 	.precise_resolution = snd_ymfpci_timer_precise_resolution,
 };
 
-int __devinit snd_ymfpci_timer(struct snd_ymfpci *chip, int device)
+int snd_ymfpci_timer(struct snd_ymfpci *chip, int device)
 {
 	struct snd_timer *timer = NULL;
 	struct snd_timer_id tid;
@@ -2006,7 +2007,7 @@
 		snd_iprintf(buffer, "%04x: %04x\n", i, snd_ymfpci_readl(chip, i));
 }
 
-static int __devinit snd_ymfpci_proc_init(struct snd_card *card, struct snd_ymfpci *chip)
+static int snd_ymfpci_proc_init(struct snd_card *card, struct snd_ymfpci *chip)
 {
 	struct snd_info_entry *entry;
 	
@@ -2128,7 +2129,7 @@
 	snd_ymfpci_enable_dsp(chip);
 }
 
-static int __devinit snd_ymfpci_memalloc(struct snd_ymfpci *chip)
+static int snd_ymfpci_memalloc(struct snd_ymfpci *chip)
 {
 	long size, playback_ctrl_size;
 	int voice, bank, reg;
@@ -2261,7 +2262,7 @@
 #endif
 
 #ifdef CONFIG_PM_SLEEP
-	vfree(chip->saved_regs);
+	kfree(chip->saved_regs);
 #endif
 	if (chip->irq >= 0)
 		free_irq(chip->irq, chip);
@@ -2394,10 +2395,10 @@
 SIMPLE_DEV_PM_OPS(snd_ymfpci_pm, snd_ymfpci_suspend, snd_ymfpci_resume);
 #endif /* CONFIG_PM_SLEEP */
 
-int __devinit snd_ymfpci_create(struct snd_card *card,
-				struct pci_dev * pci,
-				unsigned short old_legacy_ctrl,
-				struct snd_ymfpci ** rchip)
+int snd_ymfpci_create(struct snd_card *card,
+		      struct pci_dev *pci,
+		      unsigned short old_legacy_ctrl,
+		      struct snd_ymfpci **rchip)
 {
 	struct snd_ymfpci *chip;
 	int err;
@@ -2471,7 +2472,8 @@
 	}
 
 #ifdef CONFIG_PM_SLEEP
-	chip->saved_regs = vmalloc(YDSXGR_NUM_SAVED_REGS * sizeof(u32));
+	chip->saved_regs = kmalloc(YDSXGR_NUM_SAVED_REGS * sizeof(u32),
+				   GFP_KERNEL);
 	if (chip->saved_regs == NULL) {
 		snd_ymfpci_free(chip);
 		return -ENOMEM;
diff --git a/sound/ppc/awacs.c b/sound/ppc/awacs.c
index b366793..5fbf5db 100644
--- a/sound/ppc/awacs.c
+++ b/sound/ppc/awacs.c
@@ -477,7 +477,7 @@
 #define AMP_CH_SPK	0
 #define AMP_CH_HD	1
 
-static struct snd_kcontrol_new snd_pmac_awacs_amp_vol[] __devinitdata = {
+static struct snd_kcontrol_new snd_pmac_awacs_amp_vol[] = {
 	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	  .name = "Speaker Playback Volume",
 	  .info = snd_pmac_awacs_info_volume_amp,
@@ -514,7 +514,7 @@
 	},
 };
 
-static struct snd_kcontrol_new snd_pmac_awacs_amp_hp_sw __devinitdata = {
+static struct snd_kcontrol_new snd_pmac_awacs_amp_hp_sw = {
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name = "Headphone Playback Switch",
 	.info = snd_pmac_boolean_stereo_info,
@@ -523,7 +523,7 @@
 	.private_value = AMP_CH_HD,
 };
 
-static struct snd_kcontrol_new snd_pmac_awacs_amp_spk_sw __devinitdata = {
+static struct snd_kcontrol_new snd_pmac_awacs_amp_spk_sw = {
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name = "Speaker Playback Switch",
 	.info = snd_pmac_boolean_stereo_info,
@@ -595,46 +595,46 @@
 /*
  * lists of mixer elements
  */
-static struct snd_kcontrol_new snd_pmac_awacs_mixers[] __devinitdata = {
+static struct snd_kcontrol_new snd_pmac_awacs_mixers[] = {
 	AWACS_SWITCH("Master Capture Switch", 1, SHIFT_LOOPTHRU, 0),
 	AWACS_VOLUME("Master Capture Volume", 0, 4, 0),
 /*	AWACS_SWITCH("Unknown Playback Switch", 6, SHIFT_PAROUT0, 0), */
 };
 
-static struct snd_kcontrol_new snd_pmac_screamer_mixers_beige[] __devinitdata = {
+static struct snd_kcontrol_new snd_pmac_screamer_mixers_beige[] = {
 	AWACS_VOLUME("Master Playback Volume", 2, 6, 1),
 	AWACS_VOLUME("Play-through Playback Volume", 5, 6, 1),
 	AWACS_SWITCH("Line Capture Switch", 0, SHIFT_MUX_MIC, 0),
 	AWACS_SWITCH("CD Capture Switch", 0, SHIFT_MUX_LINE, 0),
 };
 
-static struct snd_kcontrol_new snd_pmac_screamer_mixers_lo[] __devinitdata = {
+static struct snd_kcontrol_new snd_pmac_screamer_mixers_lo[] = {
 	AWACS_VOLUME("Line out Playback Volume", 2, 6, 1),
 };
 
-static struct snd_kcontrol_new snd_pmac_screamer_mixers_imac[] __devinitdata = {
+static struct snd_kcontrol_new snd_pmac_screamer_mixers_imac[] = {
 	AWACS_VOLUME("Play-through Playback Volume", 5, 6, 1),
 	AWACS_SWITCH("CD Capture Switch", 0, SHIFT_MUX_CD, 0),
 };
 
-static struct snd_kcontrol_new snd_pmac_screamer_mixers_g4agp[] __devinitdata = {
+static struct snd_kcontrol_new snd_pmac_screamer_mixers_g4agp[] = {
 	AWACS_VOLUME("Line out Playback Volume", 2, 6, 1),
 	AWACS_VOLUME("Master Playback Volume", 5, 6, 1),
 	AWACS_SWITCH("CD Capture Switch", 0, SHIFT_MUX_CD, 0),
 	AWACS_SWITCH("Line Capture Switch", 0, SHIFT_MUX_MIC, 0),
 };
 
-static struct snd_kcontrol_new snd_pmac_awacs_mixers_pmac7500[] __devinitdata = {
+static struct snd_kcontrol_new snd_pmac_awacs_mixers_pmac7500[] = {
 	AWACS_VOLUME("Line out Playback Volume", 2, 6, 1),
 	AWACS_SWITCH("CD Capture Switch", 0, SHIFT_MUX_CD, 0),
 	AWACS_SWITCH("Line Capture Switch", 0, SHIFT_MUX_MIC, 0),
 };
 
-static struct snd_kcontrol_new snd_pmac_awacs_mixers_pmac5500[] __devinitdata = {
+static struct snd_kcontrol_new snd_pmac_awacs_mixers_pmac5500[] = {
 	AWACS_VOLUME("Headphone Playback Volume", 2, 6, 1),
 };
 
-static struct snd_kcontrol_new snd_pmac_awacs_mixers_pmac[] __devinitdata = {
+static struct snd_kcontrol_new snd_pmac_awacs_mixers_pmac[] = {
 	AWACS_VOLUME("Master Playback Volume", 2, 6, 1),
 	AWACS_SWITCH("CD Capture Switch", 0, SHIFT_MUX_CD, 0),
 };
@@ -642,34 +642,34 @@
 /* FIXME: is this correct order?
  * screamer (powerbook G3 pismo) seems to have different bits...
  */
-static struct snd_kcontrol_new snd_pmac_awacs_mixers2[] __devinitdata = {
+static struct snd_kcontrol_new snd_pmac_awacs_mixers2[] = {
 	AWACS_SWITCH("Line Capture Switch", 0, SHIFT_MUX_LINE, 0),
 	AWACS_SWITCH("Mic Capture Switch", 0, SHIFT_MUX_MIC, 0),
 };
 
-static struct snd_kcontrol_new snd_pmac_screamer_mixers2[] __devinitdata = {
+static struct snd_kcontrol_new snd_pmac_screamer_mixers2[] = {
 	AWACS_SWITCH("Line Capture Switch", 0, SHIFT_MUX_MIC, 0),
 	AWACS_SWITCH("Mic Capture Switch", 0, SHIFT_MUX_LINE, 0),
 };
 
-static struct snd_kcontrol_new snd_pmac_awacs_mixers2_pmac5500[] __devinitdata = {
+static struct snd_kcontrol_new snd_pmac_awacs_mixers2_pmac5500[] = {
 	AWACS_SWITCH("CD Capture Switch", 0, SHIFT_MUX_CD, 0),
 };
 
-static struct snd_kcontrol_new snd_pmac_awacs_master_sw __devinitdata =
+static struct snd_kcontrol_new snd_pmac_awacs_master_sw =
 AWACS_SWITCH("Master Playback Switch", 1, SHIFT_HDMUTE, 1);
 
-static struct snd_kcontrol_new snd_pmac_awacs_master_sw_imac __devinitdata =
+static struct snd_kcontrol_new snd_pmac_awacs_master_sw_imac =
 AWACS_SWITCH("Line out Playback Switch", 1, SHIFT_HDMUTE, 1);
 
-static struct snd_kcontrol_new snd_pmac_awacs_master_sw_pmac5500 __devinitdata =
+static struct snd_kcontrol_new snd_pmac_awacs_master_sw_pmac5500 =
 AWACS_SWITCH("Headphone Playback Switch", 1, SHIFT_HDMUTE, 1);
 
-static struct snd_kcontrol_new snd_pmac_awacs_mic_boost[] __devinitdata = {
+static struct snd_kcontrol_new snd_pmac_awacs_mic_boost[] = {
 	AWACS_SWITCH("Mic Boost Capture Switch", 0, SHIFT_GAINLINE, 0),
 };
 
-static struct snd_kcontrol_new snd_pmac_screamer_mic_boost[] __devinitdata = {
+static struct snd_kcontrol_new snd_pmac_screamer_mic_boost[] = {
 	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	  .name = "Mic Boost Capture Volume",
 	  .info = snd_pmac_screamer_mic_boost_info,
@@ -678,34 +678,34 @@
 	},
 };
 
-static struct snd_kcontrol_new snd_pmac_awacs_mic_boost_pmac7500[] __devinitdata =
+static struct snd_kcontrol_new snd_pmac_awacs_mic_boost_pmac7500[] =
 {
 	AWACS_SWITCH("Line Boost Capture Switch", 0, SHIFT_GAINLINE, 0),
 };
 
-static struct snd_kcontrol_new snd_pmac_screamer_mic_boost_beige[] __devinitdata =
+static struct snd_kcontrol_new snd_pmac_screamer_mic_boost_beige[] =
 {
 	AWACS_SWITCH("Line Boost Capture Switch", 0, SHIFT_GAINLINE, 0),
 	AWACS_SWITCH("CD Boost Capture Switch", 6, SHIFT_MIC_BOOST, 0),
 };
 
-static struct snd_kcontrol_new snd_pmac_screamer_mic_boost_imac[] __devinitdata =
+static struct snd_kcontrol_new snd_pmac_screamer_mic_boost_imac[] =
 {
 	AWACS_SWITCH("Line Boost Capture Switch", 0, SHIFT_GAINLINE, 0),
 	AWACS_SWITCH("Mic Boost Capture Switch", 6, SHIFT_MIC_BOOST, 0),
 };
 
-static struct snd_kcontrol_new snd_pmac_awacs_speaker_vol[] __devinitdata = {
+static struct snd_kcontrol_new snd_pmac_awacs_speaker_vol[] = {
 	AWACS_VOLUME("Speaker Playback Volume", 4, 6, 1),
 };
 
-static struct snd_kcontrol_new snd_pmac_awacs_speaker_sw __devinitdata =
+static struct snd_kcontrol_new snd_pmac_awacs_speaker_sw =
 AWACS_SWITCH("Speaker Playback Switch", 1, SHIFT_SPKMUTE, 1);
 
-static struct snd_kcontrol_new snd_pmac_awacs_speaker_sw_imac1 __devinitdata =
+static struct snd_kcontrol_new snd_pmac_awacs_speaker_sw_imac1 =
 AWACS_SWITCH("Speaker Playback Switch", 1, SHIFT_PAROUT1, 1);
 
-static struct snd_kcontrol_new snd_pmac_awacs_speaker_sw_imac2 __devinitdata =
+static struct snd_kcontrol_new snd_pmac_awacs_speaker_sw_imac2 =
 AWACS_SWITCH("Speaker Playback Switch", 1, SHIFT_PAROUT1, 0);
 
 
@@ -872,7 +872,7 @@
 /*
  * initialize chip
  */
-int __devinit
+int
 snd_pmac_awacs_init(struct snd_pmac *chip)
 {
 	int pm7500 = IS_PM7500;
diff --git a/sound/ppc/beep.c b/sound/ppc/beep.c
index a9d3507..0040f04 100644
--- a/sound/ppc/beep.c
+++ b/sound/ppc/beep.c
@@ -215,7 +215,7 @@
 };
 
 /* Initialize beep stuff */
-int __devinit snd_pmac_attach_beep(struct snd_pmac *chip)
+int snd_pmac_attach_beep(struct snd_pmac *chip)
 {
 	struct pmac_beep *beep;
 	struct input_dev *input_dev;
diff --git a/sound/ppc/burgundy.c b/sound/ppc/burgundy.c
index 00e2d51..cb4f0a5 100644
--- a/sound/ppc/burgundy.c
+++ b/sound/ppc/burgundy.c
@@ -467,7 +467,7 @@
 /*
  * Burgundy mixers
  */
-static struct snd_kcontrol_new snd_pmac_burgundy_mixers[] __devinitdata = {
+static struct snd_kcontrol_new snd_pmac_burgundy_mixers[] = {
 	BURGUNDY_VOLUME_W("Master Playback Volume", 0,
 			MASK_ADDR_BURGUNDY_MASTER_VOLUME, 8),
 	BURGUNDY_VOLUME_W("CD Capture Volume", 0,
@@ -495,7 +495,7 @@
  */	BURGUNDY_SWITCH_B("PCM Capture Switch", 0,
 			MASK_ADDR_BURGUNDY_HOSTIFEH, 0x01, 0, 0)
 };
-static struct snd_kcontrol_new snd_pmac_burgundy_mixers_imac[] __devinitdata = {
+static struct snd_kcontrol_new snd_pmac_burgundy_mixers_imac[] = {
 	BURGUNDY_VOLUME_W("Line in Capture Volume", 0,
 			MASK_ADDR_BURGUNDY_VOLLINE, 16),
 	BURGUNDY_VOLUME_W("Mic Capture Volume", 0,
@@ -521,7 +521,7 @@
 	BURGUNDY_SWITCH_B("Mic Boost Capture Switch", 0,
 			MASK_ADDR_BURGUNDY_INPBOOST, 0x40, 0x80, 1)
 };
-static struct snd_kcontrol_new snd_pmac_burgundy_mixers_pmac[] __devinitdata = {
+static struct snd_kcontrol_new snd_pmac_burgundy_mixers_pmac[] = {
 	BURGUNDY_VOLUME_W("Line in Capture Volume", 0,
 			MASK_ADDR_BURGUNDY_VOLMIC, 16),
 	BURGUNDY_VOLUME_B("Line in Gain Capture Volume", 0,
@@ -537,33 +537,33 @@
 /*	BURGUNDY_SWITCH_B("Line in Boost Capture Switch", 0,
  *		MASK_ADDR_BURGUNDY_INPBOOST, 0x40, 0x80, 1) */
 };
-static struct snd_kcontrol_new snd_pmac_burgundy_master_sw_imac __devinitdata =
+static struct snd_kcontrol_new snd_pmac_burgundy_master_sw_imac =
 BURGUNDY_SWITCH_B("Master Playback Switch", 0,
 	MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES,
 	BURGUNDY_OUTPUT_LEFT | BURGUNDY_LINEOUT_LEFT | BURGUNDY_HP_LEFT,
 	BURGUNDY_OUTPUT_RIGHT | BURGUNDY_LINEOUT_RIGHT | BURGUNDY_HP_RIGHT, 1);
-static struct snd_kcontrol_new snd_pmac_burgundy_master_sw_pmac __devinitdata =
+static struct snd_kcontrol_new snd_pmac_burgundy_master_sw_pmac =
 BURGUNDY_SWITCH_B("Master Playback Switch", 0,
 	MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES,
 	BURGUNDY_OUTPUT_INTERN
 	| BURGUNDY_OUTPUT_LEFT, BURGUNDY_OUTPUT_RIGHT, 1);
-static struct snd_kcontrol_new snd_pmac_burgundy_speaker_sw_imac __devinitdata =
+static struct snd_kcontrol_new snd_pmac_burgundy_speaker_sw_imac =
 BURGUNDY_SWITCH_B("Speaker Playback Switch", 0,
 	MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES,
 	BURGUNDY_OUTPUT_LEFT, BURGUNDY_OUTPUT_RIGHT, 1);
-static struct snd_kcontrol_new snd_pmac_burgundy_speaker_sw_pmac __devinitdata =
+static struct snd_kcontrol_new snd_pmac_burgundy_speaker_sw_pmac =
 BURGUNDY_SWITCH_B("Speaker Playback Switch", 0,
 	MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES,
 	BURGUNDY_OUTPUT_INTERN, 0, 0);
-static struct snd_kcontrol_new snd_pmac_burgundy_line_sw_imac __devinitdata =
+static struct snd_kcontrol_new snd_pmac_burgundy_line_sw_imac =
 BURGUNDY_SWITCH_B("Line out Playback Switch", 0,
 	MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES,
 	BURGUNDY_LINEOUT_LEFT, BURGUNDY_LINEOUT_RIGHT, 1);
-static struct snd_kcontrol_new snd_pmac_burgundy_line_sw_pmac __devinitdata =
+static struct snd_kcontrol_new snd_pmac_burgundy_line_sw_pmac =
 BURGUNDY_SWITCH_B("Line out Playback Switch", 0,
 	MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES,
 	BURGUNDY_OUTPUT_LEFT, BURGUNDY_OUTPUT_RIGHT, 1);
-static struct snd_kcontrol_new snd_pmac_burgundy_hp_sw_imac __devinitdata =
+static struct snd_kcontrol_new snd_pmac_burgundy_hp_sw_imac =
 BURGUNDY_SWITCH_B("Headphone Playback Switch", 0,
 	MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES,
 	BURGUNDY_HP_LEFT, BURGUNDY_HP_RIGHT, 1);
@@ -617,7 +617,7 @@
 /*
  * initialize burgundy
  */
-int __devinit snd_pmac_burgundy_init(struct snd_pmac *chip)
+int snd_pmac_burgundy_init(struct snd_pmac *chip)
 {
 	int imac = of_machine_is_compatible("iMac");
 	int i, err;
diff --git a/sound/ppc/daca.c b/sound/ppc/daca.c
index 24200b7..b865262 100644
--- a/sound/ppc/daca.c
+++ b/sound/ppc/daca.c
@@ -244,7 +244,7 @@
 }
 
 /* exported */
-int __devinit snd_pmac_daca_init(struct snd_pmac *chip)
+int snd_pmac_daca_init(struct snd_pmac *chip)
 {
 	int i, err;
 	struct pmac_daca *mix;
diff --git a/sound/ppc/keywest.c b/sound/ppc/keywest.c
index 4080bec..01aecc2 100644
--- a/sound/ppc/keywest.c
+++ b/sound/ppc/keywest.c
@@ -115,7 +115,7 @@
 	}
 }
 
-int __devinit snd_pmac_tumbler_post_init(void)
+int snd_pmac_tumbler_post_init(void)
 {
 	int err;
 	
@@ -130,7 +130,7 @@
 }
 
 /* exported */
-int __devinit snd_pmac_keywest_init(struct pmac_keywest *i2c)
+int snd_pmac_keywest_init(struct pmac_keywest *i2c)
 {
 	int err;
 
diff --git a/sound/ppc/pmac.c b/sound/ppc/pmac.c
index ab96cde..c93fbbb 100644
--- a/sound/ppc/pmac.c
+++ b/sound/ppc/pmac.c
@@ -702,7 +702,7 @@
 	.pointer =	snd_pmac_capture_pointer,
 };
 
-int __devinit snd_pmac_pcm_new(struct snd_pmac *chip)
+int snd_pmac_pcm_new(struct snd_pmac *chip)
 {
 	struct snd_pcm *pcm;
 	int err;
@@ -907,7 +907,7 @@
  * check the machine support byteswap (little-endian)
  */
 
-static void __devinit detect_byte_swap(struct snd_pmac *chip)
+static void detect_byte_swap(struct snd_pmac *chip)
 {
 	struct device_node *mio;
 
@@ -933,7 +933,7 @@
 /*
  * detect a sound chip
  */
-static int __devinit snd_pmac_detect(struct snd_pmac *chip)
+static int snd_pmac_detect(struct snd_pmac *chip)
 {
 	struct device_node *sound;
 	struct device_node *dn;
@@ -1146,7 +1146,7 @@
 	return 0;
 }
 
-static struct snd_kcontrol_new auto_mute_controls[] __devinitdata = {
+static struct snd_kcontrol_new auto_mute_controls[] = {
 	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	  .name = "Auto Mute Switch",
 	  .info = snd_pmac_boolean_mono_info,
@@ -1161,7 +1161,7 @@
 	},
 };
 
-int __devinit snd_pmac_add_automute(struct snd_pmac *chip)
+int snd_pmac_add_automute(struct snd_pmac *chip)
 {
 	int err;
 	chip->auto_mute = 1;
@@ -1178,7 +1178,7 @@
 /*
  * create and detect a pmac chip record
  */
-int __devinit snd_pmac_new(struct snd_card *card, struct snd_pmac **chip_return)
+int snd_pmac_new(struct snd_card *card, struct snd_pmac **chip_return)
 {
 	struct snd_pmac *chip;
 	struct device_node *np;
diff --git a/sound/ppc/powermac.c b/sound/ppc/powermac.c
index 210cafe..09fc848 100644
--- a/sound/ppc/powermac.c
+++ b/sound/ppc/powermac.c
@@ -51,7 +51,7 @@
 /*
  */
 
-static int __devinit snd_pmac_probe(struct platform_device *devptr)
+static int snd_pmac_probe(struct platform_device *devptr)
 {
 	struct snd_card *card;
 	struct snd_pmac *chip;
@@ -136,7 +136,7 @@
 }
 
 
-static int __devexit snd_pmac_remove(struct platform_device *devptr)
+static int snd_pmac_remove(struct platform_device *devptr)
 {
 	snd_card_free(platform_get_drvdata(devptr));
 	platform_set_drvdata(devptr, NULL);
@@ -168,7 +168,7 @@
 
 static struct platform_driver snd_pmac_driver = {
 	.probe		= snd_pmac_probe,
-	.remove		= __devexit_p(snd_pmac_remove),
+	.remove		= snd_pmac_remove,
 	.driver		= {
 		.name	= SND_PMAC_DRIVER,
 		.owner	= THIS_MODULE,
diff --git a/sound/ppc/snd_ps3.c b/sound/ppc/snd_ps3.c
index 9b18b52..8c7dcbe 100644
--- a/sound/ppc/snd_ps3.c
+++ b/sound/ppc/snd_ps3.c
@@ -786,7 +786,7 @@
 };
 
 
-static int __devinit snd_ps3_map_mmio(void)
+static int snd_ps3_map_mmio(void)
 {
 	the_card.mapped_mmio_vaddr =
 		ioremap(the_card.ps3_dev->m_region->bus_addr,
@@ -808,7 +808,7 @@
 	the_card.mapped_mmio_vaddr = NULL;
 }
 
-static int __devinit snd_ps3_allocate_irq(void)
+static int snd_ps3_allocate_irq(void)
 {
 	int ret;
 	u64 lpar_addr, lpar_size;
@@ -866,7 +866,7 @@
 	ps3_irq_plug_destroy(the_card.irq_no);
 }
 
-static void __devinit snd_ps3_audio_set_base_addr(uint64_t ioaddr_start)
+static void snd_ps3_audio_set_base_addr(uint64_t ioaddr_start)
 {
 	uint64_t val;
 	int ret;
@@ -882,7 +882,7 @@
 			ret);
 }
 
-static void __devinit snd_ps3_audio_fixup(struct snd_ps3_card_info *card)
+static void snd_ps3_audio_fixup(struct snd_ps3_card_info *card)
 {
 	/*
 	 * avsetting driver seems to never change the followings
@@ -906,7 +906,7 @@
 		   PS3_AUDIO_AO_3WMCTRL_ASOPLRCK_DEFAULT);
 }
 
-static int __devinit snd_ps3_init_avsetting(struct snd_ps3_card_info *card)
+static int snd_ps3_init_avsetting(struct snd_ps3_card_info *card)
 {
 	int ret;
 	pr_debug("%s: start\n", __func__);
@@ -928,7 +928,7 @@
 	return ret;
 }
 
-static int __devinit snd_ps3_driver_probe(struct ps3_system_bus_device *dev)
+static int snd_ps3_driver_probe(struct ps3_system_bus_device *dev)
 {
 	int i, ret;
 	u64 lpar_addr, lpar_size;
diff --git a/sound/ppc/tumbler.c b/sound/ppc/tumbler.c
index 9cea84c..b23354a 100644
--- a/sound/ppc/tumbler.c
+++ b/sound/ppc/tumbler.c
@@ -844,7 +844,7 @@
 
 /*
  */
-static struct snd_kcontrol_new tumbler_mixers[] __devinitdata = {
+static struct snd_kcontrol_new tumbler_mixers[] = {
 	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	  .name = "Master Playback Volume",
 	  .info = tumbler_info_master_volume,
@@ -868,7 +868,7 @@
 	},
 };
 
-static struct snd_kcontrol_new snapper_mixers[] __devinitdata = {
+static struct snd_kcontrol_new snapper_mixers[] = {
 	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	  .name = "Master Playback Volume",
 	  .info = tumbler_info_master_volume,
@@ -901,7 +901,7 @@
 	},
 };
 
-static struct snd_kcontrol_new tumbler_hp_sw __devinitdata = {
+static struct snd_kcontrol_new tumbler_hp_sw = {
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name = "Headphone Playback Switch",
 	.info = snd_pmac_boolean_mono_info,
@@ -909,7 +909,7 @@
 	.put = tumbler_put_mute_switch,
 	.private_value = TUMBLER_MUTE_HP,
 };
-static struct snd_kcontrol_new tumbler_speaker_sw __devinitdata = {
+static struct snd_kcontrol_new tumbler_speaker_sw = {
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name = "Speaker Playback Switch",
 	.info = snd_pmac_boolean_mono_info,
@@ -917,7 +917,7 @@
 	.put = tumbler_put_mute_switch,
 	.private_value = TUMBLER_MUTE_AMP,
 };
-static struct snd_kcontrol_new tumbler_lineout_sw __devinitdata = {
+static struct snd_kcontrol_new tumbler_lineout_sw = {
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name = "Line Out Playback Switch",
 	.info = snd_pmac_boolean_mono_info,
@@ -925,7 +925,7 @@
 	.put = tumbler_put_mute_switch,
 	.private_value = TUMBLER_MUTE_LINE,
 };
-static struct snd_kcontrol_new tumbler_drc_sw __devinitdata = {
+static struct snd_kcontrol_new tumbler_drc_sw = {
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name = "DRC Switch",
 	.info = snd_pmac_boolean_mono_info,
@@ -1276,7 +1276,7 @@
 #endif
 
 /* initialize tumbler */
-static int __devinit tumbler_init(struct snd_pmac *chip)
+static int tumbler_init(struct snd_pmac *chip)
 {
 	int irq;
 	struct pmac_tumbler *mix = chip->mixer_data;
@@ -1349,7 +1349,7 @@
 }
 
 /* exported */
-int __devinit snd_pmac_tumbler_init(struct snd_pmac *chip)
+int snd_pmac_tumbler_init(struct snd_pmac *chip)
 {
 	int i, err;
 	struct pmac_tumbler *mix;
diff --git a/sound/sh/aica.c b/sound/sh/aica.c
index d48b523..e59a73a 100644
--- a/sound/sh/aica.c
+++ b/sound/sh/aica.c
@@ -540,7 +540,7 @@
 	return 1;
 }
 
-static struct snd_kcontrol_new snd_aica_pcmswitch_control __devinitdata = {
+static struct snd_kcontrol_new snd_aica_pcmswitch_control = {
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name = "PCM Playback Switch",
 	.index = 0,
@@ -549,7 +549,7 @@
 	.put = aica_pcmswitch_put
 };
 
-static struct snd_kcontrol_new snd_aica_pcmvolume_control __devinitdata = {
+static struct snd_kcontrol_new snd_aica_pcmvolume_control = {
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name = "PCM Playback Volume",
 	.index = 0,
@@ -574,8 +574,7 @@
 	return err;
 }
 
-static int __devinit add_aicamixer_controls(struct snd_card_aica
-					    *dreamcastcard)
+static int add_aicamixer_controls(struct snd_card_aica *dreamcastcard)
 {
 	int err;
 	err = snd_ctl_add
@@ -591,7 +590,7 @@
 	return 0;
 }
 
-static int __devexit snd_aica_remove(struct platform_device *devptr)
+static int snd_aica_remove(struct platform_device *devptr)
 {
 	struct snd_card_aica *dreamcastcard;
 	dreamcastcard = platform_get_drvdata(devptr);
@@ -603,7 +602,7 @@
 	return 0;
 }
 
-static int __devinit snd_aica_probe(struct platform_device *devptr)
+static int snd_aica_probe(struct platform_device *devptr)
 {
 	int err;
 	struct snd_card_aica *dreamcastcard;
@@ -652,7 +651,7 @@
 
 static struct platform_driver snd_aica_driver = {
 	.probe = snd_aica_probe,
-	.remove = __devexit_p(snd_aica_remove),
+	.remove = snd_aica_remove,
 	.driver = {
 		.name = SND_AICA_DRIVER,
 		.owner	= THIS_MODULE,
diff --git a/sound/sh/sh_dac_audio.c b/sound/sh/sh_dac_audio.c
index 0a33947..e68c4fc 100644
--- a/sound/sh/sh_dac_audio.c
+++ b/sound/sh/sh_dac_audio.c
@@ -261,7 +261,7 @@
 	.mmap		= snd_pcm_lib_mmap_iomem,
 };
 
-static int __devinit snd_sh_dac_pcm(struct snd_sh_dac *chip, int device)
+static int snd_sh_dac_pcm(struct snd_sh_dac *chip, int device)
 {
 	int err;
 	struct snd_pcm *pcm;
@@ -346,9 +346,9 @@
 }
 
 /* create  --  chip-specific constructor for the cards components */
-static int __devinit snd_sh_dac_create(struct snd_card *card,
-				       struct platform_device *devptr,
-				       struct snd_sh_dac **rchip)
+static int snd_sh_dac_create(struct snd_card *card,
+			     struct platform_device *devptr,
+			     struct snd_sh_dac **rchip)
 {
 	struct snd_sh_dac *chip;
 	int err;
@@ -392,7 +392,7 @@
 }
 
 /* driver .probe  --  constructor */
-static int __devinit snd_sh_dac_probe(struct platform_device *devptr)
+static int snd_sh_dac_probe(struct platform_device *devptr)
 {
 	struct snd_sh_dac *chip;
 	struct snd_card *card;
diff --git a/sound/soc/atmel/Kconfig b/sound/soc/atmel/Kconfig
index 72b09cf..d1b691b 100644
--- a/sound/soc/atmel/Kconfig
+++ b/sound/soc/atmel/Kconfig
@@ -6,6 +6,14 @@
 	  the ATMEL SSC interface. You will also need
 	  to select the audio interfaces to support below.
 
+config SND_ATMEL_SOC_PDC
+	tristate
+	depends on SND_ATMEL_SOC
+
+config SND_ATMEL_SOC_DMA
+	tristate
+	depends on SND_ATMEL_SOC
+
 config SND_ATMEL_SOC_SSC
 	tristate
 	depends on SND_ATMEL_SOC
@@ -16,8 +24,8 @@
 
 config SND_AT91_SOC_SAM9G20_WM8731
 	tristate "SoC Audio support for WM8731-based At91sam9g20 evaluation board"
-	depends on ATMEL_SSC && ARCH_AT91SAM9G20 && SND_ATMEL_SOC && \
-                   AT91_PROGRAMMABLE_CLOCKS
+	depends on ATMEL_SSC && SND_ATMEL_SOC && AT91_PROGRAMMABLE_CLOCKS
+	select SND_ATMEL_SOC_PDC
 	select SND_ATMEL_SOC_SSC
 	select SND_SOC_WM8731
 	help
@@ -27,6 +35,7 @@
 config SND_AT91_SOC_AFEB9260
 	tristate "SoC Audio support for AFEB9260 board"
 	depends on ATMEL_SSC && ARCH_AT91 && MACH_AFEB9260 && SND_ATMEL_SOC
+	select SND_ATMEL_SOC_PDC
 	select SND_ATMEL_SOC_SSC
 	select SND_SOC_TLV320AIC23
 	help
diff --git a/sound/soc/atmel/Makefile b/sound/soc/atmel/Makefile
index a5c0bf1..41967cc 100644
--- a/sound/soc/atmel/Makefile
+++ b/sound/soc/atmel/Makefile
@@ -1,8 +1,12 @@
 # AT91 Platform Support
 snd-soc-atmel-pcm-objs := atmel-pcm.o
+snd-soc-atmel-pcm-pdc-objs := atmel-pcm-pdc.o
+snd-soc-atmel-pcm-dma-objs := atmel-pcm-dma.o
 snd-soc-atmel_ssc_dai-objs := atmel_ssc_dai.o
 
 obj-$(CONFIG_SND_ATMEL_SOC) += snd-soc-atmel-pcm.o
+obj-$(CONFIG_SND_ATMEL_SOC_PDC) += snd-soc-atmel-pcm-pdc.o
+obj-$(CONFIG_SND_ATMEL_SOC_DMA) += snd-soc-atmel-pcm-dma.o
 obj-$(CONFIG_SND_ATMEL_SOC_SSC) += snd-soc-atmel_ssc_dai.o
 
 # AT91 Machine Support
diff --git a/sound/soc/atmel/atmel-pcm-dma.c b/sound/soc/atmel/atmel-pcm-dma.c
new file mode 100644
index 0000000..30184a4
--- /dev/null
+++ b/sound/soc/atmel/atmel-pcm-dma.c
@@ -0,0 +1,240 @@
+/*
+ * atmel-pcm-dma.c  --  ALSA PCM DMA support for the Atmel SoC.
+ *
+ *  Copyright (C) 2012 Atmel
+ *
+ * Author: Bo Shen <voice.shen@atmel.com>
+ *
+ * Based on atmel-pcm by:
+ * Sedji Gaouaou <sedji.gaouaou@atmel.com>
+ * Copyright 2008 Atmel
+ *
+ * This program is free software; 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/module.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/dma-mapping.h>
+#include <linux/dmaengine.h>
+#include <linux/atmel-ssc.h>
+#include <linux/platform_data/dma-atmel.h>
+
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/dmaengine_pcm.h>
+
+#include "atmel-pcm.h"
+
+/*--------------------------------------------------------------------------*\
+ * Hardware definition
+\*--------------------------------------------------------------------------*/
+static const struct snd_pcm_hardware atmel_pcm_dma_hardware = {
+	.info			= SNDRV_PCM_INFO_MMAP |
+				  SNDRV_PCM_INFO_MMAP_VALID |
+				  SNDRV_PCM_INFO_INTERLEAVED |
+				  SNDRV_PCM_INFO_RESUME |
+				  SNDRV_PCM_INFO_PAUSE,
+	.formats		= SNDRV_PCM_FMTBIT_S16_LE,
+	.period_bytes_min	= 256,		/* lighting DMA overhead */
+	.period_bytes_max	= 2 * 0xffff,	/* if 2 bytes format */
+	.periods_min		= 8,
+	.periods_max		= 1024,		/* no limit */
+	.buffer_bytes_max	= ATMEL_SSC_DMABUF_SIZE,
+};
+
+/**
+ * atmel_pcm_dma_irq: SSC interrupt handler for DMAENGINE enabled SSC
+ *
+ * We use DMAENGINE to send/receive data to/from SSC so this ISR is only to
+ * check if any overrun occured.
+ */
+static void atmel_pcm_dma_irq(u32 ssc_sr,
+	struct snd_pcm_substream *substream)
+{
+	struct atmel_pcm_dma_params *prtd;
+
+	prtd = snd_dmaengine_pcm_get_data(substream);
+
+	if (ssc_sr & prtd->mask->ssc_error) {
+		if (snd_pcm_running(substream))
+			pr_warn("atmel-pcm: buffer %s on %s (SSC_SR=%#x)\n",
+				substream->stream == SNDRV_PCM_STREAM_PLAYBACK
+				? "underrun" : "overrun", prtd->name,
+				ssc_sr);
+
+		/* stop RX and capture: will be enabled again at restart */
+		ssc_writex(prtd->ssc->regs, SSC_CR, prtd->mask->ssc_disable);
+		snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN);
+
+		/* now drain RHR and read status to remove xrun condition */
+		ssc_readx(prtd->ssc->regs, SSC_RHR);
+		ssc_readx(prtd->ssc->regs, SSC_SR);
+	}
+}
+
+/*--------------------------------------------------------------------------*\
+ * DMAENGINE operations
+\*--------------------------------------------------------------------------*/
+static bool filter(struct dma_chan *chan, void *slave)
+{
+	struct at_dma_slave *sl = slave;
+
+	if (sl->dma_dev == chan->device->dev) {
+		chan->private = sl;
+		return true;
+	} else {
+		return false;
+	}
+}
+
+static int atmel_pcm_configure_dma(struct snd_pcm_substream *substream,
+	struct snd_pcm_hw_params *params)
+{
+	struct atmel_pcm_dma_params *prtd;
+	struct ssc_device *ssc;
+	struct dma_chan *dma_chan;
+	struct dma_slave_config slave_config;
+	int ret;
+
+	prtd = snd_dmaengine_pcm_get_data(substream);
+	ssc = prtd->ssc;
+
+	ret = snd_hwparams_to_dma_slave_config(substream, params,
+			&slave_config);
+	if (ret) {
+		pr_err("atmel-pcm: hwparams to dma slave configure failed\n");
+		return ret;
+	}
+
+	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+		slave_config.dst_addr = (dma_addr_t)ssc->phybase + SSC_THR;
+		slave_config.dst_maxburst = 1;
+	} else {
+		slave_config.src_addr = (dma_addr_t)ssc->phybase + SSC_RHR;
+		slave_config.src_maxburst = 1;
+	}
+
+	slave_config.device_fc = false;
+
+	dma_chan = snd_dmaengine_pcm_get_chan(substream);
+	if (dmaengine_slave_config(dma_chan, &slave_config)) {
+		pr_err("atmel-pcm: failed to configure dma channel\n");
+		ret = -EBUSY;
+		return ret;
+	}
+
+	return 0;
+}
+
+static int atmel_pcm_hw_params(struct snd_pcm_substream *substream,
+	struct snd_pcm_hw_params *params)
+{
+	struct snd_soc_pcm_runtime *rtd = substream->private_data;
+	struct atmel_pcm_dma_params *prtd;
+	struct ssc_device *ssc;
+	struct at_dma_slave *sdata = NULL;
+	int ret;
+
+	snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
+
+	prtd = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
+	ssc = prtd->ssc;
+	if (ssc->pdev)
+		sdata = ssc->pdev->dev.platform_data;
+
+	ret = snd_dmaengine_pcm_open(substream, filter, sdata);
+	if (ret) {
+		pr_err("atmel-pcm: dmaengine pcm open failed\n");
+		return -EINVAL;
+	}
+
+	snd_dmaengine_pcm_set_data(substream, prtd);
+
+	ret = atmel_pcm_configure_dma(substream, params);
+	if (ret) {
+		pr_err("atmel-pcm: failed to configure dmai\n");
+		goto err;
+	}
+
+	prtd->dma_intr_handler = atmel_pcm_dma_irq;
+
+	return 0;
+err:
+	snd_dmaengine_pcm_close(substream);
+	return ret;
+}
+
+static int atmel_pcm_dma_prepare(struct snd_pcm_substream *substream)
+{
+	struct atmel_pcm_dma_params *prtd;
+
+	prtd = snd_dmaengine_pcm_get_data(substream);
+
+	ssc_writex(prtd->ssc->regs, SSC_IER, prtd->mask->ssc_error);
+	ssc_writex(prtd->ssc->regs, SSC_CR, prtd->mask->ssc_enable);
+
+	return 0;
+}
+
+static int atmel_pcm_open(struct snd_pcm_substream *substream)
+{
+	snd_soc_set_runtime_hwparams(substream, &atmel_pcm_dma_hardware);
+
+	return 0;
+}
+
+static int atmel_pcm_close(struct snd_pcm_substream *substream)
+{
+	snd_dmaengine_pcm_close(substream);
+
+	return 0;
+}
+
+static struct snd_pcm_ops atmel_pcm_ops = {
+	.open		= atmel_pcm_open,
+	.close		= atmel_pcm_close,
+	.ioctl		= snd_pcm_lib_ioctl,
+	.hw_params	= atmel_pcm_hw_params,
+	.prepare	= atmel_pcm_dma_prepare,
+	.trigger	= snd_dmaengine_pcm_trigger,
+	.pointer	= snd_dmaengine_pcm_pointer_no_residue,
+	.mmap		= atmel_pcm_mmap,
+};
+
+static struct snd_soc_platform_driver atmel_soc_platform = {
+	.ops		= &atmel_pcm_ops,
+	.pcm_new	= atmel_pcm_new,
+	.pcm_free	= atmel_pcm_free,
+};
+
+int atmel_pcm_dma_platform_register(struct device *dev)
+{
+	return snd_soc_register_platform(dev, &atmel_soc_platform);
+}
+EXPORT_SYMBOL(atmel_pcm_dma_platform_register);
+
+void atmel_pcm_dma_platform_unregister(struct device *dev)
+{
+	snd_soc_unregister_platform(dev);
+}
+EXPORT_SYMBOL(atmel_pcm_dma_platform_unregister);
+
+MODULE_AUTHOR("Bo Shen <voice.shen@atmel.com>");
+MODULE_DESCRIPTION("Atmel DMA based PCM module");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/atmel/atmel-pcm-pdc.c b/sound/soc/atmel/atmel-pcm-pdc.c
new file mode 100644
index 0000000..6a293c7
--- /dev/null
+++ b/sound/soc/atmel/atmel-pcm-pdc.c
@@ -0,0 +1,401 @@
+/*
+ * atmel-pcm.c  --  ALSA PCM interface for the Atmel atmel SoC.
+ *
+ *  Copyright (C) 2005 SAN People
+ *  Copyright (C) 2008 Atmel
+ *
+ * Authors: Sedji Gaouaou <sedji.gaouaou@atmel.com>
+ *
+ * Based on at91-pcm. by:
+ * Frank Mandarino <fmandarino@endrelia.com>
+ * Copyright 2006 Endrelia Technologies Inc.
+ *
+ * Based on pxa2xx-pcm.c by:
+ *
+ * Author:	Nicolas Pitre
+ * Created:	Nov 30, 2004
+ * Copyright:	(C) 2004 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
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/dma-mapping.h>
+#include <linux/atmel_pdc.h>
+#include <linux/atmel-ssc.h>
+
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+
+#include "atmel-pcm.h"
+
+
+/*--------------------------------------------------------------------------*\
+ * Hardware definition
+\*--------------------------------------------------------------------------*/
+/* TODO: These values were taken from the AT91 platform driver, check
+ *	 them against real values for AT32
+ */
+static const struct snd_pcm_hardware atmel_pcm_hardware = {
+	.info			= SNDRV_PCM_INFO_MMAP |
+				  SNDRV_PCM_INFO_MMAP_VALID |
+				  SNDRV_PCM_INFO_INTERLEAVED |
+				  SNDRV_PCM_INFO_PAUSE,
+	.formats		= SNDRV_PCM_FMTBIT_S16_LE,
+	.period_bytes_min	= 32,
+	.period_bytes_max	= 8192,
+	.periods_min		= 2,
+	.periods_max		= 1024,
+	.buffer_bytes_max	= ATMEL_SSC_DMABUF_SIZE,
+};
+
+
+/*--------------------------------------------------------------------------*\
+ * Data types
+\*--------------------------------------------------------------------------*/
+struct atmel_runtime_data {
+	struct atmel_pcm_dma_params *params;
+	dma_addr_t dma_buffer;		/* physical address of dma buffer */
+	dma_addr_t dma_buffer_end;	/* first address beyond DMA buffer */
+	size_t period_size;
+
+	dma_addr_t period_ptr;		/* physical address of next period */
+
+	/* PDC register save */
+	u32 pdc_xpr_save;
+	u32 pdc_xcr_save;
+	u32 pdc_xnpr_save;
+	u32 pdc_xncr_save;
+};
+
+/*--------------------------------------------------------------------------*\
+ * ISR
+\*--------------------------------------------------------------------------*/
+static void atmel_pcm_dma_irq(u32 ssc_sr,
+	struct snd_pcm_substream *substream)
+{
+	struct atmel_runtime_data *prtd = substream->runtime->private_data;
+	struct atmel_pcm_dma_params *params = prtd->params;
+	static int count;
+
+	count++;
+
+	if (ssc_sr & params->mask->ssc_endbuf) {
+		pr_warn("atmel-pcm: buffer %s on %s (SSC_SR=%#x, count=%d)\n",
+				substream->stream == SNDRV_PCM_STREAM_PLAYBACK
+				? "underrun" : "overrun",
+				params->name, ssc_sr, count);
+
+		/* re-start the PDC */
+		ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR,
+			   params->mask->pdc_disable);
+		prtd->period_ptr += prtd->period_size;
+		if (prtd->period_ptr >= prtd->dma_buffer_end)
+			prtd->period_ptr = prtd->dma_buffer;
+
+		ssc_writex(params->ssc->regs, params->pdc->xpr,
+			   prtd->period_ptr);
+		ssc_writex(params->ssc->regs, params->pdc->xcr,
+			   prtd->period_size / params->pdc_xfer_size);
+		ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR,
+			   params->mask->pdc_enable);
+	}
+
+	if (ssc_sr & params->mask->ssc_endx) {
+		/* Load the PDC next pointer and counter registers */
+		prtd->period_ptr += prtd->period_size;
+		if (prtd->period_ptr >= prtd->dma_buffer_end)
+			prtd->period_ptr = prtd->dma_buffer;
+
+		ssc_writex(params->ssc->regs, params->pdc->xnpr,
+			   prtd->period_ptr);
+		ssc_writex(params->ssc->regs, params->pdc->xncr,
+			   prtd->period_size / params->pdc_xfer_size);
+	}
+
+	snd_pcm_period_elapsed(substream);
+}
+
+
+/*--------------------------------------------------------------------------*\
+ * PCM operations
+\*--------------------------------------------------------------------------*/
+static int atmel_pcm_hw_params(struct snd_pcm_substream *substream,
+	struct snd_pcm_hw_params *params)
+{
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct atmel_runtime_data *prtd = runtime->private_data;
+	struct snd_soc_pcm_runtime *rtd = substream->private_data;
+
+	/* this may get called several times by oss emulation
+	 * with different params */
+
+	snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
+	runtime->dma_bytes = params_buffer_bytes(params);
+
+	prtd->params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
+	prtd->params->dma_intr_handler = atmel_pcm_dma_irq;
+
+	prtd->dma_buffer = runtime->dma_addr;
+	prtd->dma_buffer_end = runtime->dma_addr + runtime->dma_bytes;
+	prtd->period_size = params_period_bytes(params);
+
+	pr_debug("atmel-pcm: "
+		"hw_params: DMA for %s initialized "
+		"(dma_bytes=%u, period_size=%u)\n",
+		prtd->params->name,
+		runtime->dma_bytes,
+		prtd->period_size);
+	return 0;
+}
+
+static int atmel_pcm_hw_free(struct snd_pcm_substream *substream)
+{
+	struct atmel_runtime_data *prtd = substream->runtime->private_data;
+	struct atmel_pcm_dma_params *params = prtd->params;
+
+	if (params != NULL) {
+		ssc_writex(params->ssc->regs, SSC_PDC_PTCR,
+			   params->mask->pdc_disable);
+		prtd->params->dma_intr_handler = NULL;
+	}
+
+	return 0;
+}
+
+static int atmel_pcm_prepare(struct snd_pcm_substream *substream)
+{
+	struct atmel_runtime_data *prtd = substream->runtime->private_data;
+	struct atmel_pcm_dma_params *params = prtd->params;
+
+	ssc_writex(params->ssc->regs, SSC_IDR,
+		   params->mask->ssc_endx | params->mask->ssc_endbuf);
+	ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR,
+		   params->mask->pdc_disable);
+	return 0;
+}
+
+static int atmel_pcm_trigger(struct snd_pcm_substream *substream,
+	int cmd)
+{
+	struct snd_pcm_runtime *rtd = substream->runtime;
+	struct atmel_runtime_data *prtd = rtd->private_data;
+	struct atmel_pcm_dma_params *params = prtd->params;
+	int ret = 0;
+
+	pr_debug("atmel-pcm:buffer_size = %ld,"
+		"dma_area = %p, dma_bytes = %u\n",
+		rtd->buffer_size, rtd->dma_area, rtd->dma_bytes);
+
+	switch (cmd) {
+	case SNDRV_PCM_TRIGGER_START:
+		prtd->period_ptr = prtd->dma_buffer;
+
+		ssc_writex(params->ssc->regs, params->pdc->xpr,
+			   prtd->period_ptr);
+		ssc_writex(params->ssc->regs, params->pdc->xcr,
+			   prtd->period_size / params->pdc_xfer_size);
+
+		prtd->period_ptr += prtd->period_size;
+		ssc_writex(params->ssc->regs, params->pdc->xnpr,
+			   prtd->period_ptr);
+		ssc_writex(params->ssc->regs, params->pdc->xncr,
+			   prtd->period_size / params->pdc_xfer_size);
+
+		pr_debug("atmel-pcm: trigger: "
+			"period_ptr=%lx, xpr=%u, "
+			"xcr=%u, xnpr=%u, xncr=%u\n",
+			(unsigned long)prtd->period_ptr,
+			ssc_readx(params->ssc->regs, params->pdc->xpr),
+			ssc_readx(params->ssc->regs, params->pdc->xcr),
+			ssc_readx(params->ssc->regs, params->pdc->xnpr),
+			ssc_readx(params->ssc->regs, params->pdc->xncr));
+
+		ssc_writex(params->ssc->regs, SSC_IER,
+			   params->mask->ssc_endx | params->mask->ssc_endbuf);
+		ssc_writex(params->ssc->regs, SSC_PDC_PTCR,
+			   params->mask->pdc_enable);
+
+		pr_debug("sr=%u imr=%u\n",
+			ssc_readx(params->ssc->regs, SSC_SR),
+			ssc_readx(params->ssc->regs, SSC_IER));
+		break;		/* SNDRV_PCM_TRIGGER_START */
+
+	case SNDRV_PCM_TRIGGER_STOP:
+	case SNDRV_PCM_TRIGGER_SUSPEND:
+	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+		ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR,
+			   params->mask->pdc_disable);
+		break;
+
+	case SNDRV_PCM_TRIGGER_RESUME:
+	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+		ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR,
+			   params->mask->pdc_enable);
+		break;
+
+	default:
+		ret = -EINVAL;
+	}
+
+	return ret;
+}
+
+static snd_pcm_uframes_t atmel_pcm_pointer(
+	struct snd_pcm_substream *substream)
+{
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct atmel_runtime_data *prtd = runtime->private_data;
+	struct atmel_pcm_dma_params *params = prtd->params;
+	dma_addr_t ptr;
+	snd_pcm_uframes_t x;
+
+	ptr = (dma_addr_t) ssc_readx(params->ssc->regs, params->pdc->xpr);
+	x = bytes_to_frames(runtime, ptr - prtd->dma_buffer);
+
+	if (x == runtime->buffer_size)
+		x = 0;
+
+	return x;
+}
+
+static int atmel_pcm_open(struct snd_pcm_substream *substream)
+{
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct atmel_runtime_data *prtd;
+	int ret = 0;
+
+	snd_soc_set_runtime_hwparams(substream, &atmel_pcm_hardware);
+
+	/* ensure that buffer size is a multiple of period size */
+	ret = snd_pcm_hw_constraint_integer(runtime,
+						SNDRV_PCM_HW_PARAM_PERIODS);
+	if (ret < 0)
+		goto out;
+
+	prtd = kzalloc(sizeof(struct atmel_runtime_data), GFP_KERNEL);
+	if (prtd == NULL) {
+		ret = -ENOMEM;
+		goto out;
+	}
+	runtime->private_data = prtd;
+
+ out:
+	return ret;
+}
+
+static int atmel_pcm_close(struct snd_pcm_substream *substream)
+{
+	struct atmel_runtime_data *prtd = substream->runtime->private_data;
+
+	kfree(prtd);
+	return 0;
+}
+
+static struct snd_pcm_ops atmel_pcm_ops = {
+	.open		= atmel_pcm_open,
+	.close		= atmel_pcm_close,
+	.ioctl		= snd_pcm_lib_ioctl,
+	.hw_params	= atmel_pcm_hw_params,
+	.hw_free	= atmel_pcm_hw_free,
+	.prepare	= atmel_pcm_prepare,
+	.trigger	= atmel_pcm_trigger,
+	.pointer	= atmel_pcm_pointer,
+	.mmap		= atmel_pcm_mmap,
+};
+
+
+/*--------------------------------------------------------------------------*\
+ * ASoC platform driver
+\*--------------------------------------------------------------------------*/
+#ifdef CONFIG_PM
+static int atmel_pcm_suspend(struct snd_soc_dai *dai)
+{
+	struct snd_pcm_runtime *runtime = dai->runtime;
+	struct atmel_runtime_data *prtd;
+	struct atmel_pcm_dma_params *params;
+
+	if (!runtime)
+		return 0;
+
+	prtd = runtime->private_data;
+	params = prtd->params;
+
+	/* disable the PDC and save the PDC registers */
+
+	ssc_writel(params->ssc->regs, PDC_PTCR, params->mask->pdc_disable);
+
+	prtd->pdc_xpr_save = ssc_readx(params->ssc->regs, params->pdc->xpr);
+	prtd->pdc_xcr_save = ssc_readx(params->ssc->regs, params->pdc->xcr);
+	prtd->pdc_xnpr_save = ssc_readx(params->ssc->regs, params->pdc->xnpr);
+	prtd->pdc_xncr_save = ssc_readx(params->ssc->regs, params->pdc->xncr);
+
+	return 0;
+}
+
+static int atmel_pcm_resume(struct snd_soc_dai *dai)
+{
+	struct snd_pcm_runtime *runtime = dai->runtime;
+	struct atmel_runtime_data *prtd;
+	struct atmel_pcm_dma_params *params;
+
+	if (!runtime)
+		return 0;
+
+	prtd = runtime->private_data;
+	params = prtd->params;
+
+	/* restore the PDC registers and enable the PDC */
+	ssc_writex(params->ssc->regs, params->pdc->xpr, prtd->pdc_xpr_save);
+	ssc_writex(params->ssc->regs, params->pdc->xcr, prtd->pdc_xcr_save);
+	ssc_writex(params->ssc->regs, params->pdc->xnpr, prtd->pdc_xnpr_save);
+	ssc_writex(params->ssc->regs, params->pdc->xncr, prtd->pdc_xncr_save);
+
+	ssc_writel(params->ssc->regs, PDC_PTCR, params->mask->pdc_enable);
+	return 0;
+}
+#else
+#define atmel_pcm_suspend	NULL
+#define atmel_pcm_resume	NULL
+#endif
+
+static struct snd_soc_platform_driver atmel_soc_platform = {
+	.ops		= &atmel_pcm_ops,
+	.pcm_new	= atmel_pcm_new,
+	.pcm_free	= atmel_pcm_free,
+	.suspend	= atmel_pcm_suspend,
+	.resume		= atmel_pcm_resume,
+};
+
+int atmel_pcm_pdc_platform_register(struct device *dev)
+{
+	return snd_soc_register_platform(dev, &atmel_soc_platform);
+}
+EXPORT_SYMBOL(atmel_pcm_pdc_platform_register);
+
+void atmel_pcm_pdc_platform_unregister(struct device *dev)
+{
+	snd_soc_unregister_platform(dev);
+}
+EXPORT_SYMBOL(atmel_pcm_pdc_platform_unregister);
+
+MODULE_AUTHOR("Sedji Gaouaou <sedji.gaouaou@atmel.com>");
+MODULE_DESCRIPTION("Atmel PCM module");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/atmel/atmel-pcm.c b/sound/soc/atmel/atmel-pcm.c
index 9b84f98..e99f181 100644
--- a/sound/soc/atmel/atmel-pcm.c
+++ b/sound/soc/atmel/atmel-pcm.c
@@ -32,80 +32,25 @@
  */
 
 #include <linux/module.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
 #include <linux/dma-mapping.h>
-#include <linux/atmel_pdc.h>
-#include <linux/atmel-ssc.h>
-
-#include <sound/core.h>
 #include <sound/pcm.h>
-#include <sound/pcm_params.h>
 #include <sound/soc.h>
-
 #include "atmel-pcm.h"
 
-
-/*--------------------------------------------------------------------------*\
- * Hardware definition
-\*--------------------------------------------------------------------------*/
-/* TODO: These values were taken from the AT91 platform driver, check
- *	 them against real values for AT32
- */
-static const struct snd_pcm_hardware atmel_pcm_hardware = {
-	.info			= SNDRV_PCM_INFO_MMAP |
-				  SNDRV_PCM_INFO_MMAP_VALID |
-				  SNDRV_PCM_INFO_INTERLEAVED |
-				  SNDRV_PCM_INFO_PAUSE,
-	.formats		= SNDRV_PCM_FMTBIT_S16_LE,
-	.period_bytes_min	= 32,
-	.period_bytes_max	= 8192,
-	.periods_min		= 2,
-	.periods_max		= 1024,
-	.buffer_bytes_max	= 32 * 1024,
-};
-
-
-/*--------------------------------------------------------------------------*\
- * Data types
-\*--------------------------------------------------------------------------*/
-struct atmel_runtime_data {
-	struct atmel_pcm_dma_params *params;
-	dma_addr_t dma_buffer;		/* physical address of dma buffer */
-	dma_addr_t dma_buffer_end;	/* first address beyond DMA buffer */
-	size_t period_size;
-
-	dma_addr_t period_ptr;		/* physical address of next period */
-
-	/* PDC register save */
-	u32 pdc_xpr_save;
-	u32 pdc_xcr_save;
-	u32 pdc_xnpr_save;
-	u32 pdc_xncr_save;
-};
-
-
-/*--------------------------------------------------------------------------*\
- * Helper functions
-\*--------------------------------------------------------------------------*/
 static int atmel_pcm_preallocate_dma_buffer(struct snd_pcm *pcm,
 	int stream)
 {
 	struct snd_pcm_substream *substream = pcm->streams[stream].substream;
 	struct snd_dma_buffer *buf = &substream->dma_buffer;
-	size_t size = atmel_pcm_hardware.buffer_bytes_max;
+	size_t size = ATMEL_SSC_DMABUF_SIZE;
 
 	buf->dev.type = SNDRV_DMA_TYPE_DEV;
 	buf->dev.dev = pcm->card->dev;
 	buf->private_data = NULL;
 	buf->area = dma_alloc_coherent(pcm->card->dev, size,
-					  &buf->addr, GFP_KERNEL);
-	pr_debug("atmel-pcm:"
-		"preallocate_dma_buffer: area=%p, addr=%p, size=%d\n",
-		(void *) buf->area,
-		(void *) buf->addr,
-		size);
+			&buf->addr, GFP_KERNEL);
+	pr_debug("atmel-pcm: alloc dma buffer: area=%p, addr=%p, size=%d\n",
+			(void *)buf->area, (void *)buf->addr, size);
 
 	if (!buf->area)
 		return -ENOMEM;
@@ -113,258 +58,19 @@
 	buf->bytes = size;
 	return 0;
 }
-/*--------------------------------------------------------------------------*\
- * ISR
-\*--------------------------------------------------------------------------*/
-static void atmel_pcm_dma_irq(u32 ssc_sr,
-	struct snd_pcm_substream *substream)
-{
-	struct atmel_runtime_data *prtd = substream->runtime->private_data;
-	struct atmel_pcm_dma_params *params = prtd->params;
-	static int count;
 
-	count++;
-
-	if (ssc_sr & params->mask->ssc_endbuf) {
-		pr_warning("atmel-pcm: buffer %s on %s"
-				" (SSC_SR=%#x, count=%d)\n",
-				substream->stream == SNDRV_PCM_STREAM_PLAYBACK
-				? "underrun" : "overrun",
-				params->name, ssc_sr, count);
-
-		/* re-start the PDC */
-		ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR,
-			   params->mask->pdc_disable);
-		prtd->period_ptr += prtd->period_size;
-		if (prtd->period_ptr >= prtd->dma_buffer_end)
-			prtd->period_ptr = prtd->dma_buffer;
-
-		ssc_writex(params->ssc->regs, params->pdc->xpr,
-			   prtd->period_ptr);
-		ssc_writex(params->ssc->regs, params->pdc->xcr,
-			   prtd->period_size / params->pdc_xfer_size);
-		ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR,
-			   params->mask->pdc_enable);
-	}
-
-	if (ssc_sr & params->mask->ssc_endx) {
-		/* Load the PDC next pointer and counter registers */
-		prtd->period_ptr += prtd->period_size;
-		if (prtd->period_ptr >= prtd->dma_buffer_end)
-			prtd->period_ptr = prtd->dma_buffer;
-
-		ssc_writex(params->ssc->regs, params->pdc->xnpr,
-			   prtd->period_ptr);
-		ssc_writex(params->ssc->regs, params->pdc->xncr,
-			   prtd->period_size / params->pdc_xfer_size);
-	}
-
-	snd_pcm_period_elapsed(substream);
-}
-
-
-/*--------------------------------------------------------------------------*\
- * PCM operations
-\*--------------------------------------------------------------------------*/
-static int atmel_pcm_hw_params(struct snd_pcm_substream *substream,
-	struct snd_pcm_hw_params *params)
-{
-	struct snd_pcm_runtime *runtime = substream->runtime;
-	struct atmel_runtime_data *prtd = runtime->private_data;
-	struct snd_soc_pcm_runtime *rtd = substream->private_data;
-
-	/* this may get called several times by oss emulation
-	 * with different params */
-
-	snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
-	runtime->dma_bytes = params_buffer_bytes(params);
-
-	prtd->params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
-	prtd->params->dma_intr_handler = atmel_pcm_dma_irq;
-
-	prtd->dma_buffer = runtime->dma_addr;
-	prtd->dma_buffer_end = runtime->dma_addr + runtime->dma_bytes;
-	prtd->period_size = params_period_bytes(params);
-
-	pr_debug("atmel-pcm: "
-		"hw_params: DMA for %s initialized "
-		"(dma_bytes=%u, period_size=%u)\n",
-		prtd->params->name,
-		runtime->dma_bytes,
-		prtd->period_size);
-	return 0;
-}
-
-static int atmel_pcm_hw_free(struct snd_pcm_substream *substream)
-{
-	struct atmel_runtime_data *prtd = substream->runtime->private_data;
-	struct atmel_pcm_dma_params *params = prtd->params;
-
-	if (params != NULL) {
-		ssc_writex(params->ssc->regs, SSC_PDC_PTCR,
-			   params->mask->pdc_disable);
-		prtd->params->dma_intr_handler = NULL;
-	}
-
-	return 0;
-}
-
-static int atmel_pcm_prepare(struct snd_pcm_substream *substream)
-{
-	struct atmel_runtime_data *prtd = substream->runtime->private_data;
-	struct atmel_pcm_dma_params *params = prtd->params;
-
-	ssc_writex(params->ssc->regs, SSC_IDR,
-		   params->mask->ssc_endx | params->mask->ssc_endbuf);
-	ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR,
-		   params->mask->pdc_disable);
-	return 0;
-}
-
-static int atmel_pcm_trigger(struct snd_pcm_substream *substream,
-	int cmd)
-{
-	struct snd_pcm_runtime *rtd = substream->runtime;
-	struct atmel_runtime_data *prtd = rtd->private_data;
-	struct atmel_pcm_dma_params *params = prtd->params;
-	int ret = 0;
-
-	pr_debug("atmel-pcm:buffer_size = %ld,"
-		"dma_area = %p, dma_bytes = %u\n",
-		rtd->buffer_size, rtd->dma_area, rtd->dma_bytes);
-
-	switch (cmd) {
-	case SNDRV_PCM_TRIGGER_START:
-		prtd->period_ptr = prtd->dma_buffer;
-
-		ssc_writex(params->ssc->regs, params->pdc->xpr,
-			   prtd->period_ptr);
-		ssc_writex(params->ssc->regs, params->pdc->xcr,
-			   prtd->period_size / params->pdc_xfer_size);
-
-		prtd->period_ptr += prtd->period_size;
-		ssc_writex(params->ssc->regs, params->pdc->xnpr,
-			   prtd->period_ptr);
-		ssc_writex(params->ssc->regs, params->pdc->xncr,
-			   prtd->period_size / params->pdc_xfer_size);
-
-		pr_debug("atmel-pcm: trigger: "
-			"period_ptr=%lx, xpr=%u, "
-			"xcr=%u, xnpr=%u, xncr=%u\n",
-			(unsigned long)prtd->period_ptr,
-			ssc_readx(params->ssc->regs, params->pdc->xpr),
-			ssc_readx(params->ssc->regs, params->pdc->xcr),
-			ssc_readx(params->ssc->regs, params->pdc->xnpr),
-			ssc_readx(params->ssc->regs, params->pdc->xncr));
-
-		ssc_writex(params->ssc->regs, SSC_IER,
-			   params->mask->ssc_endx | params->mask->ssc_endbuf);
-		ssc_writex(params->ssc->regs, SSC_PDC_PTCR,
-			   params->mask->pdc_enable);
-
-		pr_debug("sr=%u imr=%u\n",
-			ssc_readx(params->ssc->regs, SSC_SR),
-			ssc_readx(params->ssc->regs, SSC_IER));
-		break;		/* SNDRV_PCM_TRIGGER_START */
-
-	case SNDRV_PCM_TRIGGER_STOP:
-	case SNDRV_PCM_TRIGGER_SUSPEND:
-	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
-		ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR,
-			   params->mask->pdc_disable);
-		break;
-
-	case SNDRV_PCM_TRIGGER_RESUME:
-	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
-		ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR,
-			   params->mask->pdc_enable);
-		break;
-
-	default:
-		ret = -EINVAL;
-	}
-
-	return ret;
-}
-
-static snd_pcm_uframes_t atmel_pcm_pointer(
-	struct snd_pcm_substream *substream)
-{
-	struct snd_pcm_runtime *runtime = substream->runtime;
-	struct atmel_runtime_data *prtd = runtime->private_data;
-	struct atmel_pcm_dma_params *params = prtd->params;
-	dma_addr_t ptr;
-	snd_pcm_uframes_t x;
-
-	ptr = (dma_addr_t) ssc_readx(params->ssc->regs, params->pdc->xpr);
-	x = bytes_to_frames(runtime, ptr - prtd->dma_buffer);
-
-	if (x == runtime->buffer_size)
-		x = 0;
-
-	return x;
-}
-
-static int atmel_pcm_open(struct snd_pcm_substream *substream)
-{
-	struct snd_pcm_runtime *runtime = substream->runtime;
-	struct atmel_runtime_data *prtd;
-	int ret = 0;
-
-	snd_soc_set_runtime_hwparams(substream, &atmel_pcm_hardware);
-
-	/* ensure that buffer size is a multiple of period size */
-	ret = snd_pcm_hw_constraint_integer(runtime,
-						SNDRV_PCM_HW_PARAM_PERIODS);
-	if (ret < 0)
-		goto out;
-
-	prtd = kzalloc(sizeof(struct atmel_runtime_data), GFP_KERNEL);
-	if (prtd == NULL) {
-		ret = -ENOMEM;
-		goto out;
-	}
-	runtime->private_data = prtd;
-
- out:
-	return ret;
-}
-
-static int atmel_pcm_close(struct snd_pcm_substream *substream)
-{
-	struct atmel_runtime_data *prtd = substream->runtime->private_data;
-
-	kfree(prtd);
-	return 0;
-}
-
-static int atmel_pcm_mmap(struct snd_pcm_substream *substream,
+int atmel_pcm_mmap(struct snd_pcm_substream *substream,
 	struct vm_area_struct *vma)
 {
 	return remap_pfn_range(vma, vma->vm_start,
 		       substream->dma_buffer.addr >> PAGE_SHIFT,
 		       vma->vm_end - vma->vm_start, vma->vm_page_prot);
 }
+EXPORT_SYMBOL_GPL(atmel_pcm_mmap);
 
-static struct snd_pcm_ops atmel_pcm_ops = {
-	.open		= atmel_pcm_open,
-	.close		= atmel_pcm_close,
-	.ioctl		= snd_pcm_lib_ioctl,
-	.hw_params	= atmel_pcm_hw_params,
-	.hw_free	= atmel_pcm_hw_free,
-	.prepare	= atmel_pcm_prepare,
-	.trigger	= atmel_pcm_trigger,
-	.pointer	= atmel_pcm_pointer,
-	.mmap		= atmel_pcm_mmap,
-};
-
-
-/*--------------------------------------------------------------------------*\
- * ASoC platform driver
-\*--------------------------------------------------------------------------*/
 static u64 atmel_pcm_dmamask = DMA_BIT_MASK(32);
 
-static int atmel_pcm_new(struct snd_soc_pcm_runtime *rtd)
+int atmel_pcm_new(struct snd_soc_pcm_runtime *rtd)
 {
 	struct snd_card *card = rtd->card->snd_card;
 	struct snd_pcm *pcm = rtd->pcm;
@@ -376,6 +82,7 @@
 		card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
 
 	if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) {
+		pr_debug("atmel-pcm: allocating PCM playback DMA buffer\n");
 		ret = atmel_pcm_preallocate_dma_buffer(pcm,
 			SNDRV_PCM_STREAM_PLAYBACK);
 		if (ret)
@@ -383,8 +90,7 @@
 	}
 
 	if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) {
-		pr_debug("atmel-pcm:"
-				"Allocating PCM capture DMA buffer\n");
+		pr_debug("atmel-pcm: allocating PCM capture DMA buffer\n");
 		ret = atmel_pcm_preallocate_dma_buffer(pcm,
 			SNDRV_PCM_STREAM_CAPTURE);
 		if (ret)
@@ -393,8 +99,9 @@
  out:
 	return ret;
 }
+EXPORT_SYMBOL_GPL(atmel_pcm_new);
 
-static void atmel_pcm_free_dma_buffers(struct snd_pcm *pcm)
+void atmel_pcm_free(struct snd_pcm *pcm)
 {
 	struct snd_pcm_substream *substream;
 	struct snd_dma_buffer *buf;
@@ -413,89 +120,5 @@
 		buf->area = NULL;
 	}
 }
+EXPORT_SYMBOL_GPL(atmel_pcm_free);
 
-#ifdef CONFIG_PM
-static int atmel_pcm_suspend(struct snd_soc_dai *dai)
-{
-	struct snd_pcm_runtime *runtime = dai->runtime;
-	struct atmel_runtime_data *prtd;
-	struct atmel_pcm_dma_params *params;
-
-	if (!runtime)
-		return 0;
-
-	prtd = runtime->private_data;
-	params = prtd->params;
-
-	/* disable the PDC and save the PDC registers */
-
-	ssc_writel(params->ssc->regs, PDC_PTCR, params->mask->pdc_disable);
-
-	prtd->pdc_xpr_save = ssc_readx(params->ssc->regs, params->pdc->xpr);
-	prtd->pdc_xcr_save = ssc_readx(params->ssc->regs, params->pdc->xcr);
-	prtd->pdc_xnpr_save = ssc_readx(params->ssc->regs, params->pdc->xnpr);
-	prtd->pdc_xncr_save = ssc_readx(params->ssc->regs, params->pdc->xncr);
-
-	return 0;
-}
-
-static int atmel_pcm_resume(struct snd_soc_dai *dai)
-{
-	struct snd_pcm_runtime *runtime = dai->runtime;
-	struct atmel_runtime_data *prtd;
-	struct atmel_pcm_dma_params *params;
-
-	if (!runtime)
-		return 0;
-
-	prtd = runtime->private_data;
-	params = prtd->params;
-
-	/* restore the PDC registers and enable the PDC */
-	ssc_writex(params->ssc->regs, params->pdc->xpr, prtd->pdc_xpr_save);
-	ssc_writex(params->ssc->regs, params->pdc->xcr, prtd->pdc_xcr_save);
-	ssc_writex(params->ssc->regs, params->pdc->xnpr, prtd->pdc_xnpr_save);
-	ssc_writex(params->ssc->regs, params->pdc->xncr, prtd->pdc_xncr_save);
-
-	ssc_writel(params->ssc->regs, PDC_PTCR, params->mask->pdc_enable);
-	return 0;
-}
-#else
-#define atmel_pcm_suspend	NULL
-#define atmel_pcm_resume	NULL
-#endif
-
-static struct snd_soc_platform_driver atmel_soc_platform = {
-	.ops		= &atmel_pcm_ops,
-	.pcm_new	= atmel_pcm_new,
-	.pcm_free	= atmel_pcm_free_dma_buffers,
-	.suspend	= atmel_pcm_suspend,
-	.resume		= atmel_pcm_resume,
-};
-
-static int __devinit atmel_soc_platform_probe(struct platform_device *pdev)
-{
-	return snd_soc_register_platform(&pdev->dev, &atmel_soc_platform);
-}
-
-static int __devexit atmel_soc_platform_remove(struct platform_device *pdev)
-{
-	snd_soc_unregister_platform(&pdev->dev);
-	return 0;
-}
-
-static struct platform_driver atmel_pcm_driver = {
-	.driver = {
-			.name = "atmel-pcm-audio",
-			.owner = THIS_MODULE,
-	},
-
-	.probe = atmel_soc_platform_probe,
-	.remove = __devexit_p(atmel_soc_platform_remove),
-};
-
-module_platform_driver(atmel_pcm_driver);
-
-MODULE_AUTHOR("Sedji Gaouaou <sedji.gaouaou@atmel.com>");
-MODULE_DESCRIPTION("Atmel PCM module");
-MODULE_LICENSE("GPL");
diff --git a/sound/soc/atmel/atmel-pcm.h b/sound/soc/atmel/atmel-pcm.h
index 5e0a95e..bb45d20 100644
--- a/sound/soc/atmel/atmel-pcm.h
+++ b/sound/soc/atmel/atmel-pcm.h
@@ -36,6 +36,8 @@
 
 #include <linux/atmel-ssc.h>
 
+#define ATMEL_SSC_DMABUF_SIZE	(64 * 1024)
+
 /*
  * Registers and status bits that are required by the PCM driver.
  */
@@ -50,6 +52,7 @@
 struct atmel_ssc_mask {
 	u32	ssc_enable;		/* SSC recv/trans enable */
 	u32	ssc_disable;		/* SSC recv/trans disable */
+	u32	ssc_error;		/* SSC error conditions */
 	u32	ssc_endx;		/* SSC ENDTX or ENDRX */
 	u32	ssc_endbuf;		/* SSC TXBUFE or RXBUFF */
 	u32	pdc_enable;		/* PDC recv/trans enable */
@@ -80,4 +83,35 @@
 #define ssc_readx(base, reg)            (__raw_readl((base) + (reg)))
 #define ssc_writex(base, reg, value)    __raw_writel((value), (base) + (reg))
 
+int atmel_pcm_new(struct snd_soc_pcm_runtime *rtd);
+void atmel_pcm_free(struct snd_pcm *pcm);
+int atmel_pcm_mmap(struct snd_pcm_substream *substream,
+		struct vm_area_struct *vma);
+
+#ifdef CONFIG_SND_ATMEL_SOC_PDC
+int atmel_pcm_pdc_platform_register(struct device *dev);
+void atmel_pcm_pdc_platform_unregister(struct device *dev);
+#else
+static inline int atmel_pcm_pdc_platform_register(struct device *dev)
+{
+	return 0;
+}
+static inline void atmel_pcm_pdc_platform_unregister(struct device *dev)
+{
+}
+#endif
+
+#ifdef CONFIG_SND_ATMEL_SOC_DMA
+int atmel_pcm_dma_platform_register(struct device *dev);
+void atmel_pcm_dma_platform_unregister(struct device *dev);
+#else
+static inline int atmel_pcm_dma_platform_register(struct device *dev)
+{
+	return 0;
+}
+static inline void atmel_pcm_dma_platform_unregister(struct device *dev)
+{
+}
+#endif
+
 #endif /* _ATMEL_PCM_H */
diff --git a/sound/soc/atmel/atmel_ssc_dai.c b/sound/soc/atmel/atmel_ssc_dai.c
index 354341e..1c76634 100644
--- a/sound/soc/atmel/atmel_ssc_dai.c
+++ b/sound/soc/atmel/atmel_ssc_dai.c
@@ -48,11 +48,7 @@
 #include "atmel_ssc_dai.h"
 
 
-#if defined(CONFIG_ARCH_AT91SAM9260) || defined(CONFIG_ARCH_AT91SAM9G20)
-#define NUM_SSC_DEVICES		1
-#else
 #define NUM_SSC_DEVICES		3
-#endif
 
 /*
  * SSC PDC registers required by the PCM DMA engine.
@@ -107,7 +103,6 @@
 	.pdc		= &pdc_rx_reg,
 	.mask		= &ssc_rx_mask,
 	} },
-#if NUM_SSC_DEVICES == 3
 	{{
 	.name		= "SSC1 PCM out",
 	.pdc		= &pdc_tx_reg,
@@ -128,7 +123,6 @@
 	.pdc		= &pdc_rx_reg,
 	.mask		= &ssc_rx_mask,
 	} },
-#endif
 };
 
 
@@ -139,7 +133,6 @@
 	.dir_mask	= SSC_DIR_MASK_UNUSED,
 	.initialized	= 0,
 	},
-#if NUM_SSC_DEVICES == 3
 	{
 	.name		= "ssc1",
 	.lock		= __SPIN_LOCK_UNLOCKED(ssc_info[1].lock),
@@ -152,7 +145,6 @@
 	.dir_mask	= SSC_DIR_MASK_UNUSED,
 	.initialized	= 0,
 	},
-#endif
 };
 
 
@@ -690,27 +682,9 @@
 static int atmel_ssc_probe(struct snd_soc_dai *dai)
 {
 	struct atmel_ssc_info *ssc_p = &ssc_info[dai->id];
-	int ret = 0;
 
 	snd_soc_dai_set_drvdata(dai, ssc_p);
 
-	/*
-	 * Request SSC device
-	 */
-	ssc_p->ssc = ssc_request(dai->id);
-	if (IS_ERR(ssc_p->ssc)) {
-		printk(KERN_ERR "ASoC: Failed to request SSC %d\n", dai->id);
-		ret = PTR_ERR(ssc_p->ssc);
-	}
-
-	return ret;
-}
-
-static int atmel_ssc_remove(struct snd_soc_dai *dai)
-{
-	struct atmel_ssc_info *ssc_p = snd_soc_dai_get_drvdata(dai);
-
-	ssc_free(ssc_p->ssc);
 	return 0;
 }
 
@@ -728,11 +702,8 @@
 	.set_clkdiv	= atmel_ssc_set_dai_clkdiv,
 };
 
-static struct snd_soc_dai_driver atmel_ssc_dai[NUM_SSC_DEVICES] = {
-	{
-		.name = "atmel-ssc-dai.0",
+static struct snd_soc_dai_driver atmel_ssc_dai = {
 		.probe = atmel_ssc_probe,
-		.remove = atmel_ssc_remove,
 		.suspend = atmel_ssc_suspend,
 		.resume = atmel_ssc_resume,
 		.playback = {
@@ -746,69 +717,50 @@
 			.rates = ATMEL_SSC_RATES,
 			.formats = ATMEL_SSC_FORMATS,},
 		.ops = &atmel_ssc_dai_ops,
-	},
-#if NUM_SSC_DEVICES == 3
-	{
-		.name = "atmel-ssc-dai.1",
-		.probe = atmel_ssc_probe,
-		.remove = atmel_ssc_remove,
-		.suspend = atmel_ssc_suspend,
-		.resume = atmel_ssc_resume,
-		.playback = {
-			.channels_min = 1,
-			.channels_max = 2,
-			.rates = ATMEL_SSC_RATES,
-			.formats = ATMEL_SSC_FORMATS,},
-		.capture = {
-			.channels_min = 1,
-			.channels_max = 2,
-			.rates = ATMEL_SSC_RATES,
-			.formats = ATMEL_SSC_FORMATS,},
-		.ops = &atmel_ssc_dai_ops,
-	},
-	{
-		.name = "atmel-ssc-dai.2",
-		.probe = atmel_ssc_probe,
-		.remove = atmel_ssc_remove,
-		.suspend = atmel_ssc_suspend,
-		.resume = atmel_ssc_resume,
-		.playback = {
-			.channels_min = 1,
-			.channels_max = 2,
-			.rates = ATMEL_SSC_RATES,
-			.formats = ATMEL_SSC_FORMATS,},
-		.capture = {
-			.channels_min = 1,
-			.channels_max = 2,
-			.rates = ATMEL_SSC_RATES,
-			.formats = ATMEL_SSC_FORMATS,},
-		.ops = &atmel_ssc_dai_ops,
-	},
-#endif
 };
 
-static __devinit int asoc_ssc_probe(struct platform_device *pdev)
+static int asoc_ssc_init(struct device *dev)
 {
-	BUG_ON(pdev->id < 0);
-	BUG_ON(pdev->id >= ARRAY_SIZE(atmel_ssc_dai));
-	return snd_soc_register_dai(&pdev->dev, &atmel_ssc_dai[pdev->id]);
-}
+	struct platform_device *pdev = to_platform_device(dev);
+	struct ssc_device *ssc = platform_get_drvdata(pdev);
+	int ret;
 
-static int __devexit asoc_ssc_remove(struct platform_device *pdev)
-{
-	snd_soc_unregister_dai(&pdev->dev);
+	ret = snd_soc_register_dai(dev, &atmel_ssc_dai);
+	if (ret) {
+		dev_err(dev, "Could not register DAI: %d\n", ret);
+		goto err;
+	}
+
+	if (ssc->pdata->use_dma)
+		ret = atmel_pcm_dma_platform_register(dev);
+	else
+		ret = atmel_pcm_pdc_platform_register(dev);
+
+	if (ret) {
+		dev_err(dev, "Could not register PCM: %d\n", ret);
+		goto err_unregister_dai;
+	};
+
 	return 0;
+
+err_unregister_dai:
+	snd_soc_unregister_dai(dev);
+err:
+	return ret;
 }
 
-static struct platform_driver asoc_ssc_driver = {
-	.driver = {
-			.name = "atmel-ssc-dai",
-			.owner = THIS_MODULE,
-	},
+static void asoc_ssc_exit(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct ssc_device *ssc = platform_get_drvdata(pdev);
 
-	.probe = asoc_ssc_probe,
-	.remove = __devexit_p(asoc_ssc_remove),
-};
+	if (ssc->pdata->use_dma)
+		atmel_pcm_dma_platform_unregister(dev);
+	else
+		atmel_pcm_pdc_platform_unregister(dev);
+
+	snd_soc_unregister_dai(dev);
+}
 
 /**
  * atmel_ssc_set_audio - Allocate the specified SSC for audio use.
@@ -816,50 +768,32 @@
 int atmel_ssc_set_audio(int ssc_id)
 {
 	struct ssc_device *ssc;
-	static struct platform_device *dma_pdev;
-	struct platform_device *ssc_pdev;
 	int ret;
 
-	if (ssc_id < 0 || ssc_id >= ARRAY_SIZE(atmel_ssc_dai))
-		return -EINVAL;
-
-	/* Allocate a dummy device for DMA if we don't have one already */
-	if (!dma_pdev) {
-		dma_pdev = platform_device_alloc("atmel-pcm-audio", -1);
-		if (!dma_pdev)
-			return -ENOMEM;
-
-		ret = platform_device_add(dma_pdev);
-		if (ret < 0) {
-			platform_device_put(dma_pdev);
-			dma_pdev = NULL;
-			return ret;
-		}
-	}
-
-	ssc_pdev = platform_device_alloc("atmel-ssc-dai", ssc_id);
-	if (!ssc_pdev)
-		return -ENOMEM;
-
 	/* If we can grab the SSC briefly to parent the DAI device off it */
 	ssc = ssc_request(ssc_id);
-	if (IS_ERR(ssc))
-		pr_warn("Unable to parent ASoC SSC DAI on SSC: %ld\n",
+	if (IS_ERR(ssc)) {
+		pr_err("Unable to parent ASoC SSC DAI on SSC: %ld\n",
 			PTR_ERR(ssc));
-	else {
-		ssc_pdev->dev.parent = &(ssc->pdev->dev);
-		ssc_free(ssc);
+		return PTR_ERR(ssc);
+	} else {
+		ssc_info[ssc_id].ssc = ssc;
 	}
 
-	ret = platform_device_add(ssc_pdev);
-	if (ret < 0)
-		platform_device_put(ssc_pdev);
+	ret = asoc_ssc_init(&ssc->pdev->dev);
 
 	return ret;
 }
 EXPORT_SYMBOL_GPL(atmel_ssc_set_audio);
 
-module_platform_driver(asoc_ssc_driver);
+void atmel_ssc_put_audio(int ssc_id)
+{
+	struct ssc_device *ssc = ssc_info[ssc_id].ssc;
+
+	ssc_free(ssc);
+	asoc_ssc_exit(&ssc->pdev->dev);
+}
+EXPORT_SYMBOL_GPL(atmel_ssc_put_audio);
 
 /* Module information */
 MODULE_AUTHOR("Sedji Gaouaou, sedji.gaouaou@atmel.com, www.atmel.com");
diff --git a/sound/soc/atmel/atmel_ssc_dai.h b/sound/soc/atmel/atmel_ssc_dai.h
index 5d4f0f9b..b1f08d5 100644
--- a/sound/soc/atmel/atmel_ssc_dai.h
+++ b/sound/soc/atmel/atmel_ssc_dai.h
@@ -117,6 +117,7 @@
 	struct atmel_ssc_state ssc_state;
 };
 
-int atmel_ssc_set_audio(int ssc);
+int atmel_ssc_set_audio(int ssc_id);
+void atmel_ssc_put_audio(int ssc_id);
 
 #endif /* _AT91_SSC_DAI_H */
diff --git a/sound/soc/atmel/sam9g20_wm8731.c b/sound/soc/atmel/sam9g20_wm8731.c
index c883514..da97629 100644
--- a/sound/soc/atmel/sam9g20_wm8731.c
+++ b/sound/soc/atmel/sam9g20_wm8731.c
@@ -38,6 +38,8 @@
 #include <linux/platform_device.h>
 #include <linux/i2c.h>
 
+#include <linux/pinctrl/consumer.h>
+
 #include <linux/atmel-ssc.h>
 
 #include <sound/core.h>
@@ -179,10 +181,10 @@
 static struct snd_soc_dai_link at91sam9g20ek_dai = {
 	.name = "WM8731",
 	.stream_name = "WM8731 PCM",
-	.cpu_dai_name = "atmel-ssc-dai.0",
+	.cpu_dai_name = "at91rm9200_ssc.0",
 	.codec_dai_name = "wm8731-hifi",
 	.init = at91sam9g20ek_wm8731_init,
-	.platform_name = "atmel-pcm-audio",
+	.platform_name = "at91rm9200_ssc.0",
 	.codec_name = "wm8731.0-001b",
 	.ops = &at91sam9g20ek_ops,
 };
@@ -195,20 +197,31 @@
 	.set_bias_level = at91sam9g20ek_set_bias_level,
 };
 
-static struct platform_device *at91sam9g20ek_snd_device;
-
-static int __init at91sam9g20ek_init(void)
+static int at91sam9g20ek_audio_probe(struct platform_device *pdev)
 {
+	struct device_node *np = pdev->dev.of_node;
+	struct device_node *codec_np, *cpu_np;
 	struct clk *pllb;
+	struct snd_soc_card *card = &snd_soc_at91sam9g20ek;
+	struct pinctrl *pinctrl;
 	int ret;
 
-	if (!(machine_is_at91sam9g20ek() || machine_is_at91sam9g20ek_2mmc()))
-		return -ENODEV;
+	pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
+	if (IS_ERR(pinctrl)) {
+		dev_err(&pdev->dev, "Failed to request pinctrl for mck\n");
+		return PTR_ERR(pinctrl);
+	}
+
+	if (!np) {
+		if (!(machine_is_at91sam9g20ek() ||
+			machine_is_at91sam9g20ek_2mmc()))
+			return -ENODEV;
+	}
 
 	ret = atmel_ssc_set_audio(0);
-	if (ret != 0) {
-		pr_err("Failed to set SSC 0 for audio: %d\n", ret);
-		return ret;
+	if (ret) {
+		dev_err(&pdev->dev, "ssc channel is not valid\n");
+		return -EINVAL;
 	}
 
 	/*
@@ -236,45 +249,92 @@
 
 	clk_set_rate(mclk, MCLK_RATE);
 
-	at91sam9g20ek_snd_device = platform_device_alloc("soc-audio", -1);
-	if (!at91sam9g20ek_snd_device) {
-		printk(KERN_ERR "ASoC: Platform device allocation failed\n");
-		ret = -ENOMEM;
-		goto err_mclk;
+	card->dev = &pdev->dev;
+
+	/* Parse device node info */
+	if (np) {
+		ret = snd_soc_of_parse_card_name(card, "atmel,model");
+		if (ret)
+			goto err;
+
+		ret = snd_soc_of_parse_audio_routing(card,
+			"atmel,audio-routing");
+		if (ret)
+			goto err;
+
+		/* Parse codec info */
+		at91sam9g20ek_dai.codec_name = NULL;
+		codec_np = of_parse_phandle(np, "atmel,audio-codec", 0);
+		if (!codec_np) {
+			dev_err(&pdev->dev, "codec info missing\n");
+			return -EINVAL;
+		}
+		at91sam9g20ek_dai.codec_of_node = codec_np;
+
+		/* Parse dai and platform info */
+		at91sam9g20ek_dai.cpu_dai_name = NULL;
+		at91sam9g20ek_dai.platform_name = NULL;
+		cpu_np = of_parse_phandle(np, "atmel,ssc-controller", 0);
+		if (!cpu_np) {
+			dev_err(&pdev->dev, "dai and pcm info missing\n");
+			return -EINVAL;
+		}
+		at91sam9g20ek_dai.cpu_of_node = cpu_np;
+		at91sam9g20ek_dai.platform_of_node = cpu_np;
+
+		of_node_put(codec_np);
+		of_node_put(cpu_np);
 	}
 
-	platform_set_drvdata(at91sam9g20ek_snd_device,
-			&snd_soc_at91sam9g20ek);
-
-	ret = platform_device_add(at91sam9g20ek_snd_device);
+	ret = snd_soc_register_card(card);
 	if (ret) {
-		printk(KERN_ERR "ASoC: Platform device allocation failed\n");
-		goto err_device_add;
+		printk(KERN_ERR "ASoC: snd_soc_register_card() failed\n");
 	}
 
 	return ret;
 
-err_device_add:
-	platform_device_put(at91sam9g20ek_snd_device);
 err_mclk:
 	clk_put(mclk);
 	mclk = NULL;
 err:
+	atmel_ssc_put_audio(0);
 	return ret;
 }
 
-static void __exit at91sam9g20ek_exit(void)
+static int at91sam9g20ek_audio_remove(struct platform_device *pdev)
 {
-	platform_device_unregister(at91sam9g20ek_snd_device);
-	at91sam9g20ek_snd_device = NULL;
+	struct snd_soc_card *card = platform_get_drvdata(pdev);
+
+	atmel_ssc_put_audio(0);
+	snd_soc_unregister_card(card);
 	clk_put(mclk);
 	mclk = NULL;
+
+	return 0;
 }
 
-module_init(at91sam9g20ek_init);
-module_exit(at91sam9g20ek_exit);
+#ifdef CONFIG_OF
+static const struct of_device_id at91sam9g20ek_wm8731_dt_ids[] = {
+	{ .compatible = "atmel,at91sam9g20ek-wm8731-audio", },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, at91sam9g20ek_wm8731_dt_ids);
+#endif
+
+static struct platform_driver at91sam9g20ek_audio_driver = {
+	.driver = {
+		.name	= "at91sam9g20ek-audio",
+		.owner	= THIS_MODULE,
+		.of_match_table = of_match_ptr(at91sam9g20ek_wm8731_dt_ids),
+	},
+	.probe	= at91sam9g20ek_audio_probe,
+	.remove	= at91sam9g20ek_audio_remove,
+};
+
+module_platform_driver(at91sam9g20ek_audio_driver);
 
 /* Module information */
 MODULE_AUTHOR("Sedji Gaouaou <sedji.gaouaou@atmel.com>");
 MODULE_DESCRIPTION("ALSA SoC AT91SAM9G20EK_WM8731");
+MODULE_ALIAS("platform:at91sam9g20ek-audio");
 MODULE_LICENSE("GPL");
diff --git a/sound/soc/au1x/ac97c.c b/sound/soc/au1x/ac97c.c
index c5ac244..ea7d9d1 100644
--- a/sound/soc/au1x/ac97c.c
+++ b/sound/soc/au1x/ac97c.c
@@ -223,7 +223,7 @@
 	.ops			= &alchemy_ac97c_ops,
 };
 
-static int __devinit au1xac97c_drvprobe(struct platform_device *pdev)
+static int au1xac97c_drvprobe(struct platform_device *pdev)
 {
 	int ret;
 	struct resource *iores, *dmares;
@@ -276,7 +276,7 @@
 	return 0;
 }
 
-static int __devexit au1xac97c_drvremove(struct platform_device *pdev)
+static int au1xac97c_drvremove(struct platform_device *pdev)
 {
 	struct au1xpsc_audio_data *ctx = platform_get_drvdata(pdev);
 
@@ -330,7 +330,7 @@
 		.pm	= AU1XPSCAC97_PMOPS,
 	},
 	.probe		= au1xac97c_drvprobe,
-	.remove		= __devexit_p(au1xac97c_drvremove),
+	.remove		= au1xac97c_drvremove,
 };
 
 static int __init au1xac97c_load(void)
diff --git a/sound/soc/au1x/db1000.c b/sound/soc/au1x/db1000.c
index 511d83c..376d976 100644
--- a/sound/soc/au1x/db1000.c
+++ b/sound/soc/au1x/db1000.c
@@ -34,14 +34,14 @@
 	.num_links	= 1,
 };
 
-static int __devinit db1000_audio_probe(struct platform_device *pdev)
+static int db1000_audio_probe(struct platform_device *pdev)
 {
 	struct snd_soc_card *card = &db1000_ac97;
 	card->dev = &pdev->dev;
 	return snd_soc_register_card(card);
 }
 
-static int __devexit db1000_audio_remove(struct platform_device *pdev)
+static int db1000_audio_remove(struct platform_device *pdev)
 {
 	struct snd_soc_card *card = platform_get_drvdata(pdev);
 	snd_soc_unregister_card(card);
@@ -55,7 +55,7 @@
 		.pm	= &snd_soc_pm_ops,
 	},
 	.probe		= db1000_audio_probe,
-	.remove		= __devexit_p(db1000_audio_remove),
+	.remove		= db1000_audio_remove,
 };
 
 module_platform_driver(db1000_audio_driver);
diff --git a/sound/soc/au1x/db1200.c b/sound/soc/au1x/db1200.c
index 30ea513..a497a0c 100644
--- a/sound/soc/au1x/db1200.c
+++ b/sound/soc/au1x/db1200.c
@@ -167,7 +167,7 @@
 
 /*-------------------------  COMMON PART  ---------------------------*/
 
-static struct snd_soc_card *db1200_cards[] __devinitdata = {
+static struct snd_soc_card *db1200_cards[] = {
 	&db1200_ac97_machine,
 	&db1200_i2s_machine,
 	&db1300_ac97_machine,
@@ -176,7 +176,7 @@
 	&db1550_i2s_machine,
 };
 
-static int __devinit db1200_audio_probe(struct platform_device *pdev)
+static int db1200_audio_probe(struct platform_device *pdev)
 {
 	const struct platform_device_id *pid = platform_get_device_id(pdev);
 	struct snd_soc_card *card;
@@ -186,7 +186,7 @@
 	return snd_soc_register_card(card);
 }
 
-static int __devexit db1200_audio_remove(struct platform_device *pdev)
+static int db1200_audio_remove(struct platform_device *pdev)
 {
 	struct snd_soc_card *card = platform_get_drvdata(pdev);
 	snd_soc_unregister_card(card);
@@ -201,7 +201,7 @@
 	},
 	.id_table	= db1200_pids,
 	.probe		= db1200_audio_probe,
-	.remove		= __devexit_p(db1200_audio_remove),
+	.remove		= db1200_audio_remove,
 };
 
 module_platform_driver(db1200_audio_driver);
diff --git a/sound/soc/au1x/dbdma2.c b/sound/soc/au1x/dbdma2.c
index 8372cd3..3b4eafa 100644
--- a/sound/soc/au1x/dbdma2.c
+++ b/sound/soc/au1x/dbdma2.c
@@ -347,7 +347,7 @@
 	.pcm_free	= au1xpsc_pcm_free_dma_buffers,
 };
 
-static int __devinit au1xpsc_pcm_drvprobe(struct platform_device *pdev)
+static int au1xpsc_pcm_drvprobe(struct platform_device *pdev)
 {
 	struct au1xpsc_audio_dmadata *dmadata;
 
@@ -362,7 +362,7 @@
 	return snd_soc_register_platform(&pdev->dev, &au1xpsc_soc_platform);
 }
 
-static int __devexit au1xpsc_pcm_drvremove(struct platform_device *pdev)
+static int au1xpsc_pcm_drvremove(struct platform_device *pdev)
 {
 	snd_soc_unregister_platform(&pdev->dev);
 
@@ -375,7 +375,7 @@
 		.owner	= THIS_MODULE,
 	},
 	.probe		= au1xpsc_pcm_drvprobe,
-	.remove		= __devexit_p(au1xpsc_pcm_drvremove),
+	.remove		= au1xpsc_pcm_drvremove,
 };
 
 module_platform_driver(au1xpsc_pcm_driver);
diff --git a/sound/soc/au1x/dma.c b/sound/soc/au1x/dma.c
index 0a91b18..befd107 100644
--- a/sound/soc/au1x/dma.c
+++ b/sound/soc/au1x/dma.c
@@ -322,7 +322,7 @@
 	.pcm_free	= alchemy_pcm_free_dma_buffers,
 };
 
-static int __devinit alchemy_pcm_drvprobe(struct platform_device *pdev)
+static int alchemy_pcm_drvprobe(struct platform_device *pdev)
 {
 	struct alchemy_pcm_ctx *ctx;
 
@@ -335,7 +335,7 @@
 	return snd_soc_register_platform(&pdev->dev, &alchemy_pcm_soc_platform);
 }
 
-static int __devexit alchemy_pcm_drvremove(struct platform_device *pdev)
+static int alchemy_pcm_drvremove(struct platform_device *pdev)
 {
 	snd_soc_unregister_platform(&pdev->dev);
 
@@ -348,7 +348,7 @@
 		.owner	= THIS_MODULE,
 	},
 	.probe		= alchemy_pcm_drvprobe,
-	.remove		= __devexit_p(alchemy_pcm_drvremove),
+	.remove		= alchemy_pcm_drvremove,
 };
 
 module_platform_driver(alchemy_pcmdma_driver);
diff --git a/sound/soc/au1x/i2sc.c b/sound/soc/au1x/i2sc.c
index d4b9e36..072448a 100644
--- a/sound/soc/au1x/i2sc.c
+++ b/sound/soc/au1x/i2sc.c
@@ -225,7 +225,7 @@
 	.ops = &au1xi2s_dai_ops,
 };
 
-static int __devinit au1xi2s_drvprobe(struct platform_device *pdev)
+static int au1xi2s_drvprobe(struct platform_device *pdev)
 {
 	struct resource *iores, *dmares;
 	struct au1xpsc_audio_data *ctx;
@@ -263,7 +263,7 @@
 	return snd_soc_register_dai(&pdev->dev, &au1xi2s_dai_driver);
 }
 
-static int __devexit au1xi2s_drvremove(struct platform_device *pdev)
+static int au1xi2s_drvremove(struct platform_device *pdev)
 {
 	struct au1xpsc_audio_data *ctx = platform_get_drvdata(pdev);
 
@@ -309,7 +309,7 @@
 		.pm	= AU1XI2SC_PMOPS,
 	},
 	.probe		= au1xi2s_drvprobe,
-	.remove		= __devexit_p(au1xi2s_drvremove),
+	.remove		= au1xi2s_drvremove,
 };
 
 module_platform_driver(au1xi2s_driver);
diff --git a/sound/soc/au1x/psc-ac97.c b/sound/soc/au1x/psc-ac97.c
index 476b79a..6ba07e3 100644
--- a/sound/soc/au1x/psc-ac97.c
+++ b/sound/soc/au1x/psc-ac97.c
@@ -361,7 +361,7 @@
 	.ops = &au1xpsc_ac97_dai_ops,
 };
 
-static int __devinit au1xpsc_ac97_drvprobe(struct platform_device *pdev)
+static int au1xpsc_ac97_drvprobe(struct platform_device *pdev)
 {
 	int ret;
 	struct resource *iores, *dmares;
@@ -427,7 +427,7 @@
 	return 0;
 }
 
-static int __devexit au1xpsc_ac97_drvremove(struct platform_device *pdev)
+static int au1xpsc_ac97_drvremove(struct platform_device *pdev)
 {
 	struct au1xpsc_audio_data *wd = platform_get_drvdata(pdev);
 
@@ -495,7 +495,7 @@
 		.pm	= AU1XPSCAC97_PMOPS,
 	},
 	.probe		= au1xpsc_ac97_drvprobe,
-	.remove		= __devexit_p(au1xpsc_ac97_drvremove),
+	.remove		= au1xpsc_ac97_drvremove,
 };
 
 static int __init au1xpsc_ac97_load(void)
diff --git a/sound/soc/au1x/psc-i2s.c b/sound/soc/au1x/psc-i2s.c
index 0607ba3..360b4e5 100644
--- a/sound/soc/au1x/psc-i2s.c
+++ b/sound/soc/au1x/psc-i2s.c
@@ -288,7 +288,7 @@
 	.ops = &au1xpsc_i2s_dai_ops,
 };
 
-static int __devinit au1xpsc_i2s_drvprobe(struct platform_device *pdev)
+static int au1xpsc_i2s_drvprobe(struct platform_device *pdev)
 {
 	struct resource *iores, *dmares;
 	unsigned long sel;
@@ -353,7 +353,7 @@
 	return snd_soc_register_dai(&pdev->dev, &wd->dai_drv);
 }
 
-static int __devexit au1xpsc_i2s_drvremove(struct platform_device *pdev)
+static int au1xpsc_i2s_drvremove(struct platform_device *pdev)
 {
 	struct au1xpsc_audio_data *wd = platform_get_drvdata(pdev);
 
@@ -418,7 +418,7 @@
 		.pm	= AU1XPSCI2S_PMOPS,
 	},
 	.probe		= au1xpsc_i2s_drvprobe,
-	.remove		= __devexit_p(au1xpsc_i2s_drvremove),
+	.remove		= au1xpsc_i2s_drvremove,
 };
 
 module_platform_driver(au1xpsc_i2s_driver);
diff --git a/sound/soc/blackfin/bf5xx-ac97-pcm.c b/sound/soc/blackfin/bf5xx-ac97-pcm.c
index d7dc9bd..7e2f360 100644
--- a/sound/soc/blackfin/bf5xx-ac97-pcm.c
+++ b/sound/soc/blackfin/bf5xx-ac97-pcm.c
@@ -453,12 +453,12 @@
 	.pcm_free	= bf5xx_pcm_free_dma_buffers,
 };
 
-static int __devinit bf5xx_soc_platform_probe(struct platform_device *pdev)
+static int bf5xx_soc_platform_probe(struct platform_device *pdev)
 {
 	return snd_soc_register_platform(&pdev->dev, &bf5xx_ac97_soc_platform);
 }
 
-static int __devexit bf5xx_soc_platform_remove(struct platform_device *pdev)
+static int bf5xx_soc_platform_remove(struct platform_device *pdev)
 {
 	snd_soc_unregister_platform(&pdev->dev);
 	return 0;
@@ -471,7 +471,7 @@
 	},
 
 	.probe = bf5xx_soc_platform_probe,
-	.remove = __devexit_p(bf5xx_soc_platform_remove),
+	.remove = bf5xx_soc_platform_remove,
 };
 
 module_platform_driver(bf5xx_pcm_driver);
diff --git a/sound/soc/blackfin/bf5xx-ac97.c b/sound/soc/blackfin/bf5xx-ac97.c
index f4e9dc4..8e41bcb 100644
--- a/sound/soc/blackfin/bf5xx-ac97.c
+++ b/sound/soc/blackfin/bf5xx-ac97.c
@@ -282,7 +282,7 @@
 		.formats = SNDRV_PCM_FMTBIT_S16_LE, },
 };
 
-static int __devinit asoc_bfin_ac97_probe(struct platform_device *pdev)
+static int asoc_bfin_ac97_probe(struct platform_device *pdev)
 {
 	struct sport_device *sport_handle;
 	int ret;
@@ -352,7 +352,7 @@
 	return ret;
 }
 
-static int __devexit asoc_bfin_ac97_remove(struct platform_device *pdev)
+static int asoc_bfin_ac97_remove(struct platform_device *pdev)
 {
 	struct sport_device *sport_handle = platform_get_drvdata(pdev);
 
@@ -372,7 +372,7 @@
 	},
 
 	.probe = asoc_bfin_ac97_probe,
-	.remove = __devexit_p(asoc_bfin_ac97_remove),
+	.remove = asoc_bfin_ac97_remove,
 };
 
 module_platform_driver(asoc_bfin_ac97_driver);
diff --git a/sound/soc/blackfin/bf5xx-ad1836.c b/sound/soc/blackfin/bf5xx-ad1836.c
index 16b9c9e..d23f4b0 100644
--- a/sound/soc/blackfin/bf5xx-ad1836.c
+++ b/sound/soc/blackfin/bf5xx-ad1836.c
@@ -75,7 +75,7 @@
 	.num_links = 1,
 };
 
-static __devinit int bf5xx_ad1836_driver_probe(struct platform_device *pdev)
+static int bf5xx_ad1836_driver_probe(struct platform_device *pdev)
 {
 	struct snd_soc_card *card = &bf5xx_ad1836;
 	const char **link_name;
@@ -98,7 +98,7 @@
 	return ret;
 }
 
-static int __devexit bf5xx_ad1836_driver_remove(struct platform_device *pdev)
+static int bf5xx_ad1836_driver_remove(struct platform_device *pdev)
 {
 	struct snd_soc_card *card = platform_get_drvdata(pdev);
 
@@ -113,7 +113,7 @@
 		.pm = &snd_soc_pm_ops,
 	},
 	.probe = bf5xx_ad1836_driver_probe,
-	.remove = __devexit_p(bf5xx_ad1836_driver_remove),
+	.remove = bf5xx_ad1836_driver_remove,
 };
 module_platform_driver(bf5xx_ad1836_driver);
 
diff --git a/sound/soc/blackfin/bf5xx-i2s-pcm.c b/sound/soc/blackfin/bf5xx-i2s-pcm.c
index 63205d7..262c1de 100644
--- a/sound/soc/blackfin/bf5xx-i2s-pcm.c
+++ b/sound/soc/blackfin/bf5xx-i2s-pcm.c
@@ -292,12 +292,12 @@
 	.pcm_free	= bf5xx_pcm_free_dma_buffers,
 };
 
-static int __devinit bfin_i2s_soc_platform_probe(struct platform_device *pdev)
+static int bfin_i2s_soc_platform_probe(struct platform_device *pdev)
 {
 	return snd_soc_register_platform(&pdev->dev, &bf5xx_i2s_soc_platform);
 }
 
-static int __devexit bfin_i2s_soc_platform_remove(struct platform_device *pdev)
+static int bfin_i2s_soc_platform_remove(struct platform_device *pdev)
 {
 	snd_soc_unregister_platform(&pdev->dev);
 	return 0;
@@ -310,7 +310,7 @@
 	},
 
 	.probe = bfin_i2s_soc_platform_probe,
-	.remove = __devexit_p(bfin_i2s_soc_platform_remove),
+	.remove = bfin_i2s_soc_platform_remove,
 };
 
 module_platform_driver(bfin_i2s_pcm_driver);
diff --git a/sound/soc/blackfin/bf5xx-i2s.c b/sound/soc/blackfin/bf5xx-i2s.c
index 4dccf03..168d88b 100644
--- a/sound/soc/blackfin/bf5xx-i2s.c
+++ b/sound/soc/blackfin/bf5xx-i2s.c
@@ -245,7 +245,7 @@
 	.ops = &bf5xx_i2s_dai_ops,
 };
 
-static int __devinit bf5xx_i2s_probe(struct platform_device *pdev)
+static int bf5xx_i2s_probe(struct platform_device *pdev)
 {
 	struct sport_device *sport_handle;
 	int ret;
@@ -267,7 +267,7 @@
 	return 0;
 }
 
-static int __devexit bf5xx_i2s_remove(struct platform_device *pdev)
+static int bf5xx_i2s_remove(struct platform_device *pdev)
 {
 	struct sport_device *sport_handle = platform_get_drvdata(pdev);
 
@@ -281,7 +281,7 @@
 
 static struct platform_driver bfin_i2s_driver = {
 	.probe  = bf5xx_i2s_probe,
-	.remove = __devexit_p(bf5xx_i2s_remove),
+	.remove = bf5xx_i2s_remove,
 	.driver = {
 		.name = "bfin-i2s",
 		.owner = THIS_MODULE,
diff --git a/sound/soc/blackfin/bf5xx-tdm-pcm.c b/sound/soc/blackfin/bf5xx-tdm-pcm.c
index 254490c..0e6b888 100644
--- a/sound/soc/blackfin/bf5xx-tdm-pcm.c
+++ b/sound/soc/blackfin/bf5xx-tdm-pcm.c
@@ -317,12 +317,12 @@
 	.pcm_free       = bf5xx_pcm_free_dma_buffers,
 };
 
-static int __devinit bf5xx_soc_platform_probe(struct platform_device *pdev)
+static int bf5xx_soc_platform_probe(struct platform_device *pdev)
 {
 	return snd_soc_register_platform(&pdev->dev, &bf5xx_tdm_soc_platform);
 }
 
-static int __devexit bf5xx_soc_platform_remove(struct platform_device *pdev)
+static int bf5xx_soc_platform_remove(struct platform_device *pdev)
 {
 	snd_soc_unregister_platform(&pdev->dev);
 	return 0;
@@ -335,7 +335,7 @@
 	},
 
 	.probe = bf5xx_soc_platform_probe,
-	.remove = __devexit_p(bf5xx_soc_platform_remove),
+	.remove = bf5xx_soc_platform_remove,
 };
 
 module_platform_driver(bfin_tdm_driver);
diff --git a/sound/soc/blackfin/bf5xx-tdm.c b/sound/soc/blackfin/bf5xx-tdm.c
index 594f882..c1e516e 100644
--- a/sound/soc/blackfin/bf5xx-tdm.c
+++ b/sound/soc/blackfin/bf5xx-tdm.c
@@ -249,7 +249,7 @@
 	.ops = &bf5xx_tdm_dai_ops,
 };
 
-static int __devinit bfin_tdm_probe(struct platform_device *pdev)
+static int bfin_tdm_probe(struct platform_device *pdev)
 {
 	struct sport_device *sport_handle;
 	int ret;
@@ -295,7 +295,7 @@
 	return ret;
 }
 
-static int __devexit bfin_tdm_remove(struct platform_device *pdev)
+static int bfin_tdm_remove(struct platform_device *pdev)
 {
 	struct sport_device *sport_handle = platform_get_drvdata(pdev);
 
@@ -307,7 +307,7 @@
 
 static struct platform_driver bfin_tdm_driver = {
 	.probe  = bfin_tdm_probe,
-	.remove = __devexit_p(bfin_tdm_remove),
+	.remove = bfin_tdm_remove,
 	.driver = {
 		.name   = "bfin-tdm",
 		.owner  = THIS_MODULE,
diff --git a/sound/soc/blackfin/bf6xx-i2s.c b/sound/soc/blackfin/bf6xx-i2s.c
index c3c2466..8f33797 100644
--- a/sound/soc/blackfin/bf6xx-i2s.c
+++ b/sound/soc/blackfin/bf6xx-i2s.c
@@ -186,7 +186,7 @@
 	.ops = &bfin_i2s_dai_ops,
 };
 
-static int __devinit bfin_i2s_probe(struct platform_device *pdev)
+static int bfin_i2s_probe(struct platform_device *pdev)
 {
 	struct sport_device *sport;
 	struct device *dev = &pdev->dev;
@@ -208,7 +208,7 @@
 	return 0;
 }
 
-static int __devexit bfin_i2s_remove(struct platform_device *pdev)
+static int bfin_i2s_remove(struct platform_device *pdev)
 {
 	struct sport_device *sport = platform_get_drvdata(pdev);
 
@@ -220,7 +220,7 @@
 
 static struct platform_driver bfin_i2s_driver = {
 	.probe  = bfin_i2s_probe,
-	.remove = __devexit_p(bfin_i2s_remove),
+	.remove = bfin_i2s_remove,
 	.driver = {
 		.name = "bfin-i2s",
 		.owner = THIS_MODULE,
diff --git a/sound/soc/blackfin/bfin-eval-adau1373.c b/sound/soc/blackfin/bfin-eval-adau1373.c
index f3adbdb..4ef9683 100644
--- a/sound/soc/blackfin/bfin-eval-adau1373.c
+++ b/sound/soc/blackfin/bfin-eval-adau1373.c
@@ -157,7 +157,7 @@
 	return snd_soc_register_card(&bfin_eval_adau1373);
 }
 
-static int __devexit bfin_eval_adau1373_remove(struct platform_device *pdev)
+static int bfin_eval_adau1373_remove(struct platform_device *pdev)
 {
 	struct snd_soc_card *card = platform_get_drvdata(pdev);
 
@@ -173,7 +173,7 @@
 		.pm = &snd_soc_pm_ops,
 	},
 	.probe = bfin_eval_adau1373_probe,
-	.remove = __devexit_p(bfin_eval_adau1373_remove),
+	.remove = bfin_eval_adau1373_remove,
 };
 
 module_platform_driver(bfin_eval_adau1373_driver);
diff --git a/sound/soc/blackfin/bfin-eval-adau1701.c b/sound/soc/blackfin/bfin-eval-adau1701.c
index b0531fc..3b55081 100644
--- a/sound/soc/blackfin/bfin-eval-adau1701.c
+++ b/sound/soc/blackfin/bfin-eval-adau1701.c
@@ -97,7 +97,7 @@
 	return snd_soc_register_card(&bfin_eval_adau1701);
 }
 
-static int __devexit bfin_eval_adau1701_remove(struct platform_device *pdev)
+static int bfin_eval_adau1701_remove(struct platform_device *pdev)
 {
 	struct snd_soc_card *card = platform_get_drvdata(pdev);
 
@@ -113,7 +113,7 @@
 		.pm = &snd_soc_pm_ops,
 	},
 	.probe = bfin_eval_adau1701_probe,
-	.remove = __devexit_p(bfin_eval_adau1701_remove),
+	.remove = bfin_eval_adau1701_remove,
 };
 
 module_platform_driver(bfin_eval_adau1701_driver);
diff --git a/sound/soc/blackfin/bfin-eval-adav80x.c b/sound/soc/blackfin/bfin-eval-adav80x.c
index 84b09987..3b1b61a4 100644
--- a/sound/soc/blackfin/bfin-eval-adav80x.c
+++ b/sound/soc/blackfin/bfin-eval-adav80x.c
@@ -122,7 +122,7 @@
 	return snd_soc_register_card(&bfin_eval_adav80x);
 }
 
-static int __devexit bfin_eval_adav80x_remove(struct platform_device *pdev)
+static int bfin_eval_adav80x_remove(struct platform_device *pdev)
 {
 	struct snd_soc_card *card = platform_get_drvdata(pdev);
 
@@ -145,7 +145,7 @@
 		.pm = &snd_soc_pm_ops,
 	},
 	.probe = bfin_eval_adav80x_probe,
-	.remove = __devexit_p(bfin_eval_adav80x_remove),
+	.remove = bfin_eval_adav80x_remove,
 	.id_table = bfin_eval_adav80x_ids,
 };
 
diff --git a/sound/soc/cirrus/edb93xx.c b/sound/soc/cirrus/edb93xx.c
index e01cb02..5db68cf 100644
--- a/sound/soc/cirrus/edb93xx.c
+++ b/sound/soc/cirrus/edb93xx.c
@@ -80,7 +80,7 @@
 	.num_links	= 1,
 };
 
-static int __devinit edb93xx_probe(struct platform_device *pdev)
+static int edb93xx_probe(struct platform_device *pdev)
 {
 	struct snd_soc_card *card = &snd_soc_edb93xx;
 	int ret;
@@ -101,7 +101,7 @@
 	return ret;
 }
 
-static int __devexit edb93xx_remove(struct platform_device *pdev)
+static int edb93xx_remove(struct platform_device *pdev)
 {
 	struct snd_soc_card *card = platform_get_drvdata(pdev);
 
@@ -117,7 +117,7 @@
 		.owner	= THIS_MODULE,
 	},
 	.probe		= edb93xx_probe,
-	.remove		= __devexit_p(edb93xx_remove),
+	.remove		= edb93xx_remove,
 };
 
 module_platform_driver(edb93xx_driver);
diff --git a/sound/soc/cirrus/ep93xx-ac97.c b/sound/soc/cirrus/ep93xx-ac97.c
index c352165..f3f50e6 100644
--- a/sound/soc/cirrus/ep93xx-ac97.c
+++ b/sound/soc/cirrus/ep93xx-ac97.c
@@ -352,7 +352,7 @@
 	.ops			= &ep93xx_ac97_dai_ops,
 };
 
-static int __devinit ep93xx_ac97_probe(struct platform_device *pdev)
+static int ep93xx_ac97_probe(struct platform_device *pdev)
 {
 	struct ep93xx_ac97_info *info;
 	struct resource *res;
@@ -402,7 +402,7 @@
 	return ret;
 }
 
-static int __devexit ep93xx_ac97_remove(struct platform_device *pdev)
+static int ep93xx_ac97_remove(struct platform_device *pdev)
 {
 	struct ep93xx_ac97_info	*info = platform_get_drvdata(pdev);
 
@@ -420,7 +420,7 @@
 
 static struct platform_driver ep93xx_ac97_driver = {
 	.probe	= ep93xx_ac97_probe,
-	.remove	= __devexit_p(ep93xx_ac97_remove),
+	.remove	= ep93xx_ac97_remove,
 	.driver = {
 		.name = "ep93xx-ac97",
 		.owner = THIS_MODULE,
diff --git a/sound/soc/cirrus/ep93xx-i2s.c b/sound/soc/cirrus/ep93xx-i2s.c
index ac4a751..3365d4e 100644
--- a/sound/soc/cirrus/ep93xx-i2s.c
+++ b/sound/soc/cirrus/ep93xx-i2s.c
@@ -422,7 +422,7 @@
 	return err;
 }
 
-static int __devexit ep93xx_i2s_remove(struct platform_device *pdev)
+static int ep93xx_i2s_remove(struct platform_device *pdev)
 {
 	struct ep93xx_i2s_info *info = dev_get_drvdata(&pdev->dev);
 
@@ -436,7 +436,7 @@
 
 static struct platform_driver ep93xx_i2s_driver = {
 	.probe	= ep93xx_i2s_probe,
-	.remove	= __devexit_p(ep93xx_i2s_remove),
+	.remove	= ep93xx_i2s_remove,
 	.driver	= {
 		.name	= "ep93xx-i2s",
 		.owner	= THIS_MODULE,
diff --git a/sound/soc/cirrus/ep93xx-pcm.c b/sound/soc/cirrus/ep93xx-pcm.c
index 665d9c9..72eb7a4 100644
--- a/sound/soc/cirrus/ep93xx-pcm.c
+++ b/sound/soc/cirrus/ep93xx-pcm.c
@@ -213,12 +213,12 @@
 	.pcm_free	= &ep93xx_pcm_free_dma_buffers,
 };
 
-static int __devinit ep93xx_soc_platform_probe(struct platform_device *pdev)
+static int ep93xx_soc_platform_probe(struct platform_device *pdev)
 {
 	return snd_soc_register_platform(&pdev->dev, &ep93xx_soc_platform);
 }
 
-static int __devexit ep93xx_soc_platform_remove(struct platform_device *pdev)
+static int ep93xx_soc_platform_remove(struct platform_device *pdev)
 {
 	snd_soc_unregister_platform(&pdev->dev);
 	return 0;
@@ -231,7 +231,7 @@
 	},
 
 	.probe = ep93xx_soc_platform_probe,
-	.remove = __devexit_p(ep93xx_soc_platform_remove),
+	.remove = ep93xx_soc_platform_remove,
 };
 
 module_platform_driver(ep93xx_pcm_driver);
diff --git a/sound/soc/cirrus/simone.c b/sound/soc/cirrus/simone.c
index dd99709..a397bb0 100644
--- a/sound/soc/cirrus/simone.c
+++ b/sound/soc/cirrus/simone.c
@@ -41,7 +41,7 @@
 
 static struct platform_device *simone_snd_ac97_device;
 
-static int __devinit simone_probe(struct platform_device *pdev)
+static int simone_probe(struct platform_device *pdev)
 {
 	struct snd_soc_card *card = &snd_soc_simone;
 	int ret;
@@ -63,7 +63,7 @@
 	return ret;
 }
 
-static int __devexit simone_remove(struct platform_device *pdev)
+static int simone_remove(struct platform_device *pdev)
 {
 	struct snd_soc_card *card = platform_get_drvdata(pdev);
 
@@ -79,7 +79,7 @@
 		.owner	= THIS_MODULE,
 	},
 	.probe		= simone_probe,
-	.remove		= __devexit_p(simone_remove),
+	.remove		= simone_remove,
 };
 
 module_platform_driver(simone_driver);
diff --git a/sound/soc/cirrus/snappercl15.c b/sound/soc/cirrus/snappercl15.c
index a193cea..9d77fe2 100644
--- a/sound/soc/cirrus/snappercl15.c
+++ b/sound/soc/cirrus/snappercl15.c
@@ -98,7 +98,7 @@
 	.num_links	= 1,
 };
 
-static int __devinit snappercl15_probe(struct platform_device *pdev)
+static int snappercl15_probe(struct platform_device *pdev)
 {
 	struct snd_soc_card *card = &snd_soc_snappercl15;
 	int ret;
@@ -119,7 +119,7 @@
 	return ret;
 }
 
-static int __devexit snappercl15_remove(struct platform_device *pdev)
+static int snappercl15_remove(struct platform_device *pdev)
 {
 	struct snd_soc_card *card = platform_get_drvdata(pdev);
 
@@ -135,7 +135,7 @@
 		.owner	= THIS_MODULE,
 	},
 	.probe		= snappercl15_probe,
-	.remove		= __devexit_p(snappercl15_remove),
+	.remove		= snappercl15_remove,
 };
 
 module_platform_driver(snappercl15_driver);
diff --git a/sound/soc/codecs/88pm860x-codec.c b/sound/soc/codecs/88pm860x-codec.c
index 9fd3b68..60159c0 100644
--- a/sound/soc/codecs/88pm860x-codec.c
+++ b/sound/soc/codecs/88pm860x-codec.c
@@ -1423,7 +1423,7 @@
 	.num_dapm_routes = ARRAY_SIZE(pm860x_dapm_routes),
 };
 
-static int __devinit pm860x_codec_probe(struct platform_device *pdev)
+static int pm860x_codec_probe(struct platform_device *pdev)
 {
 	struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent);
 	struct pm860x_priv *pm860x;
@@ -1463,7 +1463,7 @@
 	return -EINVAL;
 }
 
-static int __devexit pm860x_codec_remove(struct platform_device *pdev)
+static int pm860x_codec_remove(struct platform_device *pdev)
 {
 	snd_soc_unregister_codec(&pdev->dev);
 	platform_set_drvdata(pdev, NULL);
@@ -1476,7 +1476,7 @@
 		.owner	= THIS_MODULE,
 	},
 	.probe	= pm860x_codec_probe,
-	.remove	= __devexit_p(pm860x_codec_remove),
+	.remove	= pm860x_codec_remove,
 };
 
 module_platform_driver(pm860x_codec_driver);
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index b92759a..3a84782 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -44,6 +44,7 @@
 	select SND_SOC_LM4857 if I2C
 	select SND_SOC_LM49453 if I2C
 	select SND_SOC_MAX98088 if I2C
+	select SND_SOC_MAX98090 if I2C
 	select SND_SOC_MAX98095 if I2C
 	select SND_SOC_MAX9850 if I2C
 	select SND_SOC_MAX9768 if I2C
@@ -54,6 +55,7 @@
 	select SND_SOC_PCM3008
 	select SND_SOC_RT5631 if I2C
 	select SND_SOC_SGTL5000 if I2C
+	select SND_SOC_SI476X if MFD_SI476X_CORE
 	select SND_SOC_SN95031 if INTEL_SCU_IPC
 	select SND_SOC_SPDIF
 	select SND_SOC_SSM2602 if SND_SOC_I2C_AND_SPI
@@ -146,6 +148,13 @@
 	default y if SND_SOC_WM8993=y || SND_SOC_WM8994=y
 	default m if SND_SOC_WM8993=m || SND_SOC_WM8994=m
 
+config SND_SOC_WM_ADSP
+	tristate
+	default y if SND_SOC_WM5102=y
+	default y if SND_SOC_WM2200=y
+	default m if SND_SOC_WM5102=m
+	default m if SND_SOC_WM2200=m
+
 config SND_SOC_AB8500_CODEC
 	tristate
 
@@ -229,6 +238,7 @@
 	tristate
 
 config SND_SOC_JZ4740_CODEC
+	select REGMAP_MMIO
 	tristate
 
 config SND_SOC_L3
@@ -258,6 +268,9 @@
 config SND_SOC_MAX98088
        tristate
 
+config SND_SOC_MAX98090
+       tristate
+
 config SND_SOC_MAX98095
        tristate
 
@@ -277,6 +290,9 @@
 config SND_SOC_SGTL5000
 	tristate
 
+config SND_SOC_SI476X
+	tristate
+
 config SND_SOC_SIGMADSP
 	tristate
 	select CRC32
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index 9bd4d95..f6e8e36 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -34,6 +34,7 @@
 snd-soc-lm49453-objs := lm49453.o
 snd-soc-max9768-objs := max9768.o
 snd-soc-max98088-objs := max98088.o
+snd-soc-max98090-objs := max98090.o
 snd-soc-max98095-objs := max98095.o
 snd-soc-max9850-objs := max9850.o
 snd-soc-mc13783-objs := mc13783.o
@@ -45,6 +46,7 @@
 snd-soc-alc5623-objs := alc5623.o
 snd-soc-alc5632-objs := alc5632.o
 snd-soc-sigmadsp-objs := sigmadsp.o
+snd-soc-si476x-objs := si476x.o
 snd-soc-sn95031-objs := sn95031.o
 snd-soc-spdif-tx-objs := spdif_transciever.o
 snd-soc-spdif-rx-objs := spdif_receiver.o
@@ -62,6 +64,7 @@
 snd-soc-uda134x-objs := uda134x.o
 snd-soc-uda1380-objs := uda1380.o
 snd-soc-wl1273-objs := wl1273.o
+snd-soc-wm-adsp-objs := wm_adsp.o
 snd-soc-wm0010-objs := wm0010.o
 snd-soc-wm1250-ev1-objs := wm1250-ev1.o
 snd-soc-wm2000-objs := wm2000.o
@@ -155,6 +158,7 @@
 obj-$(CONFIG_SND_SOC_LM49453)   += snd-soc-lm49453.o
 obj-$(CONFIG_SND_SOC_MAX9768)	+= snd-soc-max9768.o
 obj-$(CONFIG_SND_SOC_MAX98088)	+= snd-soc-max98088.o
+obj-$(CONFIG_SND_SOC_MAX98090)	+= snd-soc-max98090.o
 obj-$(CONFIG_SND_SOC_MAX98095)	+= snd-soc-max98095.o
 obj-$(CONFIG_SND_SOC_MAX9850)	+= snd-soc-max9850.o
 obj-$(CONFIG_SND_SOC_MC13783)	+= snd-soc-mc13783.o
@@ -164,6 +168,7 @@
 obj-$(CONFIG_SND_SOC_RT5631)	+= snd-soc-rt5631.o
 obj-$(CONFIG_SND_SOC_SGTL5000)  += snd-soc-sgtl5000.o
 obj-$(CONFIG_SND_SOC_SIGMADSP)	+= snd-soc-sigmadsp.o
+obj-$(CONFIG_SND_SOC_SI476X)	+= snd-soc-si476x.o
 obj-$(CONFIG_SND_SOC_SN95031)	+=snd-soc-sn95031.o
 obj-$(CONFIG_SND_SOC_SPDIF)	+= snd-soc-spdif-rx.o snd-soc-spdif-tx.o
 obj-$(CONFIG_SND_SOC_SSM2602)	+= snd-soc-ssm2602.o
@@ -229,6 +234,7 @@
 obj-$(CONFIG_SND_SOC_WM9705)	+= snd-soc-wm9705.o
 obj-$(CONFIG_SND_SOC_WM9712)	+= snd-soc-wm9712.o
 obj-$(CONFIG_SND_SOC_WM9713)	+= snd-soc-wm9713.o
+obj-$(CONFIG_SND_SOC_WM_ADSP)	+= snd-soc-wm-adsp.o
 obj-$(CONFIG_SND_SOC_WM_HUBS)	+= snd-soc-wm-hubs.o
 
 # Amp
diff --git a/sound/soc/codecs/ab8500-codec.c b/sound/soc/codecs/ab8500-codec.c
index af54749..6c12ac2 100644
--- a/sound/soc/codecs/ab8500-codec.c
+++ b/sound/soc/codecs/ab8500-codec.c
@@ -2356,7 +2356,7 @@
 	return 0;
 }
 
-struct snd_soc_dai_driver ab8500_codec_dai[] = {
+static struct snd_soc_dai_driver ab8500_codec_dai[] = {
 	{
 		.name = "ab8500-codec-dai.0",
 		.id = 0,
@@ -2554,7 +2554,7 @@
 	.num_dapm_routes =	ARRAY_SIZE(ab8500_dapm_routes),
 };
 
-static int __devinit ab8500_codec_driver_probe(struct platform_device *pdev)
+static int ab8500_codec_driver_probe(struct platform_device *pdev)
 {
 	int status;
 	struct ab8500_codec_drvdata *drvdata;
@@ -2580,7 +2580,7 @@
 	return status;
 }
 
-static int __devexit ab8500_codec_driver_remove(struct platform_device *pdev)
+static int ab8500_codec_driver_remove(struct platform_device *pdev)
 {
 	dev_info(&pdev->dev, "%s Enter.\n", __func__);
 
@@ -2595,7 +2595,7 @@
 		.owner	= THIS_MODULE,
 	},
 	.probe		= ab8500_codec_driver_probe,
-	.remove		= __devexit_p(ab8500_codec_driver_remove),
+	.remove		= ab8500_codec_driver_remove,
 	.suspend	= NULL,
 	.resume		= NULL,
 };
diff --git a/sound/soc/codecs/ac97.c b/sound/soc/codecs/ac97.c
index ea06b83..ef2ae32 100644
--- a/sound/soc/codecs/ac97.c
+++ b/sound/soc/codecs/ac97.c
@@ -118,13 +118,13 @@
 	.resume =	ac97_soc_resume,
 };
 
-static __devinit int ac97_probe(struct platform_device *pdev)
+static int ac97_probe(struct platform_device *pdev)
 {
 	return snd_soc_register_codec(&pdev->dev,
 			&soc_codec_dev_ac97, &ac97_dai, 1);
 }
 
-static int __devexit ac97_remove(struct platform_device *pdev)
+static int ac97_remove(struct platform_device *pdev)
 {
 	snd_soc_unregister_codec(&pdev->dev);
 	return 0;
@@ -137,7 +137,7 @@
 	},
 
 	.probe = ac97_probe,
-	.remove = __devexit_p(ac97_remove),
+	.remove = ac97_remove,
 };
 
 module_platform_driver(ac97_codec_driver);
diff --git a/sound/soc/codecs/ad1836.c b/sound/soc/codecs/ad1836.c
index dce6ebe..9a92b79 100644
--- a/sound/soc/codecs/ad1836.c
+++ b/sound/soc/codecs/ad1836.c
@@ -360,7 +360,7 @@
 	.cache_type = REGCACHE_RBTREE,
 };
 
-static int __devinit ad1836_spi_probe(struct spi_device *spi)
+static int ad1836_spi_probe(struct spi_device *spi)
 {
 	struct ad1836_priv *ad1836;
 	int ret;
@@ -383,7 +383,7 @@
 	return ret;
 }
 
-static int __devexit ad1836_spi_remove(struct spi_device *spi)
+static int ad1836_spi_remove(struct spi_device *spi)
 {
 	snd_soc_unregister_codec(&spi->dev);
 	return 0;
@@ -405,7 +405,7 @@
 		.owner	= THIS_MODULE,
 	},
 	.probe		= ad1836_spi_probe,
-	.remove		= __devexit_p(ad1836_spi_remove),
+	.remove		= ad1836_spi_remove,
 	.id_table	= ad1836_ids,
 };
 
diff --git a/sound/soc/codecs/ad193x.c b/sound/soc/codecs/ad193x.c
index 2f75266..aea7e52 100644
--- a/sound/soc/codecs/ad193x.c
+++ b/sound/soc/codecs/ad193x.c
@@ -378,7 +378,7 @@
 	.volatile_reg = adau193x_reg_volatile,
 };
 
-static int __devinit ad193x_spi_probe(struct spi_device *spi)
+static int ad193x_spi_probe(struct spi_device *spi)
 {
 	struct ad193x_priv *ad193x;
 
@@ -397,7 +397,7 @@
 			&ad193x_dai, 1);
 }
 
-static int __devexit ad193x_spi_remove(struct spi_device *spi)
+static int ad193x_spi_remove(struct spi_device *spi)
 {
 	snd_soc_unregister_codec(&spi->dev);
 	return 0;
@@ -409,7 +409,7 @@
 		.owner	= THIS_MODULE,
 	},
 	.probe		= ad193x_spi_probe,
-	.remove		= __devexit_p(ad193x_spi_remove),
+	.remove		= ad193x_spi_remove,
 };
 #endif
 
@@ -430,8 +430,8 @@
 };
 MODULE_DEVICE_TABLE(i2c, ad193x_id);
 
-static int __devinit ad193x_i2c_probe(struct i2c_client *client,
-		const struct i2c_device_id *id)
+static int ad193x_i2c_probe(struct i2c_client *client,
+			    const struct i2c_device_id *id)
 {
 	struct ad193x_priv *ad193x;
 
@@ -450,7 +450,7 @@
 			&ad193x_dai, 1);
 }
 
-static int __devexit ad193x_i2c_remove(struct i2c_client *client)
+static int ad193x_i2c_remove(struct i2c_client *client)
 {
 	snd_soc_unregister_codec(&client->dev);
 	return 0;
@@ -461,7 +461,7 @@
 		.name = "ad193x",
 	},
 	.probe    = ad193x_i2c_probe,
-	.remove   = __devexit_p(ad193x_i2c_remove),
+	.remove   = ad193x_i2c_remove,
 	.id_table = ad193x_id,
 };
 #endif
diff --git a/sound/soc/codecs/ad1980.c b/sound/soc/codecs/ad1980.c
index 8c39ddd..f385342 100644
--- a/sound/soc/codecs/ad1980.c
+++ b/sound/soc/codecs/ad1980.c
@@ -255,13 +255,13 @@
 	.read = ac97_read,
 };
 
-static __devinit int ad1980_probe(struct platform_device *pdev)
+static int ad1980_probe(struct platform_device *pdev)
 {
 	return snd_soc_register_codec(&pdev->dev,
 			&soc_codec_dev_ad1980, &ad1980_dai, 1);
 }
 
-static int __devexit ad1980_remove(struct platform_device *pdev)
+static int ad1980_remove(struct platform_device *pdev)
 {
 	snd_soc_unregister_codec(&pdev->dev);
 	return 0;
@@ -274,7 +274,7 @@
 	},
 
 	.probe = ad1980_probe,
-	.remove = __devexit_p(ad1980_remove),
+	.remove = ad1980_remove,
 };
 
 module_platform_driver(ad1980_codec_driver);
diff --git a/sound/soc/codecs/ad73311.c b/sound/soc/codecs/ad73311.c
index ee7a68d..b1f2baf 100644
--- a/sound/soc/codecs/ad73311.c
+++ b/sound/soc/codecs/ad73311.c
@@ -47,7 +47,7 @@
 			&soc_codec_dev_ad73311, &ad73311_dai, 1);
 }
 
-static int __devexit ad73311_remove(struct platform_device *pdev)
+static int ad73311_remove(struct platform_device *pdev)
 {
 	snd_soc_unregister_codec(&pdev->dev);
 	return 0;
@@ -60,7 +60,7 @@
 	},
 
 	.probe = ad73311_probe,
-	.remove = __devexit_p(ad73311_remove),
+	.remove = ad73311_remove,
 };
 
 module_platform_driver(ad73311_codec_driver);
diff --git a/sound/soc/codecs/adau1373.c b/sound/soc/codecs/adau1373.c
index 704544b..068b3ae 100644
--- a/sound/soc/codecs/adau1373.c
+++ b/sound/soc/codecs/adau1373.c
@@ -1353,8 +1353,8 @@
 	.num_dapm_routes = ARRAY_SIZE(adau1373_dapm_routes),
 };
 
-static int __devinit adau1373_i2c_probe(struct i2c_client *client,
-	const struct i2c_device_id *id)
+static int adau1373_i2c_probe(struct i2c_client *client,
+			      const struct i2c_device_id *id)
 {
 	struct adau1373 *adau1373;
 	int ret;
@@ -1370,7 +1370,7 @@
 	return ret;
 }
 
-static int __devexit adau1373_i2c_remove(struct i2c_client *client)
+static int adau1373_i2c_remove(struct i2c_client *client)
 {
 	snd_soc_unregister_codec(&client->dev);
 	return 0;
@@ -1388,7 +1388,7 @@
 		.owner = THIS_MODULE,
 	},
 	.probe = adau1373_i2c_probe,
-	.remove = __devexit_p(adau1373_i2c_remove),
+	.remove = adau1373_i2c_remove,
 	.id_table = adau1373_i2c_id,
 };
 
diff --git a/sound/soc/codecs/adau1701.c b/sound/soc/codecs/adau1701.c
index 51f2f3c..dafdbe8 100644
--- a/sound/soc/codecs/adau1701.c
+++ b/sound/soc/codecs/adau1701.c
@@ -489,8 +489,8 @@
 	.set_sysclk		= adau1701_set_sysclk,
 };
 
-static __devinit int adau1701_i2c_probe(struct i2c_client *client,
-		const struct i2c_device_id *id)
+static int adau1701_i2c_probe(struct i2c_client *client,
+			      const struct i2c_device_id *id)
 {
 	struct adau1701 *adau1701;
 	int ret;
@@ -505,7 +505,7 @@
 	return ret;
 }
 
-static __devexit int adau1701_i2c_remove(struct i2c_client *client)
+static int adau1701_i2c_remove(struct i2c_client *client)
 {
 	snd_soc_unregister_codec(&client->dev);
 	return 0;
@@ -523,7 +523,7 @@
 		.owner	= THIS_MODULE,
 	},
 	.probe		= adau1701_i2c_probe,
-	.remove		= __devexit_p(adau1701_i2c_remove),
+	.remove		= adau1701_i2c_remove,
 	.id_table	= adau1701_i2c_id,
 };
 
diff --git a/sound/soc/codecs/adav80x.c b/sound/soc/codecs/adav80x.c
index ebd7b37..3c839cc 100644
--- a/sound/soc/codecs/adav80x.c
+++ b/sound/soc/codecs/adav80x.c
@@ -839,8 +839,8 @@
 	.num_dapm_routes = ARRAY_SIZE(adav80x_dapm_routes),
 };
 
-static int __devinit adav80x_bus_probe(struct device *dev,
-		enum snd_soc_control_type control_type)
+static int adav80x_bus_probe(struct device *dev,
+			     enum snd_soc_control_type control_type)
 {
 	struct adav80x *adav80x;
 	int ret;
@@ -860,7 +860,7 @@
 	return ret;
 }
 
-static int __devexit adav80x_bus_remove(struct device *dev)
+static int adav80x_bus_remove(struct device *dev)
 {
 	snd_soc_unregister_codec(dev);
 	kfree(dev_get_drvdata(dev));
@@ -868,12 +868,12 @@
 }
 
 #if defined(CONFIG_SPI_MASTER)
-static int __devinit adav80x_spi_probe(struct spi_device *spi)
+static int adav80x_spi_probe(struct spi_device *spi)
 {
 	return adav80x_bus_probe(&spi->dev, SND_SOC_SPI);
 }
 
-static int __devexit adav80x_spi_remove(struct spi_device *spi)
+static int adav80x_spi_remove(struct spi_device *spi)
 {
 	return adav80x_bus_remove(&spi->dev);
 }
@@ -884,7 +884,7 @@
 		.owner	= THIS_MODULE,
 	},
 	.probe		= adav80x_spi_probe,
-	.remove		= __devexit_p(adav80x_spi_remove),
+	.remove		= adav80x_spi_remove,
 };
 #endif
 
@@ -895,13 +895,13 @@
 };
 MODULE_DEVICE_TABLE(i2c, adav80x_id);
 
-static int __devinit adav80x_i2c_probe(struct i2c_client *client,
-		const struct i2c_device_id *id)
+static int adav80x_i2c_probe(struct i2c_client *client,
+			     const struct i2c_device_id *id)
 {
 	return adav80x_bus_probe(&client->dev, SND_SOC_I2C);
 }
 
-static int __devexit adav80x_i2c_remove(struct i2c_client *client)
+static int adav80x_i2c_remove(struct i2c_client *client)
 {
 	return adav80x_bus_remove(&client->dev);
 }
@@ -912,7 +912,7 @@
 		.owner = THIS_MODULE,
 	},
 	.probe = adav80x_i2c_probe,
-	.remove = __devexit_p(adav80x_i2c_remove),
+	.remove = adav80x_i2c_remove,
 	.id_table = adav80x_id,
 };
 #endif
diff --git a/sound/soc/codecs/ads117x.c b/sound/soc/codecs/ads117x.c
index 8103b93..506d474 100644
--- a/sound/soc/codecs/ads117x.c
+++ b/sound/soc/codecs/ads117x.c
@@ -36,13 +36,13 @@
 
 static struct snd_soc_codec_driver soc_codec_dev_ads117x;
 
-static __devinit int ads117x_probe(struct platform_device *pdev)
+static int ads117x_probe(struct platform_device *pdev)
 {
 	return snd_soc_register_codec(&pdev->dev,
 			&soc_codec_dev_ads117x, &ads117x_dai, 1);
 }
 
-static int __devexit ads117x_remove(struct platform_device *pdev)
+static int ads117x_remove(struct platform_device *pdev)
 {
 	snd_soc_unregister_codec(&pdev->dev);
 	return 0;
@@ -55,7 +55,7 @@
 	},
 
 	.probe = ads117x_probe,
-	.remove = __devexit_p(ads117x_remove),
+	.remove = ads117x_remove,
 };
 
 module_platform_driver(ads117x_codec_driver);
diff --git a/sound/soc/codecs/ak4104.c b/sound/soc/codecs/ak4104.c
index 31d4483..6f6c335 100644
--- a/sound/soc/codecs/ak4104.c
+++ b/sound/soc/codecs/ak4104.c
@@ -15,6 +15,8 @@
 #include <sound/soc.h>
 #include <sound/initval.h>
 #include <linux/spi/spi.h>
+#include <linux/of_device.h>
+#include <linux/of_gpio.h>
 #include <sound/asoundef.h>
 
 /* AK4104 registers addresses */
@@ -98,14 +100,32 @@
 	val = 0;
 
 	switch (params_rate(params)) {
+	case 22050:
+		val |= IEC958_AES3_CON_FS_22050;
+		break;
+	case 24000:
+		val |= IEC958_AES3_CON_FS_24000;
+		break;
+	case 32000:
+		val |= IEC958_AES3_CON_FS_32000;
+		break;
 	case 44100:
 		val |= IEC958_AES3_CON_FS_44100;
 		break;
 	case 48000:
 		val |= IEC958_AES3_CON_FS_48000;
 		break;
-	case 32000:
-		val |= IEC958_AES3_CON_FS_32000;
+	case 88200:
+		val |= IEC958_AES3_CON_FS_88200;
+		break;
+	case 96000:
+		val |= IEC958_AES3_CON_FS_96000;
+		break;
+	case 176400:
+		val |= IEC958_AES3_CON_FS_176400;
+		break;
+	case 192000:
+		val |= IEC958_AES3_CON_FS_192000;
 		break;
 	default:
 		dev_err(codec->dev, "unsupported sampling rate\n");
@@ -186,6 +206,7 @@
 
 static int ak4104_spi_probe(struct spi_device *spi)
 {
+	struct device_node *np = spi->dev.of_node;
 	struct ak4104_private *ak4104;
 	unsigned int val;
 	int ret;
@@ -201,52 +222,62 @@
 	if (ak4104 == NULL)
 		return -ENOMEM;
 
-	ak4104->regmap = regmap_init_spi(spi, &ak4104_regmap);
+	ak4104->regmap = devm_regmap_init_spi(spi, &ak4104_regmap);
 	if (IS_ERR(ak4104->regmap)) {
 		ret = PTR_ERR(ak4104->regmap);
 		return ret;
 	}
 
+	if (np) {
+		enum of_gpio_flags flags;
+		int gpio = of_get_named_gpio_flags(np, "reset-gpio", 0, &flags);
+
+		if (gpio_is_valid(gpio)) {
+			ret = devm_gpio_request_one(&spi->dev, gpio,
+				     flags & OF_GPIO_ACTIVE_LOW ?
+					GPIOF_OUT_INIT_LOW : GPIOF_OUT_INIT_HIGH,
+				     "ak4104 reset");
+			if (ret < 0)
+				return ret;
+		}
+	}
+
 	/* read the 'reserved' register - according to the datasheet, it
 	 * should contain 0x5b. Not a good way to verify the presence of
 	 * the device, but there is no hardware ID register. */
 	ret = regmap_read(ak4104->regmap, AK4104_REG_RESERVED, &val);
 	if (ret != 0)
-		goto err;
-	if (val != AK4104_RESERVED_VAL) {
-		ret = -ENODEV;
-		goto err;
-	}
+		return ret;
+	if (val != AK4104_RESERVED_VAL)
+		return -ENODEV;
 
 	spi_set_drvdata(spi, ak4104);
 
 	ret = snd_soc_register_codec(&spi->dev,
 			&soc_codec_device_ak4104, &ak4104_dai, 1);
-	if (ret != 0)
-		goto err;
-
-	return 0;
-
-err:
-	regmap_exit(ak4104->regmap);
 	return ret;
 }
 
-static int __devexit ak4104_spi_remove(struct spi_device *spi)
+static int ak4104_spi_remove(struct spi_device *spi)
 {
-	struct ak4104_private *ak4101 = spi_get_drvdata(spi);
-	regmap_exit(ak4101->regmap);
 	snd_soc_unregister_codec(&spi->dev);
 	return 0;
 }
 
+static const struct of_device_id ak4104_of_match[] = {
+	{ .compatible = "asahi-kasei,ak4104", },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, ak4104_of_match);
+
 static struct spi_driver ak4104_spi_driver = {
 	.driver  = {
 		.name   = DRV_NAME,
 		.owner  = THIS_MODULE,
+		.of_match_table = ak4104_of_match,
 	},
 	.probe  = ak4104_spi_probe,
-	.remove = __devexit_p(ak4104_spi_remove),
+	.remove = ak4104_spi_remove,
 };
 
 module_spi_driver(ak4104_spi_driver);
diff --git a/sound/soc/codecs/ak4535.c b/sound/soc/codecs/ak4535.c
index 618fdc3..684fe91 100644
--- a/sound/soc/codecs/ak4535.c
+++ b/sound/soc/codecs/ak4535.c
@@ -436,8 +436,8 @@
 	.num_dapm_routes = ARRAY_SIZE(ak4535_audio_map),
 };
 
-static __devinit int ak4535_i2c_probe(struct i2c_client *i2c,
-				      const struct i2c_device_id *id)
+static int ak4535_i2c_probe(struct i2c_client *i2c,
+			    const struct i2c_device_id *id)
 {
 	struct ak4535_priv *ak4535;
 	int ret;
@@ -447,7 +447,7 @@
 	if (ak4535 == NULL)
 		return -ENOMEM;
 
-	ak4535->regmap = regmap_init_i2c(i2c, &ak4535_regmap);
+	ak4535->regmap = devm_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);
@@ -458,18 +458,13 @@
 
 	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)
+static 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;
 }
 
@@ -485,7 +480,7 @@
 		.owner = THIS_MODULE,
 	},
 	.probe =    ak4535_i2c_probe,
-	.remove =   __devexit_p(ak4535_i2c_remove),
+	.remove =   ak4535_i2c_remove,
 	.id_table = ak4535_i2c_id,
 };
 
diff --git a/sound/soc/codecs/ak4641.c b/sound/soc/codecs/ak4641.c
index 543a12f..5f9af1f 100644
--- a/sound/soc/codecs/ak4641.c
+++ b/sound/soc/codecs/ak4641.c
@@ -557,8 +557,8 @@
 };
 
 
-static int __devinit ak4641_i2c_probe(struct i2c_client *i2c,
-				      const struct i2c_device_id *id)
+static int ak4641_i2c_probe(struct i2c_client *i2c,
+			    const struct i2c_device_id *id)
 {
 	struct ak4641_platform_data *pdata = i2c->dev.platform_data;
 	struct ak4641_priv *ak4641;
@@ -610,7 +610,7 @@
 	return ret;
 }
 
-static int __devexit ak4641_i2c_remove(struct i2c_client *i2c)
+static int ak4641_i2c_remove(struct i2c_client *i2c)
 {
 	struct ak4641_platform_data *pdata = i2c->dev.platform_data;
 
@@ -640,7 +640,7 @@
 		.owner = THIS_MODULE,
 	},
 	.probe =    ak4641_i2c_probe,
-	.remove =   __devexit_p(ak4641_i2c_remove),
+	.remove =   ak4641_i2c_remove,
 	.id_table = ak4641_i2c_id,
 };
 
diff --git a/sound/soc/codecs/ak4642.c b/sound/soc/codecs/ak4642.c
index b3e24f2..1f0cdab 100644
--- a/sound/soc/codecs/ak4642.c
+++ b/sound/soc/codecs/ak4642.c
@@ -194,12 +194,6 @@
 	{"LINEOUT Mixer", "DACL", "DAC"},
 };
 
-/* codec private data */
-struct ak4642_priv {
-	unsigned int sysclk;
-	enum snd_soc_control_type control_type;
-};
-
 /*
  * ak4642 register cache
  */
@@ -468,10 +462,9 @@
 
 static int ak4642_probe(struct snd_soc_codec *codec)
 {
-	struct ak4642_priv *ak4642 = snd_soc_codec_get_drvdata(codec);
 	int ret;
 
-	ret = snd_soc_codec_set_cache_io(codec, 8, 8, ak4642->control_type);
+	ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_I2C);
 	if (ret < 0) {
 		dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
 		return ret;
@@ -520,27 +513,15 @@
 };
 
 #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
-static __devinit int ak4642_i2c_probe(struct i2c_client *i2c,
-				      const struct i2c_device_id *id)
+static int ak4642_i2c_probe(struct i2c_client *i2c,
+			    const struct i2c_device_id *id)
 {
-	struct ak4642_priv *ak4642;
-	int ret;
-
-	ak4642 = devm_kzalloc(&i2c->dev, sizeof(struct ak4642_priv),
-			      GFP_KERNEL);
-	if (!ak4642)
-		return -ENOMEM;
-
-	i2c_set_clientdata(i2c, ak4642);
-	ak4642->control_type = SND_SOC_I2C;
-
-	ret =  snd_soc_register_codec(&i2c->dev,
+	return snd_soc_register_codec(&i2c->dev,
 				(struct snd_soc_codec_driver *)id->driver_data,
 				&ak4642_dai, 1);
-	return ret;
 }
 
-static __devexit int ak4642_i2c_remove(struct i2c_client *client)
+static int ak4642_i2c_remove(struct i2c_client *client)
 {
 	snd_soc_unregister_codec(&client->dev);
 	return 0;
@@ -560,7 +541,7 @@
 		.owner = THIS_MODULE,
 	},
 	.probe		= ak4642_i2c_probe,
-	.remove		= __devexit_p(ak4642_i2c_remove),
+	.remove		= ak4642_i2c_remove,
 	.id_table	= ak4642_i2c_id,
 };
 #endif
diff --git a/sound/soc/codecs/ak4671.c b/sound/soc/codecs/ak4671.c
index 2b45797..25bdf6a 100644
--- a/sound/soc/codecs/ak4671.c
+++ b/sound/soc/codecs/ak4671.c
@@ -655,8 +655,8 @@
 	.num_dapm_routes = ARRAY_SIZE(ak4671_intercon),
 };
 
-static int __devinit ak4671_i2c_probe(struct i2c_client *client,
-		const struct i2c_device_id *id)
+static int ak4671_i2c_probe(struct i2c_client *client,
+			    const struct i2c_device_id *id)
 {
 	struct ak4671_priv *ak4671;
 	int ret;
@@ -674,7 +674,7 @@
 	return ret;
 }
 
-static __devexit int ak4671_i2c_remove(struct i2c_client *client)
+static int ak4671_i2c_remove(struct i2c_client *client)
 {
 	snd_soc_unregister_codec(&client->dev);
 	return 0;
@@ -692,7 +692,7 @@
 		.owner = THIS_MODULE,
 	},
 	.probe = ak4671_i2c_probe,
-	.remove = __devexit_p(ak4671_i2c_remove),
+	.remove = ak4671_i2c_remove,
 	.id_table = ak4671_i2c_id,
 };
 
diff --git a/sound/soc/codecs/alc5623.c b/sound/soc/codecs/alc5623.c
index 1960478..256c364 100644
--- a/sound/soc/codecs/alc5623.c
+++ b/sound/soc/codecs/alc5623.c
@@ -991,8 +991,8 @@
  *    low  = 0x1a
  *    high = 0x1b
  */
-static __devinit int alc5623_i2c_probe(struct i2c_client *client,
-				const struct i2c_device_id *id)
+static int alc5623_i2c_probe(struct i2c_client *client,
+			     const struct i2c_device_id *id)
 {
 	struct alc5623_platform_data *pdata;
 	struct alc5623_priv *alc5623;
@@ -1058,7 +1058,7 @@
 	return ret;
 }
 
-static __devexit int alc5623_i2c_remove(struct i2c_client *client)
+static int alc5623_i2c_remove(struct i2c_client *client)
 {
 	snd_soc_unregister_codec(&client->dev);
 	return 0;
@@ -1079,7 +1079,7 @@
 		.owner = THIS_MODULE,
 	},
 	.probe = alc5623_i2c_probe,
-	.remove =  __devexit_p(alc5623_i2c_remove),
+	.remove =  alc5623_i2c_remove,
 	.id_table = alc5623_i2c_table,
 };
 
diff --git a/sound/soc/codecs/alc5632.c b/sound/soc/codecs/alc5632.c
index 7dd0242..f2e62e4 100644
--- a/sound/soc/codecs/alc5632.c
+++ b/sound/soc/codecs/alc5632.c
@@ -1116,8 +1116,8 @@
  *    low  = 0x1a
  *    high = 0x1b
  */
-static __devinit int alc5632_i2c_probe(struct i2c_client *client,
-				const struct i2c_device_id *id)
+static int alc5632_i2c_probe(struct i2c_client *client,
+			     const struct i2c_device_id *id)
 {
 	struct alc5632_priv *alc5632;
 	int ret, ret1, ret2;
@@ -1179,7 +1179,7 @@
 	return ret;
 }
 
-static __devexit int alc5632_i2c_remove(struct i2c_client *client)
+static int alc5632_i2c_remove(struct i2c_client *client)
 {
 	snd_soc_unregister_codec(&client->dev);
 	return 0;
@@ -1198,7 +1198,7 @@
 		.owner = THIS_MODULE,
 	},
 	.probe = alc5632_i2c_probe,
-	.remove =  __devexit_p(alc5632_i2c_remove),
+	.remove =  alc5632_i2c_remove,
 	.id_table = alc5632_i2c_table,
 };
 
diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c
index 054967d..adf397b 100644
--- a/sound/soc/codecs/arizona.c
+++ b/sound/soc/codecs/arizona.c
@@ -226,6 +226,31 @@
 const DECLARE_TLV_DB_SCALE(arizona_mixer_tlv, -3200, 100, 0);
 EXPORT_SYMBOL_GPL(arizona_mixer_tlv);
 
+static const char *arizona_vol_ramp_text[] = {
+	"0ms/6dB", "0.5ms/6dB", "1ms/6dB", "2ms/6dB", "4ms/6dB", "8ms/6dB",
+	"15ms/6dB", "30ms/6dB",
+};
+
+const struct soc_enum arizona_in_vd_ramp =
+	SOC_ENUM_SINGLE(ARIZONA_INPUT_VOLUME_RAMP,
+			ARIZONA_IN_VD_RAMP_SHIFT, 7, arizona_vol_ramp_text);
+EXPORT_SYMBOL_GPL(arizona_in_vd_ramp);
+
+const struct soc_enum arizona_in_vi_ramp =
+	SOC_ENUM_SINGLE(ARIZONA_INPUT_VOLUME_RAMP,
+			ARIZONA_IN_VI_RAMP_SHIFT, 7, arizona_vol_ramp_text);
+EXPORT_SYMBOL_GPL(arizona_in_vi_ramp);
+
+const struct soc_enum arizona_out_vd_ramp =
+	SOC_ENUM_SINGLE(ARIZONA_OUTPUT_VOLUME_RAMP,
+			ARIZONA_OUT_VD_RAMP_SHIFT, 7, arizona_vol_ramp_text);
+EXPORT_SYMBOL_GPL(arizona_out_vd_ramp);
+
+const struct soc_enum arizona_out_vi_ramp =
+	SOC_ENUM_SINGLE(ARIZONA_OUTPUT_VOLUME_RAMP,
+			ARIZONA_OUT_VI_RAMP_SHIFT, 7, arizona_vol_ramp_text);
+EXPORT_SYMBOL_GPL(arizona_out_vi_ramp);
+
 static const char *arizona_lhpf_mode_text[] = {
 	"Low-pass", "High-pass"
 };
@@ -380,6 +405,18 @@
 	case 49152000:
 		val |= 3 << ARIZONA_SYSCLK_FREQ_SHIFT;
 		break;
+	case 67737600:
+	case 73728000:
+		val |= 4 << ARIZONA_SYSCLK_FREQ_SHIFT;
+		break;
+	case 90316800:
+	case 98304000:
+		val |= 5 << ARIZONA_SYSCLK_FREQ_SHIFT;
+		break;
+	case 135475200:
+	case 147456000:
+		val |= 6 << ARIZONA_SYSCLK_FREQ_SHIFT;
+		break;
 	default:
 		return -EINVAL;
 	}
@@ -737,6 +774,9 @@
 		return -EBUSY;
 	}
 
+	dev_dbg(codec->dev, "Setting AIF%d to %s\n", dai->id + 1,
+		arizona_dai_clk_str(clk_id));
+
 	memset(&routes, 0, sizeof(routes));
 	routes[0].sink = dai->driver->capture.stream_name;
 	routes[1].sink = dai->driver->playback.stream_name;
@@ -749,6 +789,8 @@
 	routes[1].source = arizona_dai_clk_str(clk_id);
 	snd_soc_dapm_add_routes(&codec->dapm, routes, ARRAY_SIZE(routes));
 
+	dai_priv->clk = clk_id;
+
 	return snd_soc_dapm_sync(&codec->dapm);
 }
 
@@ -925,6 +967,9 @@
 	bool ena;
 	int ret;
 
+	if (fll->fref == Fref && fll->fout == Fout)
+		return 0;
+
 	ret = regmap_read(arizona->regmap, fll->base + 1, &reg);
 	if (ret != 0) {
 		arizona_fll_err(fll, "Failed to read current state: %d\n",
@@ -970,6 +1015,9 @@
 		if (ena)
 			pm_runtime_put_autosuspend(arizona->dev);
 
+		fll->fref = Fref;
+		fll->fout = Fout;
+
 		return 0;
 	}
 
@@ -998,10 +1046,13 @@
 				   ARIZONA_FLL1_SYNC_ENA);
 
 	ret = wait_for_completion_timeout(&fll->ok,
-					  msecs_to_jiffies(25));
+					  msecs_to_jiffies(250));
 	if (ret == 0)
 		arizona_fll_warn(fll, "Timed out waiting for lock\n");
 
+	fll->fref = Fref;
+	fll->fout = Fout;
+
 	return 0;
 }
 EXPORT_SYMBOL_GPL(arizona_set_fll);
diff --git a/sound/soc/codecs/arizona.h b/sound/soc/codecs/arizona.h
index 36ec649..41dae1e 100644
--- a/sound/soc/codecs/arizona.h
+++ b/sound/soc/codecs/arizona.h
@@ -17,6 +17,8 @@
 
 #include <sound/soc.h>
 
+#include "wm_adsp.h"
+
 #define ARIZONA_CLK_SYSCLK         1
 #define ARIZONA_CLK_ASYNCCLK       2
 #define ARIZONA_CLK_OPCLK          3
@@ -46,15 +48,18 @@
 #define ARIZONA_MIXER_VOL_SHIFT                 1
 #define ARIZONA_MIXER_VOL_WIDTH                 7
 
-#define ARIZONA_MAX_DAI 3
+#define ARIZONA_MAX_DAI  4
+#define ARIZONA_MAX_ADSP 4
 
 struct arizona;
+struct wm_adsp;
 
 struct arizona_dai_priv {
 	int clk;
 };
 
 struct arizona_priv {
+	struct wm_adsp adsp[ARIZONA_MAX_ADSP];
 	struct arizona *arizona;
 	int sysclk;
 	int asyncclk;
@@ -89,19 +94,30 @@
 	const struct snd_kcontrol_new name##_mux =	\
 		SOC_DAPM_VALUE_ENUM("Route", name##_enum)
 
+#define ARIZONA_MUX_ENUMS(name, base_reg) \
+	static ARIZONA_MUX_ENUM_DECL(name##_enum, base_reg);      \
+	static ARIZONA_MUX_CTL_DECL(name)
+
 #define ARIZONA_MIXER_ENUMS(name, base_reg) \
-	static ARIZONA_MUX_ENUM_DECL(name##_in1_enum, base_reg);      \
-	static ARIZONA_MUX_ENUM_DECL(name##_in2_enum, base_reg + 2);  \
-	static ARIZONA_MUX_ENUM_DECL(name##_in3_enum, base_reg + 4);  \
-	static ARIZONA_MUX_ENUM_DECL(name##_in4_enum, base_reg + 6);  \
-	static ARIZONA_MUX_CTL_DECL(name##_in1); \
-	static ARIZONA_MUX_CTL_DECL(name##_in2); \
-	static ARIZONA_MUX_CTL_DECL(name##_in3); \
-	static ARIZONA_MUX_CTL_DECL(name##_in4)
+	ARIZONA_MUX_ENUMS(name##_in1, base_reg);     \
+	ARIZONA_MUX_ENUMS(name##_in2, base_reg + 2); \
+	ARIZONA_MUX_ENUMS(name##_in3, base_reg + 4); \
+	ARIZONA_MUX_ENUMS(name##_in4, base_reg + 6)
+
+#define ARIZONA_DSP_AUX_ENUMS(name, base_reg) \
+	ARIZONA_MUX_ENUMS(name##_aux1, base_reg);	\
+	ARIZONA_MUX_ENUMS(name##_aux2, base_reg + 8);	\
+	ARIZONA_MUX_ENUMS(name##_aux3, base_reg + 16);	\
+	ARIZONA_MUX_ENUMS(name##_aux4, base_reg + 24);	\
+	ARIZONA_MUX_ENUMS(name##_aux5, base_reg + 32);	\
+	ARIZONA_MUX_ENUMS(name##_aux6, base_reg + 40)
 
 #define ARIZONA_MUX(name, ctrl) \
 	SND_SOC_DAPM_VALUE_MUX(name, SND_SOC_NOPM, 0, 0, ctrl)
 
+#define ARIZONA_MUX_WIDGETS(name, name_str) \
+	ARIZONA_MUX(name_str " Input", &name##_mux)
+
 #define ARIZONA_MIXER_WIDGETS(name, name_str)	\
 	ARIZONA_MUX(name_str " Input 1", &name##_in1_mux), \
 	ARIZONA_MUX(name_str " Input 2", &name##_in2_mux), \
@@ -109,6 +125,19 @@
 	ARIZONA_MUX(name_str " Input 4", &name##_in4_mux), \
 	SND_SOC_DAPM_MIXER(name_str " Mixer", SND_SOC_NOPM, 0, 0, NULL, 0)
 
+#define ARIZONA_DSP_WIDGETS(name, name_str) \
+	ARIZONA_MIXER_WIDGETS(name##L, name_str "L"), \
+	ARIZONA_MIXER_WIDGETS(name##R, name_str "R"), \
+	ARIZONA_MUX(name_str " Aux 1", &name##_aux1_mux), \
+	ARIZONA_MUX(name_str " Aux 2", &name##_aux2_mux), \
+	ARIZONA_MUX(name_str " Aux 3", &name##_aux3_mux), \
+	ARIZONA_MUX(name_str " Aux 4", &name##_aux4_mux), \
+	ARIZONA_MUX(name_str " Aux 5", &name##_aux5_mux), \
+	ARIZONA_MUX(name_str " Aux 6", &name##_aux6_mux)
+
+#define ARIZONA_MUX_ROUTES(name) \
+	ARIZONA_MIXER_INPUT_ROUTES(name " Input")
+
 #define ARIZONA_MIXER_ROUTES(widget, name) \
 	{ widget, NULL, name " Mixer" },         \
 	{ name " Mixer", NULL, name " Input 1" }, \
@@ -120,6 +149,28 @@
 	ARIZONA_MIXER_INPUT_ROUTES(name " Input 3"), \
 	ARIZONA_MIXER_INPUT_ROUTES(name " Input 4")
 
+#define ARIZONA_DSP_ROUTES(name) \
+	{ name, NULL, name " Aux 1" }, \
+	{ name, NULL, name " Aux 2" }, \
+	{ name, NULL, name " Aux 3" }, \
+	{ name, NULL, name " Aux 4" }, \
+	{ name, NULL, name " Aux 5" }, \
+	{ name, NULL, name " Aux 6" }, \
+	ARIZONA_MIXER_INPUT_ROUTES(name " Aux 1"), \
+	ARIZONA_MIXER_INPUT_ROUTES(name " Aux 2"), \
+	ARIZONA_MIXER_INPUT_ROUTES(name " Aux 3"), \
+	ARIZONA_MIXER_INPUT_ROUTES(name " Aux 4"), \
+	ARIZONA_MIXER_INPUT_ROUTES(name " Aux 5"), \
+	ARIZONA_MIXER_INPUT_ROUTES(name " Aux 6"), \
+	ARIZONA_MIXER_ROUTES(name, name "L"), \
+	ARIZONA_MIXER_ROUTES(name, name "R")
+
+extern const struct soc_enum arizona_in_vi_ramp;
+extern const struct soc_enum arizona_in_vd_ramp;
+
+extern const struct soc_enum arizona_out_vi_ramp;
+extern const struct soc_enum arizona_out_vd_ramp;
+
 extern const struct soc_enum arizona_lhpf1_mode;
 extern const struct soc_enum arizona_lhpf2_mode;
 extern const struct soc_enum arizona_lhpf3_mode;
@@ -146,6 +197,8 @@
 	unsigned int vco_mult;
 	struct completion lock;
 	struct completion ok;
+	unsigned int fref;
+	unsigned int fout;
 
 	char lock_name[ARIZONA_FLL_NAME_LEN];
 	char clock_ok_name[ARIZONA_FLL_NAME_LEN];
diff --git a/sound/soc/codecs/cq93vc.c b/sound/soc/codecs/cq93vc.c
index 064cd6a..23316c8 100644
--- a/sound/soc/codecs/cq93vc.c
+++ b/sound/soc/codecs/cq93vc.c
@@ -201,7 +201,7 @@
 	},
 
 	.probe = cq93vc_platform_probe,
-	.remove = __devexit_p(cq93vc_platform_remove),
+	.remove = cq93vc_platform_remove,
 };
 
 module_platform_driver(cq93vc_codec_driver);
diff --git a/sound/soc/codecs/cs4271.c b/sound/soc/codecs/cs4271.c
index e3f0a7f..4f11279 100644
--- a/sound/soc/codecs/cs4271.c
+++ b/sound/soc/codecs/cs4271.c
@@ -474,15 +474,25 @@
 	struct cs4271_platform_data *cs4271plat = codec->dev->platform_data;
 	int ret;
 	int gpio_nreset = -EINVAL;
+	int amutec_eq_bmutec = 0;
 
 #ifdef CONFIG_OF
-	if (of_match_device(cs4271_dt_ids, codec->dev))
+	if (of_match_device(cs4271_dt_ids, codec->dev)) {
 		gpio_nreset = of_get_named_gpio(codec->dev->of_node,
 						"reset-gpio", 0);
+
+		if (!of_get_property(codec->dev->of_node,
+				     "cirrus,amutec-eq-bmutec", NULL))
+			amutec_eq_bmutec = 1;
+	}
 #endif
 
-	if (cs4271plat && gpio_is_valid(cs4271plat->gpio_nreset))
-		gpio_nreset = cs4271plat->gpio_nreset;
+	if (cs4271plat) {
+		if (gpio_is_valid(cs4271plat->gpio_nreset))
+			gpio_nreset = cs4271plat->gpio_nreset;
+
+		amutec_eq_bmutec = cs4271plat->amutec_eq_bmutec;
+	}
 
 	if (gpio_nreset >= 0)
 		if (devm_gpio_request(codec->dev, gpio_nreset, "CS4271 Reset"))
@@ -528,6 +538,11 @@
 	/* Power-up sequence requires 85 uS */
 	udelay(85);
 
+	if (amutec_eq_bmutec)
+		snd_soc_update_bits(codec, CS4271_MODE2,
+				    CS4271_MODE2_MUTECAEQUB,
+				    CS4271_MODE2_MUTECAEQUB);
+
 	return snd_soc_add_codec_controls(codec, cs4271_snd_controls,
 		ARRAY_SIZE(cs4271_snd_controls));
 }
@@ -555,7 +570,7 @@
 };
 
 #if defined(CONFIG_SPI_MASTER)
-static int __devinit cs4271_spi_probe(struct spi_device *spi)
+static int cs4271_spi_probe(struct spi_device *spi)
 {
 	struct cs4271_private *cs4271;
 
@@ -570,7 +585,7 @@
 		&cs4271_dai, 1);
 }
 
-static int __devexit cs4271_spi_remove(struct spi_device *spi)
+static int cs4271_spi_remove(struct spi_device *spi)
 {
 	snd_soc_unregister_codec(&spi->dev);
 	return 0;
@@ -583,7 +598,7 @@
 		.of_match_table = of_match_ptr(cs4271_dt_ids),
 	},
 	.probe		= cs4271_spi_probe,
-	.remove		= __devexit_p(cs4271_spi_remove),
+	.remove		= cs4271_spi_remove,
 };
 #endif /* defined(CONFIG_SPI_MASTER) */
 
@@ -594,8 +609,8 @@
 };
 MODULE_DEVICE_TABLE(i2c, cs4271_i2c_id);
 
-static int __devinit cs4271_i2c_probe(struct i2c_client *client,
-				      const struct i2c_device_id *id)
+static int cs4271_i2c_probe(struct i2c_client *client,
+			    const struct i2c_device_id *id)
 {
 	struct cs4271_private *cs4271;
 
@@ -610,7 +625,7 @@
 		&cs4271_dai, 1);
 }
 
-static int __devexit cs4271_i2c_remove(struct i2c_client *client)
+static int cs4271_i2c_remove(struct i2c_client *client)
 {
 	snd_soc_unregister_codec(&client->dev);
 	return 0;
@@ -624,7 +639,7 @@
 	},
 	.id_table	= cs4271_i2c_id,
 	.probe		= cs4271_i2c_probe,
-	.remove		= __devexit_p(cs4271_i2c_remove),
+	.remove		= cs4271_i2c_remove,
 };
 #endif /* defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) */
 
diff --git a/sound/soc/codecs/cs42l52.c b/sound/soc/codecs/cs42l52.c
index 97a8105..99bb1c6 100644
--- a/sound/soc/codecs/cs42l52.c
+++ b/sound/soc/codecs/cs42l52.c
@@ -1271,7 +1271,7 @@
 	},
 	.id_table = cs42l52_id,
 	.probe =    cs42l52_i2c_probe,
-	.remove =   __devexit_p(cs42l52_i2c_remove),
+	.remove =   cs42l52_i2c_remove,
 };
 
 module_i2c_driver(cs42l52_i2c_driver);
diff --git a/sound/soc/codecs/cs42l73.c b/sound/soc/codecs/cs42l73.c
index 2c08c4c..a0791ec 100644
--- a/sound/soc/codecs/cs42l73.c
+++ b/sound/soc/codecs/cs42l73.c
@@ -1345,8 +1345,8 @@
 	.cache_type = REGCACHE_RBTREE,
 };
 
-static __devinit int cs42l73_i2c_probe(struct i2c_client *i2c_client,
-				       const struct i2c_device_id *id)
+static int cs42l73_i2c_probe(struct i2c_client *i2c_client,
+			     const struct i2c_device_id *id)
 {
 	struct cs42l73_private *cs42l73;
 	int ret;
@@ -1406,7 +1406,7 @@
 	return 0;
 }
 
-static __devexit int cs42l73_i2c_remove(struct i2c_client *client)
+static int cs42l73_i2c_remove(struct i2c_client *client)
 {
 	snd_soc_unregister_codec(&client->dev);
 	return 0;
@@ -1426,7 +1426,7 @@
 		   },
 	.id_table = cs42l73_id,
 	.probe = cs42l73_i2c_probe,
-	.remove = __devexit_p(cs42l73_i2c_remove),
+	.remove = cs42l73_i2c_remove,
 
 };
 
diff --git a/sound/soc/codecs/da7210.c b/sound/soc/codecs/da7210.c
index af5db70..9c12314 100644
--- a/sound/soc/codecs/da7210.c
+++ b/sound/soc/codecs/da7210.c
@@ -1218,8 +1218,8 @@
 	.cache_type = REGCACHE_RBTREE,
 };
 
-static int __devinit da7210_i2c_probe(struct i2c_client *i2c,
-			   	      const struct i2c_device_id *id)
+static int da7210_i2c_probe(struct i2c_client *i2c,
+			    const struct i2c_device_id *id)
 {
 	struct da7210_priv *da7210;
 	int ret;
@@ -1231,7 +1231,7 @@
 
 	i2c_set_clientdata(i2c, da7210);
 
-	da7210->regmap = regmap_init_i2c(i2c, &da7210_regmap_config_i2c);
+	da7210->regmap = devm_regmap_init_i2c(i2c, &da7210_regmap_config_i2c);
 	if (IS_ERR(da7210->regmap)) {
 		ret = PTR_ERR(da7210->regmap);
 		dev_err(&i2c->dev, "regmap_init() failed: %d\n", ret);
@@ -1245,24 +1245,15 @@
 
 	ret =  snd_soc_register_codec(&i2c->dev,
 			&soc_codec_dev_da7210, &da7210_dai, 1);
-	if (ret < 0) {
+	if (ret < 0)
 		dev_err(&i2c->dev, "Failed to register codec: %d\n", ret);
-		goto err_regmap;
-	}
-	return ret;
-
-err_regmap:
-	regmap_exit(da7210->regmap);
 
 	return ret;
 }
 
-static int __devexit da7210_i2c_remove(struct i2c_client *client)
+static int da7210_i2c_remove(struct i2c_client *client)
 {
-	struct da7210_priv *da7210 = i2c_get_clientdata(client);
-
 	snd_soc_unregister_codec(&client->dev);
-	regmap_exit(da7210->regmap);
 	return 0;
 }
 
@@ -1279,7 +1270,7 @@
 		.owner = THIS_MODULE,
 	},
 	.probe		= da7210_i2c_probe,
-	.remove		= __devexit_p(da7210_i2c_remove),
+	.remove		= da7210_i2c_remove,
 	.id_table	= da7210_i2c_id,
 };
 #endif
@@ -1323,7 +1314,7 @@
 	.cache_type = REGCACHE_RBTREE,
 };
 
-static int __devinit da7210_spi_probe(struct spi_device *spi)
+static int da7210_spi_probe(struct spi_device *spi)
 {
 	struct da7210_priv *da7210;
 	int ret;
@@ -1346,24 +1337,15 @@
 	if (ret != 0)
 		dev_warn(&spi->dev, "Failed to apply regmap patch: %d\n", ret);
 
-	ret =  snd_soc_register_codec(&spi->dev,
+	ret = snd_soc_register_codec(&spi->dev,
 			&soc_codec_dev_da7210, &da7210_dai, 1);
-	if (ret < 0)
-		goto err_regmap;
-
-	return ret;
-
-err_regmap:
-	regmap_exit(da7210->regmap);
 
 	return ret;
 }
 
-static int __devexit da7210_spi_remove(struct spi_device *spi)
+static int da7210_spi_remove(struct spi_device *spi)
 {
-	struct da7210_priv *da7210 = spi_get_drvdata(spi);
 	snd_soc_unregister_codec(&spi->dev);
-	regmap_exit(da7210->regmap);
 	return 0;
 }
 
@@ -1373,7 +1355,7 @@
 		.owner = THIS_MODULE,
 	},
 	.probe = da7210_spi_probe,
-	.remove = __devexit_p(da7210_spi_remove)
+	.remove = da7210_spi_remove
 };
 #endif
 
diff --git a/sound/soc/codecs/da732x.c b/sound/soc/codecs/da732x.c
index 01be2a3..dc0284d 100644
--- a/sound/soc/codecs/da732x.c
+++ b/sound/soc/codecs/da732x.c
@@ -1557,8 +1557,8 @@
 	.reg_cache_size		= ARRAY_SIZE(da732x_reg_cache),
 };
 
-static __devinit int da732x_i2c_probe(struct i2c_client *i2c,
-				      const struct i2c_device_id *id)
+static int da732x_i2c_probe(struct i2c_client *i2c,
+			    const struct i2c_device_id *id)
 {
 	struct da732x_priv *da732x;
 	unsigned int reg;
@@ -1596,7 +1596,7 @@
 	return ret;
 }
 
-static __devexit int da732x_i2c_remove(struct i2c_client *client)
+static int da732x_i2c_remove(struct i2c_client *client)
 {
 	snd_soc_unregister_codec(&client->dev);
 
@@ -1615,7 +1615,7 @@
 		.owner	= THIS_MODULE,
 	},
 	.probe		= da732x_i2c_probe,
-	.remove		= __devexit_p(da732x_i2c_remove),
+	.remove		= da732x_i2c_remove,
 	.id_table	= da732x_i2c_id,
 };
 
diff --git a/sound/soc/codecs/da9055.c b/sound/soc/codecs/da9055.c
index f379b08..fc9802d 100644
--- a/sound/soc/codecs/da9055.c
+++ b/sound/soc/codecs/da9055.c
@@ -173,6 +173,7 @@
 #define DA9055_AIF_FORMAT_I2S_MODE	(0 << 0)
 #define DA9055_AIF_FORMAT_LEFT_J	(1 << 0)
 #define DA9055_AIF_FORMAT_RIGHT_J	(2 << 0)
+#define DA9055_AIF_FORMAT_DSP		(3 << 0)
 #define DA9055_AIF_WORD_S16_LE		(0 << 2)
 #define DA9055_AIF_WORD_S20_3LE		(1 << 2)
 #define DA9055_AIF_WORD_S24_LE		(2 << 2)
@@ -752,6 +753,17 @@
 			6, 1, 0),
 };
 
+/* Headphone Output Enable */
+static const struct snd_kcontrol_new da9055_dapm_hp_l_control =
+SOC_DAPM_SINGLE("Switch", DA9055_HP_L_CTRL, 3, 1, 0);
+
+static const struct snd_kcontrol_new da9055_dapm_hp_r_control =
+SOC_DAPM_SINGLE("Switch", DA9055_HP_R_CTRL, 3, 1, 0);
+
+/* Lineout Output Enable */
+static const struct snd_kcontrol_new da9055_dapm_lineout_control =
+SOC_DAPM_SINGLE("Switch", DA9055_LINE_CTRL, 3, 1, 0);
+
 /* DAPM widgets */
 static const struct snd_soc_dapm_widget da9055_dapm_widgets[] = {
 	/* Input Side */
@@ -816,6 +828,14 @@
 			   &da9055_dapm_mixoutr_controls[0],
 			   ARRAY_SIZE(da9055_dapm_mixoutr_controls)),
 
+	/* Output Enable Switches */
+	SND_SOC_DAPM_SWITCH("Headphone Left Enable", SND_SOC_NOPM, 0, 0,
+			    &da9055_dapm_hp_l_control),
+	SND_SOC_DAPM_SWITCH("Headphone Right Enable", SND_SOC_NOPM, 0, 0,
+			    &da9055_dapm_hp_r_control),
+	SND_SOC_DAPM_SWITCH("Lineout Enable", SND_SOC_NOPM, 0, 0,
+			    &da9055_dapm_lineout_control),
+
 	/* Output PGAs */
 	SND_SOC_DAPM_PGA("MIXOUT Left", DA9055_MIXOUT_L_CTRL, 7, 0, NULL, 0),
 	SND_SOC_DAPM_PGA("MIXOUT Right", DA9055_MIXOUT_R_CTRL, 7, 0, NULL, 0),
@@ -901,17 +921,20 @@
 	{"Out Mixer Right", "DAC Right Switch", "DAC Right"},
 
 	{"MIXOUT Left", NULL, "Out Mixer Left"},
-	{"Headphone Left", NULL, "MIXOUT Left"},
+	{"Headphone Left Enable", "Switch", "MIXOUT Left"},
+	{"Headphone Left", NULL, "Headphone Left Enable"},
 	{"Headphone Left", NULL, "Charge Pump"},
 	{"HPL", NULL, "Headphone Left"},
 
 	{"MIXOUT Right", NULL, "Out Mixer Right"},
-	{"Headphone Right", NULL, "MIXOUT Right"},
+	{"Headphone Right Enable", "Switch", "MIXOUT Right"},
+	{"Headphone Right", NULL, "Headphone Right Enable"},
 	{"Headphone Right", NULL, "Charge Pump"},
 	{"HPR", NULL, "Headphone Right"},
 
 	{"MIXOUT Right", NULL, "Out Mixer Right"},
-	{"Lineout", NULL, "MIXOUT Right"},
+	{"Lineout Enable", "Switch", "MIXOUT Right"},
+	{"Lineout", NULL, "Lineout Enable"},
 	{"LINE", NULL, "Lineout"},
 };
 
@@ -1175,6 +1198,9 @@
 	case SND_SOC_DAIFMT_RIGHT_J:
 		aif_ctrl = DA9055_AIF_FORMAT_RIGHT_J;
 		break;
+	case SND_SOC_DAIFMT_DSP_A:
+		aif_ctrl = DA9055_AIF_FORMAT_DSP;
+		break;
 	default:
 		return -EINVAL;
 	}
@@ -1390,8 +1416,7 @@
 			    DA9055_GAIN_RAMPING_EN, DA9055_GAIN_RAMPING_EN);
 
 	/*
-	 * There are two separate control bits for input and output mixers as
-	 * well as headphone and line outs.
+	 * There are two separate control bits for input and output mixers.
 	 * One to enable corresponding amplifier and other to enable its
 	 * output. As amplifier bits are related to power control, they are
 	 * being managed by DAPM while other (non power related) bits are
@@ -1407,14 +1432,6 @@
 	snd_soc_update_bits(codec, DA9055_MIXOUT_R_CTRL,
 			    DA9055_MIXOUT_R_MIX_EN, DA9055_MIXOUT_R_MIX_EN);
 
-	snd_soc_update_bits(codec, DA9055_HP_L_CTRL,
-			    DA9055_HP_L_AMP_OE, DA9055_HP_L_AMP_OE);
-	snd_soc_update_bits(codec, DA9055_HP_R_CTRL,
-			    DA9055_HP_R_AMP_OE, DA9055_HP_R_AMP_OE);
-
-	snd_soc_update_bits(codec, DA9055_LINE_CTRL,
-			    DA9055_LINE_AMP_OE, DA9055_LINE_AMP_OE);
-
 	/* Set this as per your system configuration */
 	snd_soc_write(codec, DA9055_PLL_CTRL, DA9055_PLL_INDIV_10_20_MHZ);
 
@@ -1467,8 +1484,8 @@
 	.cache_type = REGCACHE_RBTREE,
 };
 
-static int __devinit da9055_i2c_probe(struct i2c_client *i2c,
-				      const struct i2c_device_id *id)
+static int da9055_i2c_probe(struct i2c_client *i2c,
+			    const struct i2c_device_id *id)
 {
 	struct da9055_priv *da9055;
 	struct da9055_platform_data *pdata = dev_get_platdata(&i2c->dev);
@@ -1500,7 +1517,7 @@
 	return ret;
 }
 
-static int __devexit da9055_remove(struct i2c_client *client)
+static int da9055_remove(struct i2c_client *client)
 {
 	snd_soc_unregister_codec(&client->dev);
 	return 0;
@@ -1519,7 +1536,7 @@
 		.owner = THIS_MODULE,
 	},
 	.probe		= da9055_i2c_probe,
-	.remove		= __devexit_p(da9055_remove),
+	.remove		= da9055_remove,
 	.id_table	= da9055_i2c_id,
 };
 
diff --git a/sound/soc/codecs/dfbmcs320.c b/sound/soc/codecs/dfbmcs320.c
index bfe46aa..4f4f7f4 100644
--- a/sound/soc/codecs/dfbmcs320.c
+++ b/sound/soc/codecs/dfbmcs320.c
@@ -33,13 +33,13 @@
 
 static struct snd_soc_codec_driver soc_codec_dev_dfbmcs320;
 
-static int __devinit dfbmcs320_probe(struct platform_device *pdev)
+static int dfbmcs320_probe(struct platform_device *pdev)
 {
 	return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_dfbmcs320,
 			&dfbmcs320_dai, 1);
 }
 
-static int __devexit dfbmcs320_remove(struct platform_device *pdev)
+static int dfbmcs320_remove(struct platform_device *pdev)
 {
 	snd_soc_unregister_codec(&pdev->dev);
 
@@ -52,7 +52,7 @@
 		.owner = THIS_MODULE,
 	},
 	.probe = dfbmcs320_probe,
-	.remove = __devexit_p(dfbmcs320_remove),
+	.remove = dfbmcs320_remove,
 };
 
 module_platform_driver(dfmcs320_driver);
diff --git a/sound/soc/codecs/dmic.c b/sound/soc/codecs/dmic.c
index 3e929f0..66967ba 100644
--- a/sound/soc/codecs/dmic.c
+++ b/sound/soc/codecs/dmic.c
@@ -66,13 +66,13 @@
 	.probe	= dmic_probe,
 };
 
-static int __devinit dmic_dev_probe(struct platform_device *pdev)
+static int dmic_dev_probe(struct platform_device *pdev)
 {
 	return snd_soc_register_codec(&pdev->dev,
 			&soc_dmic, &dmic_dai, 1);
 }
 
-static int __devexit dmic_dev_remove(struct platform_device *pdev)
+static int dmic_dev_remove(struct platform_device *pdev)
 {
 	snd_soc_unregister_codec(&pdev->dev);
 	return 0;
@@ -86,7 +86,7 @@
 		.owner = THIS_MODULE,
 	},
 	.probe = dmic_dev_probe,
-	.remove = __devexit_p(dmic_dev_remove),
+	.remove = dmic_dev_remove,
 };
 
 module_platform_driver(dmic_driver);
diff --git a/sound/soc/codecs/isabelle.c b/sound/soc/codecs/isabelle.c
index 1bf5560..53b455b 100644
--- a/sound/soc/codecs/isabelle.c
+++ b/sound/soc/codecs/isabelle.c
@@ -1119,8 +1119,8 @@
 	.cache_type = REGCACHE_RBTREE,
 };
 
-static int __devinit isabelle_i2c_probe(struct i2c_client *i2c,
-					const struct i2c_device_id *id)
+static int isabelle_i2c_probe(struct i2c_client *i2c,
+			      const struct i2c_device_id *id)
 {
 	struct regmap *isabelle_regmap;
 	int ret = 0;
@@ -1145,7 +1145,7 @@
 	return ret;
 }
 
-static int __devexit isabelle_i2c_remove(struct i2c_client *client)
+static int isabelle_i2c_remove(struct i2c_client *client)
 {
 	snd_soc_unregister_codec(&client->dev);
 	return 0;
@@ -1163,7 +1163,7 @@
 		.owner = THIS_MODULE,
 	},
 	.probe = isabelle_i2c_probe,
-	.remove = __devexit_p(isabelle_i2c_remove),
+	.remove = isabelle_i2c_remove,
 	.id_table = isabelle_i2c_id,
 };
 
diff --git a/sound/soc/codecs/jz4740.c b/sound/soc/codecs/jz4740.c
index 85d9cab..d991529 100644
--- a/sound/soc/codecs/jz4740.c
+++ b/sound/soc/codecs/jz4740.c
@@ -16,6 +16,7 @@
 #include <linux/platform_device.h>
 #include <linux/slab.h>
 #include <linux/io.h>
+#include <linux/regmap.h>
 
 #include <linux/delay.h>
 
@@ -24,9 +25,10 @@
 #include <sound/pcm_params.h>
 #include <sound/initval.h>
 #include <sound/soc.h>
+#include <sound/tlv.h>
 
 #define JZ4740_REG_CODEC_1 0x0
-#define JZ4740_REG_CODEC_2 0x1
+#define JZ4740_REG_CODEC_2 0x4
 
 #define JZ4740_CODEC_1_LINE_ENABLE BIT(29)
 #define JZ4740_CODEC_1_MIC_ENABLE BIT(28)
@@ -67,43 +69,36 @@
 #define JZ4740_CODEC_2_MIC_BOOST_GAIN_OFFSET	 4
 #define JZ4740_CODEC_2_HEADPHONE_VOLUME_OFFSET	 0
 
-static const uint32_t jz4740_codec_regs[] = {
-	0x021b2302, 0x00170803,
+static const struct reg_default jz4740_codec_reg_defaults[] = {
+	{ JZ4740_REG_CODEC_1, 0x021b2302 },
+	{ JZ4740_REG_CODEC_2, 0x00170803 },
 };
 
 struct jz4740_codec {
-	void __iomem *base;
-	struct resource *mem;
+	struct regmap *regmap;
 };
 
-static unsigned int jz4740_codec_read(struct snd_soc_codec *codec,
-	unsigned int reg)
-{
-	struct jz4740_codec *jz4740_codec = snd_soc_codec_get_drvdata(codec);
-	return readl(jz4740_codec->base + (reg << 2));
-}
+static const unsigned int jz4740_mic_tlv[] = {
+	TLV_DB_RANGE_HEAD(2),
+	0, 2, TLV_DB_SCALE_ITEM(0, 600, 0),
+	3, 3, TLV_DB_SCALE_ITEM(2000, 0, 0),
+};
 
-static int jz4740_codec_write(struct snd_soc_codec *codec, unsigned int reg,
-	unsigned int val)
-{
-	struct jz4740_codec *jz4740_codec = snd_soc_codec_get_drvdata(codec);
-	u32 *cache = codec->reg_cache;
-
-	cache[reg] = val;
-	writel(val, jz4740_codec->base + (reg << 2));
-
-	return 0;
-}
+static const DECLARE_TLV_DB_SCALE(jz4740_out_tlv, 0, 200, 0);
+static const DECLARE_TLV_DB_SCALE(jz4740_in_tlv, -3450, 150, 0);
 
 static const struct snd_kcontrol_new jz4740_codec_controls[] = {
-	SOC_SINGLE("Master Playback Volume", JZ4740_REG_CODEC_2,
-			JZ4740_CODEC_2_HEADPHONE_VOLUME_OFFSET, 3, 0),
-	SOC_SINGLE("Master Capture Volume", JZ4740_REG_CODEC_2,
-			JZ4740_CODEC_2_INPUT_VOLUME_OFFSET, 31, 0),
+	SOC_SINGLE_TLV("Master Playback Volume", JZ4740_REG_CODEC_2,
+			JZ4740_CODEC_2_HEADPHONE_VOLUME_OFFSET, 3, 0,
+			jz4740_out_tlv),
+	SOC_SINGLE_TLV("Master Capture Volume", JZ4740_REG_CODEC_2,
+			JZ4740_CODEC_2_INPUT_VOLUME_OFFSET, 31, 0,
+			jz4740_in_tlv),
 	SOC_SINGLE("Master Playback Switch", JZ4740_REG_CODEC_1,
 			JZ4740_CODEC_1_HEADPHONE_DISABLE_OFFSET, 1, 1),
-	SOC_SINGLE("Mic Capture Volume", JZ4740_REG_CODEC_2,
-			JZ4740_CODEC_2_MIC_BOOST_GAIN_OFFSET, 3, 0),
+	SOC_SINGLE_TLV("Mic Capture Volume", JZ4740_REG_CODEC_2,
+			JZ4740_CODEC_2_MIC_BOOST_GAIN_OFFSET, 3, 0,
+			jz4740_mic_tlv),
 };
 
 static const struct snd_kcontrol_new jz4740_codec_output_controls[] = {
@@ -163,8 +158,8 @@
 static int jz4740_codec_hw_params(struct snd_pcm_substream *substream,
 	struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
 {
+	struct jz4740_codec *jz4740_codec = snd_soc_codec_get_drvdata(dai->codec);
 	uint32_t val;
-	struct snd_soc_codec *codec = dai->codec;
 
 	switch (params_rate(params)) {
 	case 8000:
@@ -200,7 +195,7 @@
 
 	val <<= JZ4740_CODEC_2_SAMPLE_RATE_OFFSET;
 
-	snd_soc_update_bits(codec, JZ4740_REG_CODEC_2,
+	regmap_update_bits(jz4740_codec->regmap, JZ4740_REG_CODEC_2,
 				JZ4740_CODEC_2_SAMPLE_RATE_MASK, val);
 
 	return 0;
@@ -230,25 +225,23 @@
 	.symmetric_rates = 1,
 };
 
-static void jz4740_codec_wakeup(struct snd_soc_codec *codec)
+static void jz4740_codec_wakeup(struct regmap *regmap)
 {
-	int i;
-	uint32_t *cache = codec->reg_cache;
-
-	snd_soc_update_bits(codec, JZ4740_REG_CODEC_1,
+	regmap_update_bits(regmap, JZ4740_REG_CODEC_1,
 		JZ4740_CODEC_1_RESET, JZ4740_CODEC_1_RESET);
 	udelay(2);
 
-	snd_soc_update_bits(codec, JZ4740_REG_CODEC_1,
+	regmap_update_bits(regmap, JZ4740_REG_CODEC_1,
 		JZ4740_CODEC_1_SUSPEND | JZ4740_CODEC_1_RESET, 0);
 
-	for (i = 0; i < ARRAY_SIZE(jz4740_codec_regs); ++i)
-		jz4740_codec_write(codec, i, cache[i]);
+	regcache_sync(regmap);
 }
 
 static int jz4740_codec_set_bias_level(struct snd_soc_codec *codec,
 	enum snd_soc_bias_level level)
 {
+	struct jz4740_codec *jz4740_codec = snd_soc_codec_get_drvdata(codec);
+	struct regmap *regmap = jz4740_codec->regmap;
 	unsigned int mask;
 	unsigned int value;
 
@@ -261,12 +254,12 @@
 				JZ4740_CODEC_1_HEADPHONE_POWERDOWN_M;
 		value = 0;
 
-		snd_soc_update_bits(codec, JZ4740_REG_CODEC_1, mask, value);
+		regmap_update_bits(regmap, JZ4740_REG_CODEC_1, mask, value);
 		break;
 	case SND_SOC_BIAS_STANDBY:
 		/* The only way to clear the suspend flag is to reset the codec */
 		if (codec->dapm.bias_level == SND_SOC_BIAS_OFF)
-			jz4740_codec_wakeup(codec);
+			jz4740_codec_wakeup(regmap);
 
 		mask = JZ4740_CODEC_1_VREF_DISABLE |
 			JZ4740_CODEC_1_VREF_AMP_DISABLE |
@@ -275,13 +268,14 @@
 			JZ4740_CODEC_1_VREF_AMP_DISABLE |
 			JZ4740_CODEC_1_HEADPHONE_POWERDOWN_M;
 
-		snd_soc_update_bits(codec, JZ4740_REG_CODEC_1, mask, value);
+		regmap_update_bits(regmap, JZ4740_REG_CODEC_1, mask, value);
 		break;
 	case SND_SOC_BIAS_OFF:
 		mask = JZ4740_CODEC_1_SUSPEND;
 		value = JZ4740_CODEC_1_SUSPEND;
 
-		snd_soc_update_bits(codec, JZ4740_REG_CODEC_1, mask, value);
+		regmap_update_bits(regmap, JZ4740_REG_CODEC_1, mask, value);
+		regcache_mark_dirty(regmap);
 		break;
 	default:
 		break;
@@ -294,7 +288,9 @@
 
 static int jz4740_codec_dev_probe(struct snd_soc_codec *codec)
 {
-	snd_soc_update_bits(codec, JZ4740_REG_CODEC_1,
+	struct jz4740_codec *jz4740_codec = snd_soc_codec_get_drvdata(codec);
+
+	regmap_update_bits(jz4740_codec->regmap, JZ4740_REG_CODEC_1,
 			JZ4740_CODEC_1_SW2_ENABLE, JZ4740_CODEC_1_SW2_ENABLE);
 
 	jz4740_codec_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
@@ -331,12 +327,7 @@
 	.remove = jz4740_codec_dev_remove,
 	.suspend = jz4740_codec_suspend,
 	.resume = jz4740_codec_resume,
-	.read = jz4740_codec_read,
-	.write = jz4740_codec_write,
 	.set_bias_level = jz4740_codec_set_bias_level,
-	.reg_cache_default	= jz4740_codec_regs,
-	.reg_word_size = sizeof(u32),
-	.reg_cache_size	= 2,
 
 	.controls = jz4740_codec_controls,
 	.num_controls = ARRAY_SIZE(jz4740_codec_controls),
@@ -346,11 +337,23 @@
 	.num_dapm_routes = ARRAY_SIZE(jz4740_codec_dapm_routes),
 };
 
-static int __devinit jz4740_codec_probe(struct platform_device *pdev)
+static const struct regmap_config jz4740_codec_regmap_config = {
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+	.max_register = JZ4740_REG_CODEC_2,
+
+	.reg_defaults = jz4740_codec_reg_defaults,
+	.num_reg_defaults = ARRAY_SIZE(jz4740_codec_reg_defaults),
+	.cache_type = REGCACHE_RBTREE,
+};
+
+static int jz4740_codec_probe(struct platform_device *pdev)
 {
 	int ret;
 	struct jz4740_codec *jz4740_codec;
 	struct resource *mem;
+	void __iomem *base;
 
 	jz4740_codec = devm_kzalloc(&pdev->dev, sizeof(*jz4740_codec),
 				    GFP_KERNEL);
@@ -358,56 +361,29 @@
 		return -ENOMEM;
 
 	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (!mem) {
-		dev_err(&pdev->dev, "Failed to get mmio memory resource\n");
-		ret = -ENOENT;
-		goto err_out;
-	}
+	base = devm_request_and_ioremap(&pdev->dev, mem);
+	if (!base)
+		return -EBUSY;
 
-	mem = request_mem_region(mem->start, resource_size(mem), pdev->name);
-	if (!mem) {
-		dev_err(&pdev->dev, "Failed to request mmio memory region\n");
-		ret = -EBUSY;
-		goto err_out;
-	}
-
-	jz4740_codec->base = ioremap(mem->start, resource_size(mem));
-	if (!jz4740_codec->base) {
-		dev_err(&pdev->dev, "Failed to ioremap mmio memory\n");
-		ret = -EBUSY;
-		goto err_release_mem_region;
-	}
-	jz4740_codec->mem = mem;
+	jz4740_codec->regmap = devm_regmap_init_mmio(&pdev->dev, base,
+					    &jz4740_codec_regmap_config);
+	if (IS_ERR(jz4740_codec->regmap))
+		return PTR_ERR(jz4740_codec->regmap);
 
 	platform_set_drvdata(pdev, jz4740_codec);
 
 	ret = snd_soc_register_codec(&pdev->dev,
 			&soc_codec_dev_jz4740_codec, &jz4740_codec_dai, 1);
-	if (ret) {
+	if (ret)
 		dev_err(&pdev->dev, "Failed to register codec\n");
-		goto err_iounmap;
-	}
 
-	return 0;
-
-err_iounmap:
-	iounmap(jz4740_codec->base);
-err_release_mem_region:
-	release_mem_region(mem->start, resource_size(mem));
-err_out:
 	return ret;
 }
 
-static int __devexit jz4740_codec_remove(struct platform_device *pdev)
+static int jz4740_codec_remove(struct platform_device *pdev)
 {
-	struct jz4740_codec *jz4740_codec = platform_get_drvdata(pdev);
-	struct resource *mem = jz4740_codec->mem;
-
 	snd_soc_unregister_codec(&pdev->dev);
 
-	iounmap(jz4740_codec->base);
-	release_mem_region(mem->start, resource_size(mem));
-
 	platform_set_drvdata(pdev, NULL);
 
 	return 0;
@@ -415,7 +391,7 @@
 
 static struct platform_driver jz4740_codec_driver = {
 	.probe = jz4740_codec_probe,
-	.remove = __devexit_p(jz4740_codec_remove),
+	.remove = jz4740_codec_remove,
 	.driver = {
 		.name = "jz4740-codec",
 		.owner = THIS_MODULE,
diff --git a/sound/soc/codecs/lm4857.c b/sound/soc/codecs/lm4857.c
index 81a328c..9f9f595 100644
--- a/sound/soc/codecs/lm4857.c
+++ b/sound/soc/codecs/lm4857.c
@@ -209,8 +209,8 @@
 	.set_bias_level = lm4857_set_bias_level,
 };
 
-static int __devinit lm4857_i2c_probe(struct i2c_client *i2c,
-	const struct i2c_device_id *id)
+static int lm4857_i2c_probe(struct i2c_client *i2c,
+			    const struct i2c_device_id *id)
 {
 	struct lm4857 *lm4857;
 	int ret;
@@ -228,7 +228,7 @@
 	return ret;
 }
 
-static int __devexit lm4857_i2c_remove(struct i2c_client *i2c)
+static int lm4857_i2c_remove(struct i2c_client *i2c)
 {
 	snd_soc_unregister_codec(&i2c->dev);
 	return 0;
@@ -246,7 +246,7 @@
 		.owner = THIS_MODULE,
 	},
 	.probe = lm4857_i2c_probe,
-	.remove = __devexit_p(lm4857_i2c_remove),
+	.remove = lm4857_i2c_remove,
 	.id_table = lm4857_i2c_id,
 };
 
diff --git a/sound/soc/codecs/lm49453.c b/sound/soc/codecs/lm49453.c
index 99b0a9d..d75257d 100644
--- a/sound/soc/codecs/lm49453.c
+++ b/sound/soc/codecs/lm49453.c
@@ -1483,8 +1483,8 @@
 	.cache_type = REGCACHE_RBTREE,
 };
 
-static __devinit int lm49453_i2c_probe(struct i2c_client *i2c,
-				       const struct i2c_device_id *id)
+static int lm49453_i2c_probe(struct i2c_client *i2c,
+			     const struct i2c_device_id *id)
 {
 	struct lm49453_priv *lm49453;
 	int ret = 0;
@@ -1497,7 +1497,7 @@
 
 	i2c_set_clientdata(i2c, lm49453);
 
-	lm49453->regmap = regmap_init_i2c(i2c, &lm49453_regmap_config);
+	lm49453->regmap = devm_regmap_init_i2c(i2c, &lm49453_regmap_config);
 	if (IS_ERR(lm49453->regmap)) {
 		ret = PTR_ERR(lm49453->regmap);
 		dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
@@ -1508,21 +1508,15 @@
 	ret =  snd_soc_register_codec(&i2c->dev,
 				      &soc_codec_dev_lm49453,
 				      lm49453_dai, ARRAY_SIZE(lm49453_dai));
-	if (ret < 0) {
+	if (ret < 0)
 		dev_err(&i2c->dev, "Failed to register codec: %d\n", ret);
-		regmap_exit(lm49453->regmap);
-		return ret;
-	}
 
 	return ret;
 }
 
-static int __devexit lm49453_i2c_remove(struct i2c_client *client)
+static int lm49453_i2c_remove(struct i2c_client *client)
 {
-	struct lm49453_priv *lm49453 = i2c_get_clientdata(client);
-
 	snd_soc_unregister_codec(&client->dev);
-	regmap_exit(lm49453->regmap);
 	return 0;
 }
 
@@ -1538,7 +1532,7 @@
 		.owner = THIS_MODULE,
 	},
 	.probe = lm49453_i2c_probe,
-	.remove = __devexit_p(lm49453_i2c_remove),
+	.remove = lm49453_i2c_remove,
 	.id_table = lm49453_i2c_id,
 };
 
diff --git a/sound/soc/codecs/max9768.c b/sound/soc/codecs/max9768.c
index 17b3ec2..a6ac231 100644
--- a/sound/soc/codecs/max9768.c
+++ b/sound/soc/codecs/max9768.c
@@ -159,8 +159,8 @@
 	.cache_type = REGCACHE_RBTREE,
 };
 
-static int __devinit max9768_i2c_probe(struct i2c_client *client,
-	const struct i2c_device_id *id)
+static int max9768_i2c_probe(struct i2c_client *client,
+			     const struct i2c_device_id *id)
 {
 	struct max9768 *max9768;
 	struct max9768_pdata *pdata = client->dev.platform_data;
@@ -187,7 +187,7 @@
 
 	i2c_set_clientdata(client, max9768);
 
-	max9768->regmap = regmap_init_i2c(client, &max9768_i2c_regmap_config);
+	max9768->regmap = devm_regmap_init_i2c(client, &max9768_i2c_regmap_config);
 	if (IS_ERR(max9768->regmap)) {
 		err = PTR_ERR(max9768->regmap);
 		goto err_gpio_free;
@@ -195,12 +195,10 @@
 
 	err = snd_soc_register_codec(&client->dev, &max9768_codec_driver, NULL, 0);
 	if (err)
-		goto err_regmap_free;
+		goto err_gpio_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);
@@ -210,12 +208,11 @@
 	return err;
 }
 
-static int __devexit max9768_i2c_remove(struct i2c_client *client)
+static int 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);
@@ -237,7 +234,7 @@
 		.owner = THIS_MODULE,
 	},
 	.probe = max9768_i2c_probe,
-	.remove = __devexit_p(max9768_i2c_remove),
+	.remove = max9768_i2c_remove,
 	.id_table = max9768_i2c_id,
 };
 module_i2c_driver(max9768_i2c_driver);
diff --git a/sound/soc/codecs/max98088.c b/sound/soc/codecs/max98088.c
index 3264a51..a4c16fd 100644
--- a/sound/soc/codecs/max98088.c
+++ b/sound/soc/codecs/max98088.c
@@ -2084,7 +2084,7 @@
        return ret;
 }
 
-static int __devexit max98088_i2c_remove(struct i2c_client *client)
+static int max98088_i2c_remove(struct i2c_client *client)
 {
        snd_soc_unregister_codec(&client->dev);
        return 0;
@@ -2098,13 +2098,13 @@
 MODULE_DEVICE_TABLE(i2c, max98088_i2c_id);
 
 static struct i2c_driver max98088_i2c_driver = {
-       .driver = {
-               .name = "max98088",
-               .owner = THIS_MODULE,
-       },
-       .probe  = max98088_i2c_probe,
-       .remove = __devexit_p(max98088_i2c_remove),
-       .id_table = max98088_i2c_id,
+	.driver = {
+		.name = "max98088",
+		.owner = THIS_MODULE,
+	},
+	.probe  = max98088_i2c_probe,
+	.remove = max98088_i2c_remove,
+	.id_table = max98088_i2c_id,
 };
 
 module_i2c_driver(max98088_i2c_driver);
diff --git a/sound/soc/codecs/max98090.c b/sound/soc/codecs/max98090.c
new file mode 100644
index 0000000..c9772ca
--- /dev/null
+++ b/sound/soc/codecs/max98090.c
@@ -0,0 +1,577 @@
+/*
+ * max98090.c -- MAX98090 ALSA SoC Audio driver
+ * based on Rev0p8 datasheet
+ *
+ * Copyright (C) 2012 Renesas Solutions Corp.
+ * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+ *
+ * Based on
+ *
+ * max98095.c
+ * Copyright 2011 Maxim Integrated Products
+ *
+ * https://github.com/hardkernel/linux/commit/\
+ *	3417d7166b17113b3b33b0a337c74d1c7cc313df#sound/soc/codecs/max98090.c
+ * Copyright 2011 Maxim Integrated Products
+ *
+ * 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/i2c.h>
+#include <linux/module.h>
+#include <linux/regmap.h>
+#include <sound/soc.h>
+#include <sound/tlv.h>
+
+/*
+ *
+ * MAX98090 Registers Definition
+ *
+ */
+
+/* RESET / STATUS / INTERRUPT REGISTERS */
+#define MAX98090_0x00_SW_RESET		0x00
+#define MAX98090_0x01_INT_STS		0x01
+#define MAX98090_0x02_JACK_STS		0x02
+#define MAX98090_0x03_INT_MASK		0x03
+
+/* QUICK SETUP REGISTERS */
+#define MAX98090_0x04_SYS_CLK		0x04
+#define MAX98090_0x05_SAMPLE_RATE	0x05
+#define MAX98090_0x06_DAI_IF		0x06
+#define MAX98090_0x07_DAC_PATH		0x07
+#define MAX98090_0x08_MIC_TO_ADC	0x08
+#define MAX98090_0x09_LINE_TO_ADC	0x09
+#define MAX98090_0x0A_ANALOG_MIC_LOOP	0x0A
+#define MAX98090_0x0B_ANALOG_LINE_LOOP	0x0B
+
+/* ANALOG INPUT CONFIGURATION REGISTERS */
+#define MAX98090_0x0D_INPUT_CONFIG	0x0D
+#define MAX98090_0x0E_LINE_IN_LVL	0x0E
+#define MAX98090_0x0F_LINI_IN_CFG	0x0F
+#define MAX98090_0x10_MIC1_IN_LVL	0x10
+#define MAX98090_0x11_MIC2_IN_LVL	0x11
+
+/* MICROPHONE CONFIGURATION REGISTERS  */
+#define MAX98090_0x12_MIC_BIAS_VOL	0x12
+#define MAX98090_0x13_DIGITAL_MIC_CFG	0x13
+#define MAX98090_0x14_DIGITAL_MIC_MODE	0x14
+
+/* ADC PATH AND CONFIGURATION REGISTERS */
+#define MAX98090_0x15_L_ADC_MIX		0x15
+#define MAX98090_0x16_R_ADC_MIX		0x16
+#define MAX98090_0x17_L_ADC_LVL		0x17
+#define MAX98090_0x18_R_ADC_LVL		0x18
+#define MAX98090_0x19_ADC_BIQUAD_LVL	0x19
+#define MAX98090_0x1A_ADC_SIDETONE	0x1A
+
+/* CLOCK CONFIGURATION REGISTERS */
+#define MAX98090_0x1B_SYS_CLK		0x1B
+#define MAX98090_0x1C_CLK_MODE		0x1C
+#define MAX98090_0x1D_ANY_CLK1		0x1D
+#define MAX98090_0x1E_ANY_CLK2		0x1E
+#define MAX98090_0x1F_ANY_CLK3		0x1F
+#define MAX98090_0x20_ANY_CLK4		0x20
+#define MAX98090_0x21_MASTER_MODE	0x21
+
+/* INTERFACE CONTROL REGISTERS */
+#define MAX98090_0x22_DAI_IF_FMT	0x22
+#define MAX98090_0x23_DAI_TDM_FMT1	0x23
+#define MAX98090_0x24_DAI_TDM_FMT2	0x24
+#define MAX98090_0x25_DAI_IO_CFG	0x25
+#define MAX98090_0x26_FILTER_CFG	0x26
+#define MAX98090_0x27_DAI_PLAYBACK_LVL	0x27
+#define MAX98090_0x28_EQ_PLAYBACK_LVL	0x28
+
+/* HEADPHONE CONTROL REGISTERS */
+#define MAX98090_0x29_L_HP_MIX		0x29
+#define MAX98090_0x2A_R_HP_MIX		0x2A
+#define MAX98090_0x2B_HP_CTR		0x2B
+#define MAX98090_0x2C_L_HP_VOL		0x2C
+#define MAX98090_0x2D_R_HP_VOL		0x2D
+
+/* SPEAKER CONFIGURATION REGISTERS */
+#define MAX98090_0x2E_L_SPK_MIX		0x2E
+#define MAX98090_0x2F_R_SPK_MIX		0x2F
+#define MAX98090_0x30_SPK_CTR		0x30
+#define MAX98090_0x31_L_SPK_VOL		0x31
+#define MAX98090_0x32_R_SPK_VOL		0x32
+
+/* ALC CONFIGURATION REGISTERS */
+#define MAX98090_0x33_ALC_TIMING	0x33
+#define MAX98090_0x34_ALC_COMPRESSOR	0x34
+#define MAX98090_0x35_ALC_EXPANDER	0x35
+#define MAX98090_0x36_ALC_GAIN		0x36
+
+/* RECEIVER AND LINE_OUTPUT REGISTERS */
+#define MAX98090_0x37_RCV_LOUT_L_MIX	0x37
+#define MAX98090_0x38_RCV_LOUT_L_CNTL	0x38
+#define MAX98090_0x39_RCV_LOUT_L_VOL	0x39
+#define MAX98090_0x3A_LOUT_R_MIX	0x3A
+#define MAX98090_0x3B_LOUT_R_CNTL	0x3B
+#define MAX98090_0x3C_LOUT_R_VOL	0x3C
+
+/* JACK DETECT AND ENABLE REGISTERS */
+#define MAX98090_0x3D_JACK_DETECT	0x3D
+#define MAX98090_0x3E_IN_ENABLE		0x3E
+#define MAX98090_0x3F_OUT_ENABLE	0x3F
+#define MAX98090_0x40_LVL_CTR		0x40
+#define MAX98090_0x41_DSP_FILTER_ENABLE	0x41
+
+/* BIAS AND POWER MODE CONFIGURATION REGISTERS */
+#define MAX98090_0x42_BIAS_CTR		0x42
+#define MAX98090_0x43_DAC_CTR		0x43
+#define MAX98090_0x44_ADC_CTR		0x44
+#define MAX98090_0x45_DEV_SHUTDOWN	0x45
+
+/* REVISION ID REGISTER */
+#define MAX98090_0xFF_REV_ID		0xFF
+
+#define MAX98090_REG_MAX_CACHED		0x45
+#define MAX98090_REG_END		0xFF
+
+/*
+ *
+ * MAX98090 Registers Bit Fields
+ *
+ */
+
+/* MAX98090_0x06_DAI_IF */
+#define MAX98090_DAI_IF_MASK		0x3F
+#define MAX98090_RJ_M			(1 << 5)
+#define MAX98090_RJ_S			(1 << 4)
+#define MAX98090_LJ_M			(1 << 3)
+#define MAX98090_LJ_S			(1 << 2)
+#define MAX98090_I2S_M			(1 << 1)
+#define MAX98090_I2S_S			(1 << 0)
+
+/* MAX98090_0x45_DEV_SHUTDOWN */
+#define MAX98090_SHDNRUN		(1 << 7)
+
+/* codec private data */
+struct max98090_priv {
+	struct regmap *regmap;
+};
+
+static const struct reg_default max98090_reg_defaults[] = {
+	/* RESET / STATUS / INTERRUPT REGISTERS */
+	{MAX98090_0x00_SW_RESET,		0x00},
+	{MAX98090_0x01_INT_STS,			0x00},
+	{MAX98090_0x02_JACK_STS,		0x00},
+	{MAX98090_0x03_INT_MASK,		0x04},
+
+	/* QUICK SETUP REGISTERS */
+	{MAX98090_0x04_SYS_CLK,			0x00},
+	{MAX98090_0x05_SAMPLE_RATE,		0x00},
+	{MAX98090_0x06_DAI_IF,			0x00},
+	{MAX98090_0x07_DAC_PATH,		0x00},
+	{MAX98090_0x08_MIC_TO_ADC,		0x00},
+	{MAX98090_0x09_LINE_TO_ADC,		0x00},
+	{MAX98090_0x0A_ANALOG_MIC_LOOP,		0x00},
+	{MAX98090_0x0B_ANALOG_LINE_LOOP,	0x00},
+
+	/* ANALOG INPUT CONFIGURATION REGISTERS */
+	{MAX98090_0x0D_INPUT_CONFIG,		0x00},
+	{MAX98090_0x0E_LINE_IN_LVL,		0x1B},
+	{MAX98090_0x0F_LINI_IN_CFG,		0x00},
+	{MAX98090_0x10_MIC1_IN_LVL,		0x11},
+	{MAX98090_0x11_MIC2_IN_LVL,		0x11},
+
+	/* MICROPHONE CONFIGURATION REGISTERS  */
+	{MAX98090_0x12_MIC_BIAS_VOL,		0x00},
+	{MAX98090_0x13_DIGITAL_MIC_CFG,		0x00},
+	{MAX98090_0x14_DIGITAL_MIC_MODE,	0x00},
+
+	/* ADC PATH AND CONFIGURATION REGISTERS */
+	{MAX98090_0x15_L_ADC_MIX,		0x00},
+	{MAX98090_0x16_R_ADC_MIX,		0x00},
+	{MAX98090_0x17_L_ADC_LVL,		0x03},
+	{MAX98090_0x18_R_ADC_LVL,		0x03},
+	{MAX98090_0x19_ADC_BIQUAD_LVL,		0x00},
+	{MAX98090_0x1A_ADC_SIDETONE,		0x00},
+
+	/* CLOCK CONFIGURATION REGISTERS */
+	{MAX98090_0x1B_SYS_CLK,			0x00},
+	{MAX98090_0x1C_CLK_MODE,		0x00},
+	{MAX98090_0x1D_ANY_CLK1,		0x00},
+	{MAX98090_0x1E_ANY_CLK2,		0x00},
+	{MAX98090_0x1F_ANY_CLK3,		0x00},
+	{MAX98090_0x20_ANY_CLK4,		0x00},
+	{MAX98090_0x21_MASTER_MODE,		0x00},
+
+	/* INTERFACE CONTROL REGISTERS */
+	{MAX98090_0x22_DAI_IF_FMT,		0x00},
+	{MAX98090_0x23_DAI_TDM_FMT1,		0x00},
+	{MAX98090_0x24_DAI_TDM_FMT2,		0x00},
+	{MAX98090_0x25_DAI_IO_CFG,		0x00},
+	{MAX98090_0x26_FILTER_CFG,		0x80},
+	{MAX98090_0x27_DAI_PLAYBACK_LVL,	0x00},
+	{MAX98090_0x28_EQ_PLAYBACK_LVL,		0x00},
+
+	/* HEADPHONE CONTROL REGISTERS */
+	{MAX98090_0x29_L_HP_MIX,		0x00},
+	{MAX98090_0x2A_R_HP_MIX,		0x00},
+	{MAX98090_0x2B_HP_CTR,			0x00},
+	{MAX98090_0x2C_L_HP_VOL,		0x1A},
+	{MAX98090_0x2D_R_HP_VOL,		0x1A},
+
+	/* SPEAKER CONFIGURATION REGISTERS */
+	{MAX98090_0x2E_L_SPK_MIX,		0x00},
+	{MAX98090_0x2F_R_SPK_MIX,		0x00},
+	{MAX98090_0x30_SPK_CTR,			0x00},
+	{MAX98090_0x31_L_SPK_VOL,		0x2C},
+	{MAX98090_0x32_R_SPK_VOL,		0x2C},
+
+	/* ALC CONFIGURATION REGISTERS */
+	{MAX98090_0x33_ALC_TIMING,		0x00},
+	{MAX98090_0x34_ALC_COMPRESSOR,		0x00},
+	{MAX98090_0x35_ALC_EXPANDER,		0x00},
+	{MAX98090_0x36_ALC_GAIN,		0x00},
+
+	/* RECEIVER AND LINE_OUTPUT REGISTERS */
+	{MAX98090_0x37_RCV_LOUT_L_MIX,		0x00},
+	{MAX98090_0x38_RCV_LOUT_L_CNTL,		0x00},
+	{MAX98090_0x39_RCV_LOUT_L_VOL,		0x15},
+	{MAX98090_0x3A_LOUT_R_MIX,		0x00},
+	{MAX98090_0x3B_LOUT_R_CNTL,		0x00},
+	{MAX98090_0x3C_LOUT_R_VOL,		0x15},
+
+	/* JACK DETECT AND ENABLE REGISTERS */
+	{MAX98090_0x3D_JACK_DETECT,		0x00},
+	{MAX98090_0x3E_IN_ENABLE,		0x00},
+	{MAX98090_0x3F_OUT_ENABLE,		0x00},
+	{MAX98090_0x40_LVL_CTR,			0x00},
+	{MAX98090_0x41_DSP_FILTER_ENABLE,	0x00},
+
+	/* BIAS AND POWER MODE CONFIGURATION REGISTERS */
+	{MAX98090_0x42_BIAS_CTR,		0x00},
+	{MAX98090_0x43_DAC_CTR,			0x00},
+	{MAX98090_0x44_ADC_CTR,			0x06},
+	{MAX98090_0x45_DEV_SHUTDOWN,		0x00},
+};
+
+static const unsigned int max98090_hp_tlv[] = {
+	TLV_DB_RANGE_HEAD(5),
+	0x0,	0x6,	TLV_DB_SCALE_ITEM(-6700, 400, 0),
+	0x7,	0xE,	TLV_DB_SCALE_ITEM(-4000, 300, 0),
+	0xF,	0x15,	TLV_DB_SCALE_ITEM(-1700, 200, 0),
+	0x16,	0x1B,	TLV_DB_SCALE_ITEM(-400, 100, 0),
+	0x1C,	0x1F,	TLV_DB_SCALE_ITEM(150, 50, 0),
+};
+
+static struct snd_kcontrol_new max98090_snd_controls[] = {
+	SOC_DOUBLE_R_TLV("Headphone Volume", MAX98090_0x2C_L_HP_VOL,
+			 MAX98090_0x2D_R_HP_VOL, 0, 31, 0, max98090_hp_tlv),
+};
+
+/* Left HeadPhone Mixer Switch */
+static struct snd_kcontrol_new max98090_left_hp_mixer_controls[] = {
+	SOC_DAPM_SINGLE("DACR Switch", MAX98090_0x29_L_HP_MIX, 1, 1, 0),
+	SOC_DAPM_SINGLE("DACL Switch", MAX98090_0x29_L_HP_MIX, 0, 1, 0),
+};
+
+/* Right HeadPhone Mixer Switch */
+static struct snd_kcontrol_new max98090_right_hp_mixer_controls[] = {
+	SOC_DAPM_SINGLE("DACR Switch", MAX98090_0x2A_R_HP_MIX, 1, 1, 0),
+	SOC_DAPM_SINGLE("DACL Switch", MAX98090_0x2A_R_HP_MIX, 0, 1, 0),
+};
+
+static struct snd_soc_dapm_widget max98090_dapm_widgets[] = {
+	/* Output */
+	SND_SOC_DAPM_OUTPUT("HPL"),
+	SND_SOC_DAPM_OUTPUT("HPR"),
+
+	/* PGA */
+	SND_SOC_DAPM_PGA("HPL Out", MAX98090_0x3F_OUT_ENABLE, 7, 0, NULL, 0),
+	SND_SOC_DAPM_PGA("HPR Out", MAX98090_0x3F_OUT_ENABLE, 6, 0, NULL, 0),
+
+	/* Mixer */
+	SND_SOC_DAPM_MIXER("HPL Mixer", SND_SOC_NOPM, 0, 0,
+			   max98090_left_hp_mixer_controls,
+			   ARRAY_SIZE(max98090_left_hp_mixer_controls)),
+
+	SND_SOC_DAPM_MIXER("HPR Mixer", SND_SOC_NOPM, 0, 0,
+			   max98090_right_hp_mixer_controls,
+			   ARRAY_SIZE(max98090_right_hp_mixer_controls)),
+
+	/* DAC */
+	SND_SOC_DAPM_DAC("DACL", "Hifi Playback", MAX98090_0x3F_OUT_ENABLE, 0, 0),
+	SND_SOC_DAPM_DAC("DACR", "Hifi Playback", MAX98090_0x3F_OUT_ENABLE, 1, 0),
+};
+
+static struct snd_soc_dapm_route max98090_audio_map[] = {
+	/* Output */
+	{"HPL", NULL, "HPL Out"},
+	{"HPR", NULL, "HPR Out"},
+
+	/* PGA */
+	{"HPL Out", NULL, "HPL Mixer"},
+	{"HPR Out", NULL, "HPR Mixer"},
+
+	/* Mixer*/
+	{"HPL Mixer", "DACR Switch", "DACR"},
+	{"HPL Mixer", "DACL Switch", "DACL"},
+
+	{"HPR Mixer", "DACR Switch", "DACR"},
+	{"HPR Mixer", "DACL Switch", "DACL"},
+};
+
+static bool max98090_volatile(struct device *dev, unsigned int reg)
+{
+	if ((reg == MAX98090_0x01_INT_STS)	||
+	    (reg == MAX98090_0x02_JACK_STS)	||
+	    (reg >  MAX98090_REG_MAX_CACHED))
+		return true;
+
+	return false;
+}
+
+static int max98090_dai_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;
+	unsigned int val;
+
+	switch (params_rate(params)) {
+	case 96000:
+		val = 1 << 5;
+		break;
+	case 32000:
+		val = 1 << 4;
+		break;
+	case 48000:
+		val = 1 << 3;
+		break;
+	case 44100:
+		val = 1 << 2;
+		break;
+	case 16000:
+		val = 1 << 1;
+		break;
+	case 8000:
+		val = 1 << 0;
+		break;
+	default:
+		dev_err(codec->dev, "unsupported rate\n");
+		return -EINVAL;
+	}
+	snd_soc_update_bits(codec, MAX98090_0x05_SAMPLE_RATE, 0x03F, val);
+
+	return 0;
+}
+
+static int max98090_dai_set_sysclk(struct snd_soc_dai *dai,
+		int clk_id, unsigned int freq, int dir)
+{
+	struct snd_soc_codec *codec = dai->codec;
+	unsigned int val;
+
+	snd_soc_update_bits(codec, MAX98090_0x45_DEV_SHUTDOWN,
+			    MAX98090_SHDNRUN, 0);
+
+	switch (freq) {
+	case 26000000:
+		val = 1 << 7;
+		break;
+	case 19200000:
+		val = 1 << 6;
+		break;
+	case 13000000:
+		val = 1 << 5;
+		break;
+	case 12288000:
+		val = 1 << 4;
+		break;
+	case 12000000:
+		val = 1 << 3;
+		break;
+	case 11289600:
+		val = 1 << 2;
+		break;
+	default:
+		dev_err(codec->dev, "Invalid master clock frequency\n");
+		return -EINVAL;
+	}
+	snd_soc_update_bits(codec, MAX98090_0x04_SYS_CLK, 0xFD, val);
+
+	snd_soc_update_bits(codec, MAX98090_0x45_DEV_SHUTDOWN,
+			    MAX98090_SHDNRUN, MAX98090_SHDNRUN);
+
+	dev_dbg(dai->dev, "sysclk is %uHz\n", freq);
+
+	return 0;
+}
+
+static int max98090_dai_set_fmt(struct snd_soc_dai *dai,
+				unsigned int fmt)
+{
+	struct snd_soc_codec *codec = dai->codec;
+	int is_master;
+	u8 val;
+
+	/* master/slave mode */
+	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+	case SND_SOC_DAIFMT_CBM_CFM:
+		is_master = 1;
+		break;
+	case SND_SOC_DAIFMT_CBS_CFS:
+		is_master = 0;
+		break;
+	default:
+		dev_err(codec->dev, "unsupported clock\n");
+		return -EINVAL;
+	}
+
+	/* format */
+	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+	case SND_SOC_DAIFMT_I2S:
+		val = (is_master) ? MAX98090_I2S_M : MAX98090_I2S_S;
+		break;
+	case SND_SOC_DAIFMT_RIGHT_J:
+		val = (is_master) ? MAX98090_RJ_M : MAX98090_RJ_S;
+		break;
+	case SND_SOC_DAIFMT_LEFT_J:
+		val = (is_master) ? MAX98090_LJ_M : MAX98090_LJ_S;
+		break;
+	default:
+		dev_err(codec->dev, "unsupported format\n");
+		return -EINVAL;
+	}
+	snd_soc_update_bits(codec, MAX98090_0x06_DAI_IF,
+			    MAX98090_DAI_IF_MASK, val);
+
+	return 0;
+}
+
+#define MAX98090_RATES SNDRV_PCM_RATE_8000_96000
+#define MAX98090_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE)
+
+static struct snd_soc_dai_ops max98090_dai_ops = {
+	.set_sysclk	= max98090_dai_set_sysclk,
+	.set_fmt	= max98090_dai_set_fmt,
+	.hw_params	= max98090_dai_hw_params,
+};
+
+static struct snd_soc_dai_driver max98090_dai = {
+	.name = "max98090-Hifi",
+	.playback = {
+		.stream_name	= "Playback",
+		.channels_min	= 1,
+		.channels_max	= 2,
+		.rates		= MAX98090_RATES,
+		.formats	= MAX98090_FORMATS,
+	},
+	.ops = &max98090_dai_ops,
+};
+
+static int max98090_probe(struct snd_soc_codec *codec)
+{
+	struct max98090_priv *priv = snd_soc_codec_get_drvdata(codec);
+	struct device *dev = codec->dev;
+	int ret;
+
+	codec->control_data = priv->regmap;
+	ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
+	if (ret < 0) {
+		dev_err(dev, "Failed to set cache I/O: %d\n", ret);
+		return ret;
+	}
+
+	/* Device active */
+	snd_soc_update_bits(codec, MAX98090_0x45_DEV_SHUTDOWN,
+			    MAX98090_SHDNRUN, MAX98090_SHDNRUN);
+
+	return 0;
+}
+
+static int max98090_remove(struct snd_soc_codec *codec)
+{
+	return 0;
+}
+
+static struct snd_soc_codec_driver soc_codec_dev_max98090 = {
+	.probe			= max98090_probe,
+	.remove			= max98090_remove,
+	.controls		= max98090_snd_controls,
+	.num_controls		= ARRAY_SIZE(max98090_snd_controls),
+	.dapm_widgets		= max98090_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(max98090_dapm_widgets),
+	.dapm_routes		= max98090_audio_map,
+	.num_dapm_routes	= ARRAY_SIZE(max98090_audio_map),
+};
+
+static const struct regmap_config max98090_regmap = {
+	.reg_bits		= 8,
+	.val_bits		= 8,
+	.max_register		= MAX98090_REG_END,
+	.volatile_reg		= max98090_volatile,
+	.cache_type		= REGCACHE_RBTREE,
+	.reg_defaults		= max98090_reg_defaults,
+	.num_reg_defaults	= ARRAY_SIZE(max98090_reg_defaults),
+};
+
+static int max98090_i2c_probe(struct i2c_client *i2c,
+			      const struct i2c_device_id *id)
+{
+	struct max98090_priv *priv;
+	struct device *dev = &i2c->dev;
+	unsigned int val;
+	int ret;
+
+	priv = devm_kzalloc(dev, sizeof(struct max98090_priv),
+			    GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	priv->regmap = devm_regmap_init_i2c(i2c, &max98090_regmap);
+	if (IS_ERR(priv->regmap)) {
+		ret = PTR_ERR(priv->regmap);
+		dev_err(dev, "Failed to init regmap: %d\n", ret);
+		return ret;
+	}
+
+	i2c_set_clientdata(i2c, priv);
+
+	ret = regmap_read(priv->regmap, MAX98090_0xFF_REV_ID, &val);
+	if (ret < 0) {
+		dev_err(dev, "Failed to read device revision: %d\n", ret);
+		return ret;
+	}
+	dev_info(dev, "revision 0x%02x\n", val);
+
+	ret = snd_soc_register_codec(dev,
+				     &soc_codec_dev_max98090,
+				     &max98090_dai, 1);
+
+	return ret;
+}
+
+static int max98090_i2c_remove(struct i2c_client *client)
+{
+	snd_soc_unregister_codec(&client->dev);
+	return 0;
+}
+
+static const struct i2c_device_id max98090_i2c_id[] = {
+	{ "max98090", 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, max98090_i2c_id);
+
+static struct i2c_driver max98090_i2c_driver = {
+	.driver = {
+		.name = "max98090",
+		.owner = THIS_MODULE,
+	},
+	.probe		= max98090_i2c_probe,
+	.remove		= max98090_i2c_remove,
+	.id_table	= max98090_i2c_id,
+};
+module_i2c_driver(max98090_i2c_driver);
+
+MODULE_DESCRIPTION("ALSA SoC MAX98090 driver");
+MODULE_AUTHOR("Peter Hsiang, Kuninori Morimoto");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/max98095.c b/sound/soc/codecs/max98095.c
index 38d43c5..41cdd16 100644
--- a/sound/soc/codecs/max98095.c
+++ b/sound/soc/codecs/max98095.c
@@ -2511,7 +2511,7 @@
 	return ret;
 }
 
-static int __devexit max98095_i2c_remove(struct i2c_client *client)
+static int max98095_i2c_remove(struct i2c_client *client)
 {
 	snd_soc_unregister_codec(&client->dev);
 	return 0;
@@ -2529,7 +2529,7 @@
 		.owner = THIS_MODULE,
 	},
 	.probe  = max98095_i2c_probe,
-	.remove = __devexit_p(max98095_i2c_remove),
+	.remove = max98095_i2c_remove,
 	.id_table = max98095_i2c_id,
 };
 
diff --git a/sound/soc/codecs/max9850.c b/sound/soc/codecs/max9850.c
index efe535c..58c38a5 100644
--- a/sound/soc/codecs/max9850.c
+++ b/sound/soc/codecs/max9850.c
@@ -329,8 +329,8 @@
 	.num_dapm_routes = ARRAY_SIZE(max9850_dapm_routes),
 };
 
-static int __devinit max9850_i2c_probe(struct i2c_client *i2c,
-		const struct i2c_device_id *id)
+static int max9850_i2c_probe(struct i2c_client *i2c,
+			     const struct i2c_device_id *id)
 {
 	struct max9850_priv *max9850;
 	int ret;
@@ -347,7 +347,7 @@
 	return ret;
 }
 
-static __devexit int max9850_i2c_remove(struct i2c_client *client)
+static int max9850_i2c_remove(struct i2c_client *client)
 {
 	snd_soc_unregister_codec(&client->dev);
 	return 0;
@@ -365,7 +365,7 @@
 		.owner = THIS_MODULE,
 	},
 	.probe = max9850_i2c_probe,
-	.remove = __devexit_p(max9850_i2c_remove),
+	.remove = max9850_i2c_remove,
 	.id_table = max9850_i2c_id,
 };
 
diff --git a/sound/soc/codecs/max9877.c b/sound/soc/codecs/max9877.c
index d15e594..6b6c74c 100644
--- a/sound/soc/codecs/max9877.c
+++ b/sound/soc/codecs/max9877.c
@@ -258,8 +258,8 @@
 }
 EXPORT_SYMBOL_GPL(max9877_add_controls);
 
-static int __devinit max9877_i2c_probe(struct i2c_client *client,
-		const struct i2c_device_id *id)
+static int max9877_i2c_probe(struct i2c_client *client,
+			     const struct i2c_device_id *id)
 {
 	i2c = client;
 
@@ -268,7 +268,7 @@
 	return 0;
 }
 
-static __devexit int max9877_i2c_remove(struct i2c_client *client)
+static int max9877_i2c_remove(struct i2c_client *client)
 {
 	i2c = NULL;
 
@@ -287,7 +287,7 @@
 		.owner = THIS_MODULE,
 	},
 	.probe = max9877_i2c_probe,
-	.remove = __devexit_p(max9877_i2c_remove),
+	.remove = max9877_i2c_remove,
 	.id_table = max9877_i2c_id,
 };
 
diff --git a/sound/soc/codecs/mc13783.c b/sound/soc/codecs/mc13783.c
index bc95599..5402dfb 100644
--- a/sound/soc/codecs/mc13783.c
+++ b/sound/soc/codecs/mc13783.c
@@ -779,7 +779,7 @@
 		   .owner = THIS_MODULE,
 		   },
 	.probe = mc13783_codec_probe,
-	.remove = __devexit_p(mc13783_codec_remove),
+	.remove = mc13783_codec_remove,
 };
 
 module_platform_driver(mc13783_codec_driver);
diff --git a/sound/soc/codecs/ml26124.c b/sound/soc/codecs/ml26124.c
index 96aa5fa..2611882 100644
--- a/sound/soc/codecs/ml26124.c
+++ b/sound/soc/codecs/ml26124.c
@@ -626,8 +626,8 @@
 	.write_flag_mask = 0x01,
 };
 
-static __devinit int ml26124_i2c_probe(struct i2c_client *i2c,
-				      const struct i2c_device_id *id)
+static int ml26124_i2c_probe(struct i2c_client *i2c,
+			     const struct i2c_device_id *id)
 {
 	struct ml26124_priv *priv;
 	int ret;
@@ -649,7 +649,7 @@
 			&soc_codec_dev_ml26124, &ml26124_dai, 1);
 }
 
-static __devexit int ml26124_i2c_remove(struct i2c_client *client)
+static int ml26124_i2c_remove(struct i2c_client *client)
 {
 	snd_soc_unregister_codec(&client->dev);
 	return 0;
@@ -667,7 +667,7 @@
 		.owner = THIS_MODULE,
 	},
 	.probe = ml26124_i2c_probe,
-	.remove = __devexit_p(ml26124_i2c_remove),
+	.remove = ml26124_i2c_remove,
 	.id_table = ml26124_i2c_id,
 };
 
diff --git a/sound/soc/codecs/omap-hdmi.c b/sound/soc/codecs/omap-hdmi.c
index 1bf5c74..529d064 100644
--- a/sound/soc/codecs/omap-hdmi.c
+++ b/sound/soc/codecs/omap-hdmi.c
@@ -39,13 +39,13 @@
 	},
 };
 
-static __devinit int omap_hdmi_codec_probe(struct platform_device *pdev)
+static int omap_hdmi_codec_probe(struct platform_device *pdev)
 {
 	return snd_soc_register_codec(&pdev->dev, &omap_hdmi_codec,
 			&omap_hdmi_codec_dai, 1);
 }
 
-static __devexit int omap_hdmi_codec_remove(struct platform_device *pdev)
+static int omap_hdmi_codec_remove(struct platform_device *pdev)
 {
 	snd_soc_unregister_codec(&pdev->dev);
 	return 0;
@@ -58,7 +58,7 @@
 	},
 
 	.probe		= omap_hdmi_codec_probe,
-	.remove		= __devexit_p(omap_hdmi_codec_remove),
+	.remove		= omap_hdmi_codec_remove,
 };
 
 module_platform_driver(omap_hdmi_codec_driver);
diff --git a/sound/soc/codecs/pcm3008.c b/sound/soc/codecs/pcm3008.c
index edcaa7e..f2a6282 100644
--- a/sound/soc/codecs/pcm3008.c
+++ b/sound/soc/codecs/pcm3008.c
@@ -149,13 +149,13 @@
 	.resume =	pcm3008_soc_resume,
 };
 
-static int __devinit pcm3008_codec_probe(struct platform_device *pdev)
+static int pcm3008_codec_probe(struct platform_device *pdev)
 {
 	return snd_soc_register_codec(&pdev->dev,
 			&soc_codec_dev_pcm3008, &pcm3008_dai, 1);
 }
 
-static int __devexit pcm3008_codec_remove(struct platform_device *pdev)
+static int pcm3008_codec_remove(struct platform_device *pdev)
 {
 	snd_soc_unregister_codec(&pdev->dev);
 	return 0;
@@ -165,7 +165,7 @@
 
 static struct platform_driver pcm3008_codec_driver = {
 	.probe		= pcm3008_codec_probe,
-	.remove		= __devexit_p(pcm3008_codec_remove),
+	.remove		= pcm3008_codec_remove,
 	.driver		= {
 		.name	= "pcm3008-codec",
 		.owner	= THIS_MODULE,
diff --git a/sound/soc/codecs/rt5631.c b/sound/soc/codecs/rt5631.c
index 960d0e9..912c9cb 100644
--- a/sound/soc/codecs/rt5631.c
+++ b/sound/soc/codecs/rt5631.c
@@ -1382,7 +1382,7 @@
 					timesofbclk);
 	if (coeff < 0) {
 		dev_err(codec->dev, "Fail to get coeff\n");
-		return -EINVAL;
+		return coeff;
 	}
 
 	switch (params_format(params)) {
@@ -1748,7 +1748,7 @@
 	return ret;
 }
 
-static __devexit int rt5631_i2c_remove(struct i2c_client *client)
+static int rt5631_i2c_remove(struct i2c_client *client)
 {
 	snd_soc_unregister_codec(&client->dev);
 	return 0;
@@ -1760,7 +1760,7 @@
 		.owner = THIS_MODULE,
 	},
 	.probe = rt5631_i2c_probe,
-	.remove   = __devexit_p(rt5631_i2c_remove),
+	.remove   = rt5631_i2c_remove,
 	.id_table = rt5631_i2c_id,
 };
 
diff --git a/sound/soc/codecs/sgtl5000.c b/sound/soc/codecs/sgtl5000.c
index df2f99d1..cb1675c 100644
--- a/sound/soc/codecs/sgtl5000.c
+++ b/sound/soc/codecs/sgtl5000.c
@@ -1404,8 +1404,8 @@
 	.num_dapm_routes = ARRAY_SIZE(sgtl5000_dapm_routes),
 };
 
-static __devinit int sgtl5000_i2c_probe(struct i2c_client *client,
-					const struct i2c_device_id *id)
+static int sgtl5000_i2c_probe(struct i2c_client *client,
+			      const struct i2c_device_id *id)
 {
 	struct sgtl5000_priv *sgtl5000;
 	int ret;
@@ -1422,7 +1422,7 @@
 	return ret;
 }
 
-static __devexit int sgtl5000_i2c_remove(struct i2c_client *client)
+static int sgtl5000_i2c_remove(struct i2c_client *client)
 {
 	snd_soc_unregister_codec(&client->dev);
 
@@ -1449,7 +1449,7 @@
 		   .of_match_table = sgtl5000_dt_ids,
 		   },
 	.probe = sgtl5000_i2c_probe,
-	.remove = __devexit_p(sgtl5000_i2c_remove),
+	.remove = sgtl5000_i2c_remove,
 	.id_table = sgtl5000_id,
 };
 
diff --git a/sound/soc/codecs/si476x.c b/sound/soc/codecs/si476x.c
new file mode 100644
index 0000000..f2d61a1
--- /dev/null
+++ b/sound/soc/codecs/si476x.c
@@ -0,0 +1,255 @@
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/initval.h>
+
+#include <linux/i2c.h>
+
+#include <linux/mfd/si476x-core.h>
+
+enum si476x_audio_registers {
+	SI476X_DIGITAL_IO_OUTPUT_FORMAT		= 0x0203,
+	SI476X_DIGITAL_IO_OUTPUT_SAMPLE_RATE	= 0x0202,
+};
+
+enum si476x_digital_io_output_format {
+	SI476X_DIGITAL_IO_SLOT_SIZE_SHIFT	= 11,
+	SI476X_DIGITAL_IO_SAMPLE_SIZE_SHIFT	= 8,
+};
+
+#define SI476X_DIGITAL_IO_OUTPUT_WIDTH_MASK	((0b111 << SI476X_DIGITAL_IO_SLOT_SIZE_SHIFT) | \
+						  (0b111 << SI476X_DIGITAL_IO_SAMPLE_SIZE_SHIFT))
+#define SI476X_DIGITAL_IO_OUTPUT_FORMAT_MASK	(0b1111110)
+
+enum si476x_daudio_formats {
+	SI476X_DAUDIO_MODE_I2S		= (0x0 << 1),
+	SI476X_DAUDIO_MODE_DSP_A	= (0x6 << 1),
+	SI476X_DAUDIO_MODE_DSP_B	= (0x7 << 1),
+	SI476X_DAUDIO_MODE_LEFT_J	= (0x8 << 1),
+	SI476X_DAUDIO_MODE_RIGHT_J	= (0x9 << 1),
+
+	SI476X_DAUDIO_MODE_IB		= (1 << 5),
+	SI476X_DAUDIO_MODE_IF		= (1 << 6),
+};
+
+enum si476x_pcm_format {
+	SI476X_PCM_FORMAT_S8		= 2,
+	SI476X_PCM_FORMAT_S16_LE	= 4,
+	SI476X_PCM_FORMAT_S20_3LE	= 5,
+	SI476X_PCM_FORMAT_S24_LE	= 6,
+};
+
+static unsigned int si476x_codec_read(struct snd_soc_codec *codec,
+				      unsigned int reg)
+{
+	int err;
+	struct si476x_core *core = codec->control_data;
+
+	si476x_core_lock(core);
+	err = si476x_core_cmd_get_property(core, reg);
+	si476x_core_unlock(core);
+
+	return err;
+}
+
+static int si476x_codec_write(struct snd_soc_codec *codec,
+			      unsigned int reg, unsigned int val)
+{
+	int err;
+	struct si476x_core *core = codec->control_data;
+
+	si476x_core_lock(core);
+	err = si476x_core_cmd_set_property(core, reg, val);
+	si476x_core_unlock(core);
+
+	return err;
+}
+
+static int si476x_codec_set_dai_fmt(struct snd_soc_dai *codec_dai,
+				    unsigned int fmt)
+{
+	int err;
+	u16 format = 0;
+
+	if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) != SND_SOC_DAIFMT_CBS_CFS)
+		return -EINVAL;
+
+	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+	case SND_SOC_DAIFMT_DSP_A:
+		format |= SI476X_DAUDIO_MODE_DSP_A;
+		break;
+	case SND_SOC_DAIFMT_DSP_B:
+		format |= SI476X_DAUDIO_MODE_DSP_B;
+		break;
+	case SND_SOC_DAIFMT_I2S:
+		format |= SI476X_DAUDIO_MODE_I2S;
+		break;
+	case SND_SOC_DAIFMT_RIGHT_J:
+		format |= SI476X_DAUDIO_MODE_RIGHT_J;
+		break;
+	case SND_SOC_DAIFMT_LEFT_J:
+		format |= SI476X_DAUDIO_MODE_LEFT_J;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+	case SND_SOC_DAIFMT_DSP_A:
+	case SND_SOC_DAIFMT_DSP_B:
+		switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+		case SND_SOC_DAIFMT_NB_NF:
+			break;
+		case SND_SOC_DAIFMT_IB_NF:
+			format |= SI476X_DAUDIO_MODE_IB;
+			break;
+		default:
+			return -EINVAL;
+		}
+		break;
+	case SND_SOC_DAIFMT_I2S:
+	case SND_SOC_DAIFMT_RIGHT_J:
+	case SND_SOC_DAIFMT_LEFT_J:
+		switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+		case SND_SOC_DAIFMT_NB_NF:
+			break;
+		case SND_SOC_DAIFMT_IB_IF:
+			format |= SI476X_DAUDIO_MODE_IB |
+				SI476X_DAUDIO_MODE_IF;
+			break;
+		case SND_SOC_DAIFMT_IB_NF:
+			format |= SI476X_DAUDIO_MODE_IB;
+			break;
+		case SND_SOC_DAIFMT_NB_IF:
+			format |= SI476X_DAUDIO_MODE_IF;
+			break;
+		default:
+			return -EINVAL;
+		}
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	err = snd_soc_update_bits(codec_dai->codec, SI476X_DIGITAL_IO_OUTPUT_FORMAT,
+				  SI476X_DIGITAL_IO_OUTPUT_FORMAT_MASK,
+				  format);
+	if (err < 0) {
+		dev_err(codec_dai->codec->dev, "Failed to set output format\n");
+		return err;
+	}
+	
+	return 0;
+}
+
+static int si476x_codec_hw_params(struct snd_pcm_substream *substream,
+				  struct snd_pcm_hw_params *params,
+				  struct snd_soc_dai *dai)
+{
+	int rate, width, err;
+
+	rate = params_rate(params);
+	if (rate < 32000 || rate > 48000) {
+		dev_err(dai->codec->dev, "Rate: %d is not supported\n", rate);
+		return -EINVAL;
+	}
+
+	switch (params_format(params)) {
+	case SNDRV_PCM_FORMAT_S8:
+		width = SI476X_PCM_FORMAT_S8;
+	case SNDRV_PCM_FORMAT_S16_LE:
+		width = SI476X_PCM_FORMAT_S16_LE;
+		break;
+	case SNDRV_PCM_FORMAT_S20_3LE:
+		width = SI476X_PCM_FORMAT_S20_3LE;
+		break;
+	case SNDRV_PCM_FORMAT_S24_LE:
+		width = SI476X_PCM_FORMAT_S24_LE;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	err = snd_soc_write(dai->codec, SI476X_DIGITAL_IO_OUTPUT_SAMPLE_RATE,
+			    rate);
+	if (err < 0) {
+		dev_err(dai->codec->dev, "Failed to set sample rate\n");
+		return err;
+	}
+
+	err = snd_soc_update_bits(dai->codec, SI476X_DIGITAL_IO_OUTPUT_FORMAT,
+				  SI476X_DIGITAL_IO_OUTPUT_WIDTH_MASK,
+				  (width << SI476X_DIGITAL_IO_SLOT_SIZE_SHIFT) | 
+				  (width << SI476X_DIGITAL_IO_SAMPLE_SIZE_SHIFT));
+	if (err < 0) {
+		dev_err(dai->codec->dev, "Failed to set output width\n");
+		return err;
+	}
+
+	return 0;
+}
+
+static int si476x_codec_probe(struct snd_soc_codec *codec)
+{
+	codec->control_data = i2c_mfd_cell_to_core(codec->dev);
+	return 0;
+}
+
+static struct snd_soc_dai_ops si476x_dai_ops = {
+	.hw_params	= si476x_codec_hw_params,
+	.set_fmt	= si476x_codec_set_dai_fmt,
+};
+
+static struct snd_soc_dai_driver si476x_dai = {
+	.name		= "si476x-codec",
+	.capture	= {
+		.stream_name	= "Capture",
+		.channels_min	= 2,
+		.channels_max	= 2,
+
+		.rates = SNDRV_PCM_RATE_32000 |
+		SNDRV_PCM_RATE_44100 |
+		SNDRV_PCM_RATE_48000,
+		.formats = SNDRV_PCM_FMTBIT_S8 |
+		SNDRV_PCM_FMTBIT_S16_LE |
+		SNDRV_PCM_FMTBIT_S20_3LE |
+		SNDRV_PCM_FMTBIT_S24_LE
+	},
+	.ops		= &si476x_dai_ops,
+};
+
+static struct snd_soc_codec_driver soc_codec_dev_si476x = {
+	.probe  = si476x_codec_probe,
+	.read   = si476x_codec_read,
+	.write  = si476x_codec_write,
+};
+
+static int si476x_platform_probe(struct platform_device *pdev)
+{
+	return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_si476x,
+				      &si476x_dai, 1);
+}
+
+static int si476x_platform_remove(struct platform_device *pdev)
+{
+	snd_soc_unregister_codec(&pdev->dev);
+	return 0;
+}
+
+MODULE_ALIAS("platform:si476x-codec");
+
+static struct platform_driver si476x_platform_driver = {
+	.driver		= {
+		.name	= "si476x-codec",
+		.owner	= THIS_MODULE,
+	},
+	.probe		= si476x_platform_probe,
+	.remove		= si476x_platform_remove,
+};
+module_platform_driver(si476x_platform_driver);
+
+MODULE_AUTHOR("Andrey Smirnov <andrey.smirnov@convergeddevices.net>");
+MODULE_DESCRIPTION("ASoC Si4761/64 codec driver");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/sn95031.c b/sound/soc/codecs/sn95031.c
index 50dbdb9..d1ae869d 100644
--- a/sound/soc/codecs/sn95031.c
+++ b/sound/soc/codecs/sn95031.c
@@ -896,14 +896,14 @@
 	.num_dapm_routes	= ARRAY_SIZE(sn95031_audio_map),
 };
 
-static int __devinit sn95031_device_probe(struct platform_device *pdev)
+static int sn95031_device_probe(struct platform_device *pdev)
 {
 	pr_debug("codec device probe called for %s\n", dev_name(&pdev->dev));
 	return snd_soc_register_codec(&pdev->dev, &sn95031_codec,
 			sn95031_dais, ARRAY_SIZE(sn95031_dais));
 }
 
-static int __devexit sn95031_device_remove(struct platform_device *pdev)
+static int sn95031_device_remove(struct platform_device *pdev)
 {
 	pr_debug("codec device remove called\n");
 	snd_soc_unregister_codec(&pdev->dev);
@@ -916,7 +916,7 @@
 		.owner		= THIS_MODULE,
 	},
 	.probe		= sn95031_device_probe,
-	.remove		= __devexit_p(sn95031_device_remove),
+	.remove		= sn95031_device_remove,
 };
 
 module_platform_driver(sn95031_codec_driver);
diff --git a/sound/soc/codecs/ssm2602.c b/sound/soc/codecs/ssm2602.c
index 079066f..f8d30e5 100644
--- a/sound/soc/codecs/ssm2602.c
+++ b/sound/soc/codecs/ssm2602.c
@@ -691,7 +691,7 @@
 };
 
 #if defined(CONFIG_SPI_MASTER)
-static int __devinit ssm2602_spi_probe(struct spi_device *spi)
+static int ssm2602_spi_probe(struct spi_device *spi)
 {
 	struct ssm2602_priv *ssm2602;
 	int ret;
@@ -713,7 +713,7 @@
 	return ret;
 }
 
-static int __devexit ssm2602_spi_remove(struct spi_device *spi)
+static int ssm2602_spi_remove(struct spi_device *spi)
 {
 	snd_soc_unregister_codec(&spi->dev);
 	return 0;
@@ -725,7 +725,7 @@
 		.owner	= THIS_MODULE,
 	},
 	.probe		= ssm2602_spi_probe,
-	.remove		= __devexit_p(ssm2602_spi_remove),
+	.remove		= ssm2602_spi_remove,
 };
 #endif
 
@@ -736,7 +736,7 @@
  *    low  = 0x1a
  *    high = 0x1b
  */
-static int __devinit ssm2602_i2c_probe(struct i2c_client *i2c,
+static int ssm2602_i2c_probe(struct i2c_client *i2c,
 			     const struct i2c_device_id *id)
 {
 	struct ssm2602_priv *ssm2602;
@@ -759,7 +759,7 @@
 	return ret;
 }
 
-static int __devexit ssm2602_i2c_remove(struct i2c_client *client)
+static int ssm2602_i2c_remove(struct i2c_client *client)
 {
 	snd_soc_unregister_codec(&client->dev);
 	return 0;
@@ -780,7 +780,7 @@
 		.owner = THIS_MODULE,
 	},
 	.probe = ssm2602_i2c_probe,
-	.remove = __devexit_p(ssm2602_i2c_remove),
+	.remove = ssm2602_i2c_remove,
 	.id_table = ssm2602_i2c_id,
 };
 #endif
diff --git a/sound/soc/codecs/sta32x.c b/sound/soc/codecs/sta32x.c
index 0935bfe..cfb55fe 100644
--- a/sound/soc/codecs/sta32x.c
+++ b/sound/soc/codecs/sta32x.c
@@ -995,8 +995,8 @@
 	.volatile_reg =		sta32x_reg_is_volatile,
 };
 
-static __devinit int sta32x_i2c_probe(struct i2c_client *i2c,
-				      const struct i2c_device_id *id)
+static int sta32x_i2c_probe(struct i2c_client *i2c,
+			    const struct i2c_device_id *id)
 {
 	struct sta32x_priv *sta32x;
 	int ret, i;
@@ -1033,7 +1033,7 @@
 	return ret;
 }
 
-static __devexit int sta32x_i2c_remove(struct i2c_client *client)
+static int sta32x_i2c_remove(struct i2c_client *client)
 {
 	snd_soc_unregister_codec(&client->dev);
 	return 0;
@@ -1053,7 +1053,7 @@
 		.owner = THIS_MODULE,
 	},
 	.probe =    sta32x_i2c_probe,
-	.remove =   __devexit_p(sta32x_i2c_remove),
+	.remove =   sta32x_i2c_remove,
 	.id_table = sta32x_i2c_id,
 };
 
diff --git a/sound/soc/codecs/sta529.c b/sound/soc/codecs/sta529.c
index 9e31448..ab355c4 100644
--- a/sound/soc/codecs/sta529.c
+++ b/sound/soc/codecs/sta529.c
@@ -380,8 +380,8 @@
 	.num_reg_defaults = ARRAY_SIZE(sta529_reg_defaults),
 };
 
-static __devinit int sta529_i2c_probe(struct i2c_client *i2c,
-		const struct i2c_device_id *id)
+static int sta529_i2c_probe(struct i2c_client *i2c,
+			    const struct i2c_device_id *id)
 {
 	struct sta529 *sta529;
 	int ret;
@@ -412,7 +412,7 @@
 	return ret;
 }
 
-static int __devexit sta529_i2c_remove(struct i2c_client *client)
+static int sta529_i2c_remove(struct i2c_client *client)
 {
 	snd_soc_unregister_codec(&client->dev);
 
@@ -431,7 +431,7 @@
 		.owner = THIS_MODULE,
 	},
 	.probe		= sta529_i2c_probe,
-	.remove		= __devexit_p(sta529_i2c_remove),
+	.remove		= sta529_i2c_remove,
 	.id_table	= sta529_i2c_id,
 };
 
diff --git a/sound/soc/codecs/stac9766.c b/sound/soc/codecs/stac9766.c
index 982e437..2eda85ba 100644
--- a/sound/soc/codecs/stac9766.c
+++ b/sound/soc/codecs/stac9766.c
@@ -385,13 +385,13 @@
 	.reg_cache_default = stac9766_reg,
 };
 
-static __devinit int stac9766_probe(struct platform_device *pdev)
+static int stac9766_probe(struct platform_device *pdev)
 {
 	return snd_soc_register_codec(&pdev->dev,
 			&soc_codec_dev_stac9766, stac9766_dai, ARRAY_SIZE(stac9766_dai));
 }
 
-static int __devexit stac9766_remove(struct platform_device *pdev)
+static int stac9766_remove(struct platform_device *pdev)
 {
 	snd_soc_unregister_codec(&pdev->dev);
 	return 0;
@@ -404,7 +404,7 @@
 	},
 
 	.probe = stac9766_probe,
-	.remove = __devexit_p(stac9766_remove),
+	.remove = stac9766_remove,
 };
 
 module_platform_driver(stac9766_codec_driver);
diff --git a/sound/soc/codecs/tlv320aic32x4.c b/sound/soc/codecs/tlv320aic32x4.c
index f230292..17df4e3 100644
--- a/sound/soc/codecs/tlv320aic32x4.c
+++ b/sound/soc/codecs/tlv320aic32x4.c
@@ -28,6 +28,7 @@
 #include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/pm.h>
+#include <linux/gpio.h>
 #include <linux/i2c.h>
 #include <linux/cdev.h>
 #include <linux/slab.h>
@@ -65,6 +66,7 @@
 	u32 power_cfg;
 	u32 micpga_routing;
 	bool swapdacs;
+	int rstn_gpio;
 };
 
 /* 0dB min, 1dB steps */
@@ -627,10 +629,20 @@
 {
 	struct aic32x4_priv *aic32x4 = snd_soc_codec_get_drvdata(codec);
 	u32 tmp_reg;
+	int ret;
 
 	codec->hw_write = (hw_write_t) i2c_master_send;
 	codec->control_data = aic32x4->control_data;
 
+	if (aic32x4->rstn_gpio >= 0) {
+		ret = devm_gpio_request_one(codec->dev, aic32x4->rstn_gpio,
+				GPIOF_OUT_INIT_LOW, "tlv320aic32x4 rstn");
+		if (ret != 0)
+			return ret;
+		ndelay(10);
+		gpio_set_value(aic32x4->rstn_gpio, 1);
+	}
+
 	snd_soc_write(codec, AIC32X4_RESET, 0x01);
 
 	/* Power platform configuration */
@@ -675,6 +687,16 @@
 			     ARRAY_SIZE(aic32x4_snd_controls));
 	aic32x4_add_widgets(codec);
 
+	/*
+	 * Workaround: for an unknown reason, the ADC needs to be powered up
+	 * and down for the first capture to work properly. It seems related to
+	 * a HW BUG or some kind of behavior not documented in the datasheet.
+	 */
+	tmp_reg = snd_soc_read(codec, AIC32X4_ADCSETUP);
+	snd_soc_write(codec, AIC32X4_ADCSETUP, tmp_reg |
+				AIC32X4_LADC_EN | AIC32X4_RADC_EN);
+	snd_soc_write(codec, AIC32X4_ADCSETUP, tmp_reg);
+
 	return 0;
 }
 
@@ -694,8 +716,8 @@
 	.set_bias_level = aic32x4_set_bias_level,
 };
 
-static __devinit int aic32x4_i2c_probe(struct i2c_client *i2c,
-				      const struct i2c_device_id *id)
+static int aic32x4_i2c_probe(struct i2c_client *i2c,
+			     const struct i2c_device_id *id)
 {
 	struct aic32x4_pdata *pdata = i2c->dev.platform_data;
 	struct aic32x4_priv *aic32x4;
@@ -713,10 +735,12 @@
 		aic32x4->power_cfg = pdata->power_cfg;
 		aic32x4->swapdacs = pdata->swapdacs;
 		aic32x4->micpga_routing = pdata->micpga_routing;
+		aic32x4->rstn_gpio = pdata->rstn_gpio;
 	} else {
 		aic32x4->power_cfg = 0;
 		aic32x4->swapdacs = false;
 		aic32x4->micpga_routing = 0;
+		aic32x4->rstn_gpio = -1;
 	}
 
 	ret = snd_soc_register_codec(&i2c->dev,
@@ -724,7 +748,7 @@
 	return ret;
 }
 
-static __devexit int aic32x4_i2c_remove(struct i2c_client *client)
+static int aic32x4_i2c_remove(struct i2c_client *client)
 {
 	snd_soc_unregister_codec(&client->dev);
 	return 0;
@@ -742,7 +766,7 @@
 		.owner = THIS_MODULE,
 	},
 	.probe =    aic32x4_i2c_probe,
-	.remove =   __devexit_p(aic32x4_i2c_remove),
+	.remove =   aic32x4_i2c_remove,
 	.id_table = aic32x4_i2c_id,
 };
 
diff --git a/sound/soc/codecs/tlv320aic32x4.h b/sound/soc/codecs/tlv320aic32x4.h
index aae2b24..3577422 100644
--- a/sound/soc/codecs/tlv320aic32x4.h
+++ b/sound/soc/codecs/tlv320aic32x4.h
@@ -94,6 +94,9 @@
 #define AIC32X4_WORD_LEN_24BITS		0x02
 #define AIC32X4_WORD_LEN_32BITS		0x03
 
+#define AIC32X4_LADC_EN			(1 << 7)
+#define AIC32X4_RADC_EN			(1 << 6)
+
 #define AIC32X4_I2S_MODE		0x00
 #define AIC32X4_DSP_MODE		0x01
 #define AIC32X4_RIGHT_JUSTIFIED_MODE	0x02
diff --git a/sound/soc/codecs/tlv320dac33.c b/sound/soc/codecs/tlv320dac33.c
index d2e16c5..782b0cd 100644
--- a/sound/soc/codecs/tlv320dac33.c
+++ b/sound/soc/codecs/tlv320dac33.c
@@ -1514,8 +1514,8 @@
 	.ops = &dac33_dai_ops,
 };
 
-static int __devinit dac33_i2c_probe(struct i2c_client *client,
-				     const struct i2c_device_id *id)
+static int dac33_i2c_probe(struct i2c_client *client,
+			   const struct i2c_device_id *id)
 {
 	struct tlv320dac33_platform_data *pdata;
 	struct tlv320dac33_priv *dac33;
@@ -1586,7 +1586,7 @@
 	return ret;
 }
 
-static int __devexit dac33_i2c_remove(struct i2c_client *client)
+static int dac33_i2c_remove(struct i2c_client *client)
 {
 	struct tlv320dac33_priv *dac33 = i2c_get_clientdata(client);
 
@@ -1617,7 +1617,7 @@
 		.owner = THIS_MODULE,
 	},
 	.probe		= dac33_i2c_probe,
-	.remove		= __devexit_p(dac33_i2c_remove),
+	.remove		= dac33_i2c_remove,
 	.id_table	= tlv320dac33_i2c_id,
 };
 
diff --git a/sound/soc/codecs/tpa6130a2.c b/sound/soc/codecs/tpa6130a2.c
index 565ff39..8d75aa1 100644
--- a/sound/soc/codecs/tpa6130a2.c
+++ b/sound/soc/codecs/tpa6130a2.c
@@ -359,8 +359,8 @@
 }
 EXPORT_SYMBOL_GPL(tpa6130a2_add_controls);
 
-static int __devinit tpa6130a2_probe(struct i2c_client *client,
-				     const struct i2c_device_id *id)
+static int tpa6130a2_probe(struct i2c_client *client,
+			   const struct i2c_device_id *id)
 {
 	struct device *dev;
 	struct tpa6130a2_data *data;
@@ -455,7 +455,7 @@
 	return ret;
 }
 
-static int __devexit tpa6130a2_remove(struct i2c_client *client)
+static int tpa6130a2_remove(struct i2c_client *client)
 {
 	struct tpa6130a2_data *data = i2c_get_clientdata(client);
 
@@ -483,7 +483,7 @@
 		.owner = THIS_MODULE,
 	},
 	.probe = tpa6130a2_probe,
-	.remove = __devexit_p(tpa6130a2_remove),
+	.remove = tpa6130a2_remove,
 	.id_table = tpa6130a2_id,
 };
 
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c
index e7f6089..63b280b 100644
--- a/sound/soc/codecs/twl4030.c
+++ b/sound/soc/codecs/twl4030.c
@@ -2334,13 +2334,13 @@
 	.num_dapm_routes = ARRAY_SIZE(intercon),
 };
 
-static int __devinit twl4030_codec_probe(struct platform_device *pdev)
+static int twl4030_codec_probe(struct platform_device *pdev)
 {
 	return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_twl4030,
 			twl4030_dai, ARRAY_SIZE(twl4030_dai));
 }
 
-static int __devexit twl4030_codec_remove(struct platform_device *pdev)
+static int twl4030_codec_remove(struct platform_device *pdev)
 {
 	snd_soc_unregister_codec(&pdev->dev);
 	return 0;
@@ -2350,7 +2350,7 @@
 
 static struct platform_driver twl4030_codec_driver = {
 	.probe		= twl4030_codec_probe,
-	.remove		= __devexit_p(twl4030_codec_remove),
+	.remove		= twl4030_codec_remove,
 	.driver		= {
 		.name	= "twl4030-codec",
 		.owner	= THIS_MODULE,
diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c
index 00b85cc..3fc3fc6 100644
--- a/sound/soc/codecs/twl6040.c
+++ b/sound/soc/codecs/twl6040.c
@@ -1229,13 +1229,13 @@
 	.num_dapm_routes = ARRAY_SIZE(intercon),
 };
 
-static int __devinit twl6040_codec_probe(struct platform_device *pdev)
+static int twl6040_codec_probe(struct platform_device *pdev)
 {
 	return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_twl6040,
 				      twl6040_dai, ARRAY_SIZE(twl6040_dai));
 }
 
-static int __devexit twl6040_codec_remove(struct platform_device *pdev)
+static int twl6040_codec_remove(struct platform_device *pdev)
 {
 	snd_soc_unregister_codec(&pdev->dev);
 	return 0;
@@ -1247,7 +1247,7 @@
 		.owner = THIS_MODULE,
 	},
 	.probe = twl6040_codec_probe,
-	.remove = __devexit_p(twl6040_codec_remove),
+	.remove = twl6040_codec_remove,
 };
 
 module_platform_driver(twl6040_codec_driver);
diff --git a/sound/soc/codecs/uda134x.c b/sound/soc/codecs/uda134x.c
index 6c3d43b..6d0aa44 100644
--- a/sound/soc/codecs/uda134x.c
+++ b/sound/soc/codecs/uda134x.c
@@ -601,13 +601,13 @@
 	.set_bias_level = uda134x_set_bias_level,
 };
 
-static int __devinit uda134x_codec_probe(struct platform_device *pdev)
+static int uda134x_codec_probe(struct platform_device *pdev)
 {
 	return snd_soc_register_codec(&pdev->dev,
 			&soc_codec_dev_uda134x, &uda134x_dai, 1);
 }
 
-static int __devexit uda134x_codec_remove(struct platform_device *pdev)
+static int uda134x_codec_remove(struct platform_device *pdev)
 {
 	snd_soc_unregister_codec(&pdev->dev);
 	return 0;
@@ -619,7 +619,7 @@
 		.owner = THIS_MODULE,
 	},
 	.probe = uda134x_codec_probe,
-	.remove = __devexit_p(uda134x_codec_remove),
+	.remove = uda134x_codec_remove,
 };
 
 module_platform_driver(uda134x_codec_driver);
diff --git a/sound/soc/codecs/uda1380.c b/sound/soc/codecs/uda1380.c
index 2502214..fd0a314 100644
--- a/sound/soc/codecs/uda1380.c
+++ b/sound/soc/codecs/uda1380.c
@@ -795,8 +795,8 @@
 };
 
 #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
-static __devinit int uda1380_i2c_probe(struct i2c_client *i2c,
-				      const struct i2c_device_id *id)
+static int uda1380_i2c_probe(struct i2c_client *i2c,
+			     const struct i2c_device_id *id)
 {
 	struct uda1380_priv *uda1380;
 	int ret;
@@ -814,7 +814,7 @@
 	return ret;
 }
 
-static int __devexit uda1380_i2c_remove(struct i2c_client *i2c)
+static int uda1380_i2c_remove(struct i2c_client *i2c)
 {
 	snd_soc_unregister_codec(&i2c->dev);
 	return 0;
@@ -832,7 +832,7 @@
 		.owner = THIS_MODULE,
 	},
 	.probe =    uda1380_i2c_probe,
-	.remove =   __devexit_p(uda1380_i2c_remove),
+	.remove =   uda1380_i2c_remove,
 	.id_table = uda1380_i2c_id,
 };
 #endif
diff --git a/sound/soc/codecs/wl1273.c b/sound/soc/codecs/wl1273.c
index 7b24d6d..54cd3da 100644
--- a/sound/soc/codecs/wl1273.c
+++ b/sound/soc/codecs/wl1273.c
@@ -485,13 +485,13 @@
 	.remove = wl1273_remove,
 };
 
-static int __devinit wl1273_platform_probe(struct platform_device *pdev)
+static int wl1273_platform_probe(struct platform_device *pdev)
 {
 	return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_wl1273,
 				      &wl1273_dai, 1);
 }
 
-static int __devexit wl1273_platform_remove(struct platform_device *pdev)
+static int wl1273_platform_remove(struct platform_device *pdev)
 {
 	snd_soc_unregister_codec(&pdev->dev);
 	return 0;
@@ -505,7 +505,7 @@
 		.owner	= THIS_MODULE,
 	},
 	.probe		= wl1273_platform_probe,
-	.remove		= __devexit_p(wl1273_platform_remove),
+	.remove		= wl1273_platform_remove,
 };
 
 module_platform_driver(wl1273_platform_driver);
diff --git a/sound/soc/codecs/wm0010.c b/sound/soc/codecs/wm0010.c
index 99afc00..ad2fee4 100644
--- a/sound/soc/codecs/wm0010.c
+++ b/sound/soc/codecs/wm0010.c
@@ -31,6 +31,9 @@
 
 #define DEVICE_ID_WM0010	10
 
+/* We only support v1 of the .dfw INFO record */
+#define INFO_VERSION		1
+
 enum dfw_cmd {
 	DFW_CMD_FUSE = 0x01,
 	DFW_CMD_CODE_HDR,
@@ -46,6 +49,13 @@
 	uint8_t data[0];
 } __packed;
 
+struct dfw_inforec {
+	u8 info_version;
+	u8 tool_major_version;
+	u8 tool_minor_version;
+	u8 dsp_target;
+};
+
 struct dfw_pllrec {
 	u8 command;
 	u32 length:24;
@@ -97,7 +107,6 @@
 
 	enum wm0010_state state;
 	bool boot_failed;
-	int boot_done;
 	bool ready;
 	bool pll_running;
 	int max_spi_freq;
@@ -234,7 +243,7 @@
 			break;
 
 		case 0x55555555:
-			if (wm0010->boot_done == 0)
+			if (wm0010->state < WM0010_STAGE2)
 				break;
 			dev_err(codec->dev,
 				"%d: ROM bootloader running in stage 2\n", i);
@@ -321,7 +330,6 @@
 			break;
 	}
 
-	wm0010->boot_done++;
 	if (xfer->done)
 		complete(xfer->done);
 }
@@ -334,24 +342,253 @@
 		data_out[i] = cpu_to_be64(le64_to_cpu(data_in[i]));
 }
 
-static int wm0010_boot(struct snd_soc_codec *codec)
+static int wm0010_firmware_load(char *name, struct snd_soc_codec *codec)
 {
 	struct spi_device *spi = to_spi_device(codec->dev);
 	struct wm0010_priv *wm0010 = snd_soc_codec_get_drvdata(codec);
-	unsigned long flags;
 	struct list_head xfer_list;
 	struct wm0010_boot_xfer *xfer;
 	int ret;
 	struct completion done;
 	const struct firmware *fw;
 	const struct dfw_binrec *rec;
+	const struct dfw_inforec *inforec;
+	u64 *img;
+	u8 *out, dsp;
+	u32 len, offset;
+
+	INIT_LIST_HEAD(&xfer_list);
+
+	ret = request_firmware(&fw, name, codec->dev);
+	if (ret != 0) {
+		dev_err(codec->dev, "Failed to request application: %d\n",
+			ret);
+		return ret;
+	}
+
+	rec = (const struct dfw_binrec *)fw->data;
+	inforec = (const struct dfw_inforec *)rec->data;
+	offset = 0;
+	dsp = inforec->dsp_target;
+	wm0010->boot_failed = false;
+	BUG_ON(!list_empty(&xfer_list));
+	init_completion(&done);
+
+	/* First record should be INFO */
+	if (rec->command != DFW_CMD_INFO) {
+		dev_err(codec->dev, "First record not INFO\r\n");
+		ret = -EINVAL;
+		goto abort;
+	}
+
+	if (inforec->info_version != INFO_VERSION) {
+		dev_err(codec->dev,
+			"Unsupported version (%02d) of INFO record\r\n",
+			inforec->info_version);
+		ret = -EINVAL;
+		goto abort;
+	}
+
+	dev_dbg(codec->dev, "Version v%02d INFO record found\r\n",
+		inforec->info_version);
+
+	/* Check it's a DSP file */
+	if (dsp != DEVICE_ID_WM0010) {
+		dev_err(codec->dev, "Not a WM0010 firmware file.\r\n");
+		ret = -EINVAL;
+		goto abort;
+	}
+
+	/* Skip the info record as we don't need to send it */
+	offset += ((rec->length) + 8);
+	rec = (void *)&rec->data[rec->length];
+
+	while (offset < fw->size) {
+		dev_dbg(codec->dev,
+			"Packet: command %d, data length = 0x%x\r\n",
+			rec->command, rec->length);
+		len = rec->length + 8;
+
+		out = kzalloc(len, GFP_KERNEL);
+		if (!out) {
+			dev_err(codec->dev,
+				"Failed to allocate RX buffer\n");
+			ret = -ENOMEM;
+			goto abort1;
+		}
+
+		img = kzalloc(len, GFP_KERNEL);
+		if (!img) {
+			dev_err(codec->dev,
+				"Failed to allocate image buffer\n");
+			ret = -ENOMEM;
+			goto abort1;
+		}
+
+		byte_swap_64((u64 *)&rec->command, img, len);
+
+		xfer = kzalloc(sizeof(*xfer), GFP_KERNEL);
+		if (!xfer) {
+			dev_err(codec->dev, "Failed to allocate xfer\n");
+			ret = -ENOMEM;
+			goto abort1;
+		}
+
+		xfer->codec = codec;
+		list_add_tail(&xfer->list, &xfer_list);
+
+		spi_message_init(&xfer->m);
+		xfer->m.complete = wm0010_boot_xfer_complete;
+		xfer->m.context = xfer;
+		xfer->t.tx_buf = img;
+		xfer->t.rx_buf = out;
+		xfer->t.len = len;
+		xfer->t.bits_per_word = 8;
+
+		if (!wm0010->pll_running) {
+			xfer->t.speed_hz = wm0010->sysclk / 6;
+		} else {
+			xfer->t.speed_hz = wm0010->max_spi_freq;
+
+			if (wm0010->board_max_spi_speed &&
+			   (wm0010->board_max_spi_speed < wm0010->max_spi_freq))
+					xfer->t.speed_hz = wm0010->board_max_spi_speed;
+		}
+
+		/* Store max usable spi frequency for later use */
+		wm0010->max_spi_freq = xfer->t.speed_hz;
+
+		spi_message_add_tail(&xfer->t, &xfer->m);
+
+		offset += ((rec->length) + 8);
+		rec = (void *)&rec->data[rec->length];
+
+		if (offset >= fw->size) {
+			dev_dbg(codec->dev, "All transfers scheduled\n");
+			xfer->done = &done;
+		}
+
+		ret = spi_async(spi, &xfer->m);
+		if (ret != 0) {
+			dev_err(codec->dev, "Write failed: %d\n", ret);
+			goto abort1;
+		}
+
+		if (wm0010->boot_failed) {
+			dev_dbg(codec->dev, "Boot fail!\n");
+			ret = -EINVAL;
+			goto abort1;
+		}
+	}
+
+	wait_for_completion(&done);
+
+	ret = 0;
+
+abort1:
+	while (!list_empty(&xfer_list)) {
+		xfer = list_first_entry(&xfer_list, struct wm0010_boot_xfer,
+					list);
+		kfree(xfer->t.rx_buf);
+		kfree(xfer->t.tx_buf);
+		list_del(&xfer->list);
+		kfree(xfer);
+	}
+
+abort:
+	release_firmware(fw);
+	return ret;
+}
+
+static int wm0010_stage2_load(struct snd_soc_codec *codec)
+{
+	struct spi_device *spi = to_spi_device(codec->dev);
+	struct wm0010_priv *wm0010 = snd_soc_codec_get_drvdata(codec);
+	const struct firmware *fw;
+	struct spi_message m;
+	struct spi_transfer t;
+	u32 *img;
+	u8 *out;
+	int i;
+	int ret = 0;
+
+	ret = request_firmware(&fw, "wm0010_stage2.bin", codec->dev);
+	if (ret != 0) {
+		dev_err(codec->dev, "Failed to request stage2 loader: %d\n",
+			ret);
+		return ret;
+	}
+
+	dev_dbg(codec->dev, "Downloading %zu byte stage 2 loader\n", fw->size);
+
+	/* Copy to local buffer first as vmalloc causes problems for dma */
+	img = kzalloc(fw->size, GFP_KERNEL);
+	if (!img) {
+		dev_err(codec->dev, "Failed to allocate image buffer\n");
+		ret = -ENOMEM;
+		goto abort2;
+	}
+
+	out = kzalloc(fw->size, GFP_KERNEL);
+	if (!out) {
+		dev_err(codec->dev, "Failed to allocate output buffer\n");
+		ret = -ENOMEM;
+		goto abort1;
+	}
+
+	memcpy(img, &fw->data[0], fw->size);
+
+	spi_message_init(&m);
+	memset(&t, 0, sizeof(t));
+	t.rx_buf = out;
+	t.tx_buf = img;
+	t.len = fw->size;
+	t.bits_per_word = 8;
+	t.speed_hz = wm0010->sysclk / 10;
+	spi_message_add_tail(&t, &m);
+
+	dev_dbg(codec->dev, "Starting initial download at %dHz\n",
+		t.speed_hz);
+
+	ret = spi_sync(spi, &m);
+	if (ret != 0) {
+		dev_err(codec->dev, "Initial download failed: %d\n", ret);
+		goto abort;
+	}
+
+	/* Look for errors from the boot ROM */
+	for (i = 0; i < fw->size; i++) {
+		if (out[i] != 0x55) {
+			dev_err(codec->dev, "Boot ROM error: %x in %d\n",
+				out[i], i);
+			wm0010_mark_boot_failure(wm0010);
+			ret = -EBUSY;
+			goto abort;
+		}
+	}
+abort:
+	kfree(out);
+abort1:
+	kfree(img);
+abort2:
+	release_firmware(fw);
+
+	return ret;
+}
+
+static int wm0010_boot(struct snd_soc_codec *codec)
+{
+	struct spi_device *spi = to_spi_device(codec->dev);
+	struct wm0010_priv *wm0010 = snd_soc_codec_get_drvdata(codec);
+	unsigned long flags;
+	int ret;
+	const struct firmware *fw;
 	struct spi_message m;
 	struct spi_transfer t;
 	struct dfw_pllrec pll_rec;
-	u32 *img, *p;
+	u32 *p, len;
 	u64 *img_swap;
 	u8 *out;
-	u32 len, offset;
 	int i;
 
 	spin_lock_irqsave(&wm0010->irq_lock, flags);
@@ -365,8 +602,6 @@
 		goto err;
 	}
 
-	INIT_LIST_HEAD(&xfer_list);
-
 	mutex_lock(&wm0010->lock);
 	wm0010->pll_running = false;
 
@@ -402,65 +637,19 @@
 	}
 
 	if (!wait_for_completion_timeout(&wm0010->boot_completion,
-					 msecs_to_jiffies(10)))
+					 msecs_to_jiffies(20)))
 		dev_err(codec->dev, "Failed to get interrupt from DSP\n");
 
 	spin_lock_irqsave(&wm0010->irq_lock, flags);
 	wm0010->state = WM0010_BOOTROM;
 	spin_unlock_irqrestore(&wm0010->irq_lock, flags);
 
-	dev_dbg(codec->dev, "Downloading %zu byte stage 2 loader\n", fw->size);
-
-	/* Copy to local buffer first as vmalloc causes problems for dma */
-	img = kzalloc(fw->size, GFP_KERNEL);
-	if (!img) {
-		dev_err(codec->dev, "Failed to allocate image buffer\n");
+	ret = wm0010_stage2_load(codec);
+	if (ret)
 		goto abort;
-	}
-
-	out = kzalloc(fw->size, GFP_KERNEL);
-	if (!out) {
-		dev_err(codec->dev, "Failed to allocate output buffer\n");
-		goto abort;
-	}
-
-	memcpy(img, &fw->data[0], fw->size);
-
-	spi_message_init(&m);
-	memset(&t, 0, sizeof(t));
-	t.rx_buf = out;
-	t.tx_buf = img;
-	t.len = fw->size;
-	t.bits_per_word = 8;
-	t.speed_hz = wm0010->sysclk / 10;
-	spi_message_add_tail(&t, &m);
-
-	dev_dbg(codec->dev, "Starting initial download at %dHz\n",
-		t.speed_hz);
-
-	ret = spi_sync(spi, &m);
-	if (ret != 0) {
-		dev_err(codec->dev, "Initial download failed: %d\n", ret);
-		goto abort;
-	}
-
-	/* Look for errors from the boot ROM */
-	for (i = 0; i < fw->size; i++) {
-		if (out[i] != 0x55) {
-			ret = -EBUSY;
-			dev_err(codec->dev, "Boot ROM error: %x in %d\n",
-				out[i], i);
-			wm0010_mark_boot_failure(wm0010);
-			goto abort;
-		}
-	}
-
-	release_firmware(fw);
-	kfree(img);
-	kfree(out);
 
 	if (!wait_for_completion_timeout(&wm0010->boot_completion,
-					 msecs_to_jiffies(10)))
+					 msecs_to_jiffies(20)))
 		dev_err(codec->dev, "Failed to get interrupt from DSP loader.\n");
 
 	spin_lock_irqsave(&wm0010->irq_lock, flags);
@@ -535,110 +724,10 @@
 	} else
 		dev_dbg(codec->dev, "Not enabling DSP PLL.");
 
-	ret = request_firmware(&fw, "wm0010.dfw", codec->dev);
-	if (ret != 0) {
-		dev_err(codec->dev, "Failed to request application: %d\n",
-			ret);
+	ret = wm0010_firmware_load("wm0010.dfw", codec);
+
+	if (ret != 0)
 		goto abort;
-	}
-
-	rec = (const struct dfw_binrec *)fw->data;
-	offset = 0;
-	wm0010->boot_done = 0;
-	wm0010->boot_failed = false;
-	BUG_ON(!list_empty(&xfer_list));
-	init_completion(&done);
-
-	/* First record should be INFO */
-	if (rec->command != DFW_CMD_INFO) {
-		dev_err(codec->dev, "First record not INFO\r\n");
-		goto abort;
-	}
-
-	/* Check it's a 0010 file */
-	if (rec->data[0] != DEVICE_ID_WM0010) {
-		dev_err(codec->dev, "Not a WM0010 firmware file.\r\n");
-		goto abort;
-	}
-
-	/* Skip the info record as we don't need to send it */
-	offset += ((rec->length) + 8);
-	rec = (void *)&rec->data[rec->length];
-
-	while (offset < fw->size) {
-		dev_dbg(codec->dev,
-			"Packet: command %d, data length = 0x%x\r\n",
-			rec->command, rec->length);
-		len = rec->length + 8;
-
-		out = kzalloc(len, GFP_KERNEL);
-		if (!out) {
-			dev_err(codec->dev,
-				"Failed to allocate RX buffer\n");
-			goto abort;
-		}
-
-		img_swap = kzalloc(len, GFP_KERNEL);
-		if (!img_swap) {
-			dev_err(codec->dev,
-				"Failed to allocate image buffer\n");
-			goto abort;
-		}
-
-		/* We need to re-order for 0010 */
-		byte_swap_64((u64 *)&rec->command, img_swap, len);
-
-		xfer = kzalloc(sizeof(*xfer), GFP_KERNEL);
-		if (!xfer) {
-			dev_err(codec->dev, "Failed to allocate xfer\n");
-			goto abort;
-		}
-
-		xfer->codec = codec;
-		list_add_tail(&xfer->list, &xfer_list);
-
-		spi_message_init(&xfer->m);
-		xfer->m.complete = wm0010_boot_xfer_complete;
-		xfer->m.context = xfer;
-		xfer->t.tx_buf = img_swap;
-		xfer->t.rx_buf = out;
-		xfer->t.len = len;
-		xfer->t.bits_per_word = 8;
-
-		if (!wm0010->pll_running) {
-			xfer->t.speed_hz = wm0010->sysclk / 6;
-		} else {
-			xfer->t.speed_hz = wm0010->max_spi_freq;
-
-			if (wm0010->board_max_spi_speed &&
-			   (wm0010->board_max_spi_speed < wm0010->max_spi_freq))
-					xfer->t.speed_hz = wm0010->board_max_spi_speed;
-		}
-
-		/* Store max usable spi frequency for later use */
-		wm0010->max_spi_freq = xfer->t.speed_hz;
-
-		spi_message_add_tail(&xfer->t, &xfer->m);
-
-		offset += ((rec->length) + 8);
-		rec = (void *)&rec->data[rec->length];
-
-		if (offset >= fw->size) {
-			dev_dbg(codec->dev, "All transfers scheduled\n");
-			xfer->done = &done;
-		}
-
-		ret = spi_async(spi, &xfer->m);
-		if (ret != 0) {
-			dev_err(codec->dev, "Write failed: %d\n", ret);
-			goto abort;
-		}
-
-		if (wm0010->boot_failed)
-			goto abort;
-	}
-
-	wait_for_completion(&done);
 
 	spin_lock_irqsave(&wm0010->irq_lock, flags);
 	wm0010->state = WM0010_FIRMWARE;
@@ -646,17 +735,6 @@
 
 	mutex_unlock(&wm0010->lock);
 
-	release_firmware(fw);
-
-	while (!list_empty(&xfer_list)) {
-		xfer = list_first_entry(&xfer_list, struct wm0010_boot_xfer,
-					list);
-		kfree(xfer->t.rx_buf);
-		kfree(xfer->t.tx_buf);
-		list_del(&xfer->list);
-		kfree(xfer);
-	}
-
 	return 0;
 
 abort:
@@ -784,7 +862,6 @@
 	struct wm0010_priv *wm0010 = data;
 
 	switch (wm0010->state) {
-	case WM0010_POWER_OFF:
 	case WM0010_OUT_OF_RESET:
 	case WM0010_BOOTROM:
 	case WM0010_STAGE2:
@@ -808,7 +885,7 @@
 	return 0;
 }
 
-static int __devinit wm0010_spi_probe(struct spi_device *spi)
+static int wm0010_spi_probe(struct spi_device *spi)
 {
 	unsigned long gpio_flags;
 	int ret;
@@ -908,7 +985,7 @@
 	return 0;
 }
 
-static int __devexit wm0010_spi_remove(struct spi_device *spi)
+static int wm0010_spi_remove(struct spi_device *spi)
 {
 	struct wm0010_priv *wm0010 = spi_get_drvdata(spi);
 
@@ -930,7 +1007,7 @@
 		.owner	= THIS_MODULE,
 	},
 	.probe		= wm0010_spi_probe,
-	.remove		= __devexit_p(wm0010_spi_remove),
+	.remove		= wm0010_spi_remove,
 };
 
 module_spi_driver(wm0010_spi_driver);
diff --git a/sound/soc/codecs/wm1250-ev1.c b/sound/soc/codecs/wm1250-ev1.c
index 951d7b4..6e6b93d 100644
--- a/sound/soc/codecs/wm1250-ev1.c
+++ b/sound/soc/codecs/wm1250-ev1.c
@@ -153,7 +153,7 @@
 	.idle_bias_off = true,
 };
 
-static int __devinit wm1250_ev1_pdata(struct i2c_client *i2c)
+static int wm1250_ev1_pdata(struct i2c_client *i2c)
 {
 	struct wm1250_ev1_pdata *pdata = dev_get_platdata(&i2c->dev);
 	struct wm1250_priv *wm1250;
@@ -199,8 +199,8 @@
 		gpio_free_array(wm1250->gpios, ARRAY_SIZE(wm1250->gpios));
 }
 
-static int __devinit wm1250_ev1_probe(struct i2c_client *i2c,
-				      const struct i2c_device_id *i2c_id)
+static int wm1250_ev1_probe(struct i2c_client *i2c,
+			    const struct i2c_device_id *i2c_id)
 {
 	int id, board, rev, ret;
 
@@ -237,7 +237,7 @@
 	return 0;
 }
 
-static int __devexit wm1250_ev1_remove(struct i2c_client *i2c)
+static int wm1250_ev1_remove(struct i2c_client *i2c)
 {
 	snd_soc_unregister_codec(&i2c->dev);
 	wm1250_ev1_free(i2c);
@@ -257,7 +257,7 @@
 		.owner = THIS_MODULE,
 	},
 	.probe =    wm1250_ev1_probe,
-	.remove =   __devexit_p(wm1250_ev1_remove),
+	.remove =   wm1250_ev1_remove,
 	.id_table = wm1250_ev1_i2c_id,
 };
 
diff --git a/sound/soc/codecs/wm2000.c b/sound/soc/codecs/wm2000.c
index 683dc43..1cbe88f 100644
--- a/sound/soc/codecs/wm2000.c
+++ b/sound/soc/codecs/wm2000.c
@@ -646,7 +646,7 @@
 static int wm2000_anc_power_event(struct snd_soc_dapm_widget *w,
 				  struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+	struct snd_soc_codec *codec = w->codec;
 	struct wm2000_priv *wm2000 = dev_get_drvdata(codec->dev);
 
 	if (SND_SOC_DAPM_EVENT_ON(event))
@@ -764,8 +764,8 @@
 	.num_controls = ARRAY_SIZE(wm2000_controls),
 };
 
-static int __devinit wm2000_i2c_probe(struct i2c_client *i2c,
-				      const struct i2c_device_id *i2c_id)
+static int wm2000_i2c_probe(struct i2c_client *i2c,
+			    const struct i2c_device_id *i2c_id)
 {
 	struct wm2000_priv *wm2000;
 	struct wm2000_platform_data *pdata;
@@ -871,7 +871,7 @@
 	return ret;
 }
 
-static __devexit int wm2000_i2c_remove(struct i2c_client *i2c)
+static int wm2000_i2c_remove(struct i2c_client *i2c)
 {
 	snd_soc_unregister_codec(&i2c->dev);
 
@@ -890,7 +890,7 @@
 		.owner = THIS_MODULE,
 	},
 	.probe = wm2000_i2c_probe,
-	.remove = __devexit_p(wm2000_i2c_remove),
+	.remove = wm2000_i2c_remove,
 	.id_table = wm2000_i2c_id,
 };
 
diff --git a/sound/soc/codecs/wm2200.c b/sound/soc/codecs/wm2200.c
index eab64a1..afcf31d 100644
--- a/sound/soc/codecs/wm2200.c
+++ b/sound/soc/codecs/wm2200.c
@@ -15,6 +15,7 @@
 #include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/pm.h>
+#include <linux/firmware.h>
 #include <linux/gcd.h>
 #include <linux/gpio.h>
 #include <linux/i2c.h>
@@ -32,6 +33,40 @@
 #include <sound/wm2200.h>
 
 #include "wm2200.h"
+#include "wmfw.h"
+#include "wm_adsp.h"
+
+#define WM2200_DSP_CONTROL_1                   0x00
+#define WM2200_DSP_CONTROL_2                   0x02
+#define WM2200_DSP_CONTROL_3                   0x03
+#define WM2200_DSP_CONTROL_4                   0x04
+#define WM2200_DSP_CONTROL_5                   0x06
+#define WM2200_DSP_CONTROL_6                   0x07
+#define WM2200_DSP_CONTROL_7                   0x08
+#define WM2200_DSP_CONTROL_8                   0x09
+#define WM2200_DSP_CONTROL_9                   0x0A
+#define WM2200_DSP_CONTROL_10                  0x0B
+#define WM2200_DSP_CONTROL_11                  0x0C
+#define WM2200_DSP_CONTROL_12                  0x0D
+#define WM2200_DSP_CONTROL_13                  0x0F
+#define WM2200_DSP_CONTROL_14                  0x10
+#define WM2200_DSP_CONTROL_15                  0x11
+#define WM2200_DSP_CONTROL_16                  0x12
+#define WM2200_DSP_CONTROL_17                  0x13
+#define WM2200_DSP_CONTROL_18                  0x14
+#define WM2200_DSP_CONTROL_19                  0x16
+#define WM2200_DSP_CONTROL_20                  0x17
+#define WM2200_DSP_CONTROL_21                  0x18
+#define WM2200_DSP_CONTROL_22                  0x1A
+#define WM2200_DSP_CONTROL_23                  0x1B
+#define WM2200_DSP_CONTROL_24                  0x1C
+#define WM2200_DSP_CONTROL_25                  0x1E
+#define WM2200_DSP_CONTROL_26                  0x20
+#define WM2200_DSP_CONTROL_27                  0x21
+#define WM2200_DSP_CONTROL_28                  0x22
+#define WM2200_DSP_CONTROL_29                  0x23
+#define WM2200_DSP_CONTROL_30                  0x24
+#define WM2200_DSP_CONTROL_31                  0x26
 
 /* The code assumes DCVDD is generated internally */
 #define WM2200_NUM_CORE_SUPPLIES 2
@@ -49,6 +84,7 @@
 
 /* codec private data */
 struct wm2200_priv {
+	struct wm_adsp dsp[2];
 	struct regmap *regmap;
 	struct device *dev;
 	struct snd_soc_codec *codec;
@@ -64,6 +100,72 @@
 	int sysclk;
 };
 
+#define WM2200_DSP_RANGE_BASE (WM2200_MAX_REGISTER + 1)
+#define WM2200_DSP_SPACING 12288
+
+#define WM2200_DSP1_DM_BASE (WM2200_DSP_RANGE_BASE + (0 * WM2200_DSP_SPACING))
+#define WM2200_DSP1_PM_BASE (WM2200_DSP_RANGE_BASE + (1 * WM2200_DSP_SPACING))
+#define WM2200_DSP1_ZM_BASE (WM2200_DSP_RANGE_BASE + (2 * WM2200_DSP_SPACING))
+#define WM2200_DSP2_DM_BASE (WM2200_DSP_RANGE_BASE + (3 * WM2200_DSP_SPACING))
+#define WM2200_DSP2_PM_BASE (WM2200_DSP_RANGE_BASE + (4 * WM2200_DSP_SPACING))
+#define WM2200_DSP2_ZM_BASE (WM2200_DSP_RANGE_BASE + (5 * WM2200_DSP_SPACING))
+
+static const struct regmap_range_cfg wm2200_ranges[] = {
+	{ .name = "DSP1DM", .range_min = WM2200_DSP1_DM_BASE,
+	  .range_max = WM2200_DSP1_DM_BASE + 12287,
+	  .selector_reg = WM2200_DSP1_CONTROL_3,
+	  .selector_mask = WM2200_DSP1_PAGE_BASE_DM_0_MASK,
+	  .selector_shift = WM2200_DSP1_PAGE_BASE_DM_0_SHIFT,
+	  .window_start = WM2200_DSP1_DM_0, .window_len = 2048, },
+
+	{ .name = "DSP1PM", .range_min = WM2200_DSP1_PM_BASE,
+	  .range_max = WM2200_DSP1_PM_BASE + 12287,
+	  .selector_reg = WM2200_DSP1_CONTROL_2,
+	  .selector_mask = WM2200_DSP1_PAGE_BASE_PM_0_MASK,
+	  .selector_shift = WM2200_DSP1_PAGE_BASE_PM_0_SHIFT,
+	  .window_start = WM2200_DSP1_PM_0, .window_len = 768, },
+
+	{ .name = "DSP1ZM", .range_min = WM2200_DSP1_ZM_BASE,
+	  .range_max = WM2200_DSP1_ZM_BASE + 2047,
+	  .selector_reg = WM2200_DSP1_CONTROL_4,
+	  .selector_mask = WM2200_DSP1_PAGE_BASE_ZM_0_MASK,
+	  .selector_shift = WM2200_DSP1_PAGE_BASE_ZM_0_SHIFT,
+	  .window_start = WM2200_DSP1_ZM_0, .window_len = 1024, },
+
+	{ .name = "DSP2DM", .range_min = WM2200_DSP2_DM_BASE,
+	  .range_max = WM2200_DSP2_DM_BASE + 4095,
+	  .selector_reg = WM2200_DSP2_CONTROL_3,
+	  .selector_mask = WM2200_DSP2_PAGE_BASE_DM_0_MASK,
+	  .selector_shift = WM2200_DSP2_PAGE_BASE_DM_0_SHIFT,
+	  .window_start = WM2200_DSP2_DM_0, .window_len = 2048, },
+
+	{ .name = "DSP2PM", .range_min = WM2200_DSP2_PM_BASE,
+	  .range_max = WM2200_DSP2_PM_BASE + 11287,
+	  .selector_reg = WM2200_DSP2_CONTROL_2,
+	  .selector_mask = WM2200_DSP2_PAGE_BASE_PM_0_MASK,
+	  .selector_shift = WM2200_DSP2_PAGE_BASE_PM_0_SHIFT,
+	  .window_start = WM2200_DSP2_PM_0, .window_len = 768, },
+
+	{ .name = "DSP2ZM", .range_min = WM2200_DSP2_ZM_BASE,
+	  .range_max = WM2200_DSP2_ZM_BASE + 2047,
+	  .selector_reg = WM2200_DSP2_CONTROL_4,
+	  .selector_mask = WM2200_DSP2_PAGE_BASE_ZM_0_MASK,
+	  .selector_shift = WM2200_DSP2_PAGE_BASE_ZM_0_SHIFT,
+	  .window_start = WM2200_DSP2_ZM_0, .window_len = 1024, },
+};
+
+static const struct wm_adsp_region wm2200_dsp1_regions[] = {
+	{ .type = WMFW_ADSP1_PM, .base = WM2200_DSP1_PM_BASE },
+	{ .type = WMFW_ADSP1_DM, .base = WM2200_DSP1_DM_BASE },
+	{ .type = WMFW_ADSP1_ZM, .base = WM2200_DSP1_ZM_BASE },
+};
+
+static const struct wm_adsp_region wm2200_dsp2_regions[] = {
+	{ .type = WMFW_ADSP1_PM, .base = WM2200_DSP2_PM_BASE },
+	{ .type = WMFW_ADSP1_DM, .base = WM2200_DSP2_DM_BASE },
+	{ .type = WMFW_ADSP1_ZM, .base = WM2200_DSP2_ZM_BASE },
+};
+
 static struct reg_default wm2200_reg_defaults[] = {
 	{ 0x000B, 0x0000 },   /* R11    - Tone Generator 1 */
 	{ 0x0102, 0x0000 },   /* R258   - Clocking 3 */
@@ -407,6 +509,16 @@
 
 static bool wm2200_volatile_register(struct device *dev, unsigned int reg)
 {
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(wm2200_ranges); i++)
+		if ((reg >= wm2200_ranges[i].window_start &&
+		     reg <= wm2200_ranges[i].window_start +
+		     wm2200_ranges[i].window_len) ||
+		    (reg >= wm2200_ranges[i].range_min &&
+		     reg <= wm2200_ranges[i].range_max))
+			return true;
+
 	switch (reg) {
 	case WM2200_SOFTWARE_RESET:
 	case WM2200_DEVICE_REVISION:
@@ -423,6 +535,16 @@
 
 static bool wm2200_readable_register(struct device *dev, unsigned int reg)
 {
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(wm2200_ranges); i++)
+		if ((reg >= wm2200_ranges[i].window_start &&
+		     reg <= wm2200_ranges[i].window_start +
+		     wm2200_ranges[i].window_len) ||
+		    (reg >= wm2200_ranges[i].range_min &&
+		     reg <= wm2200_ranges[i].range_max))
+			return true;
+
 	switch (reg) {
 	case WM2200_SOFTWARE_RESET:
 	case WM2200_DEVICE_REVISION:
@@ -880,7 +1002,7 @@
 static const char *wm2200_mixer_texts[] = {
 	"None",
 	"Tone Generator",
-	"AEC loopback",
+	"AEC Loopback",
 	"IN1L",
 	"IN1R",
 	"IN2L",
@@ -976,6 +1098,20 @@
 	static WM2200_MUX_CTL_DECL(name##_in3); \
 	static WM2200_MUX_CTL_DECL(name##_in4)
 
+#define WM2200_DSP_ENUMS(name, base_reg) \
+	static WM2200_MUX_ENUM_DECL(name##_aux1_enum, base_reg);     \
+	static WM2200_MUX_ENUM_DECL(name##_aux2_enum, base_reg + 1); \
+	static WM2200_MUX_ENUM_DECL(name##_aux3_enum, base_reg + 2); \
+	static WM2200_MUX_ENUM_DECL(name##_aux4_enum, base_reg + 3); \
+	static WM2200_MUX_ENUM_DECL(name##_aux5_enum, base_reg + 4); \
+	static WM2200_MUX_ENUM_DECL(name##_aux6_enum, base_reg + 5); \
+	static WM2200_MUX_CTL_DECL(name##_aux1); \
+	static WM2200_MUX_CTL_DECL(name##_aux2); \
+	static WM2200_MUX_CTL_DECL(name##_aux3); \
+	static WM2200_MUX_CTL_DECL(name##_aux4); \
+	static WM2200_MUX_CTL_DECL(name##_aux5); \
+	static WM2200_MUX_CTL_DECL(name##_aux6);
+
 static const struct snd_kcontrol_new wm2200_snd_controls[] = {
 SOC_SINGLE("IN1 High Performance Switch", WM2200_IN1L_CONTROL,
 	   WM2200_IN1_OSR_SHIFT, 1, 0),
@@ -1051,6 +1187,9 @@
 WM2200_MIXER_ENUMS(DSP2L, WM2200_DSP2LMIX_INPUT_1_SOURCE);
 WM2200_MIXER_ENUMS(DSP2R, WM2200_DSP2RMIX_INPUT_1_SOURCE);
 
+WM2200_DSP_ENUMS(DSP1, WM2200_DSP1AUX1MIX_INPUT_1_SOURCE);
+WM2200_DSP_ENUMS(DSP2, WM2200_DSP2AUX1MIX_INPUT_1_SOURCE);
+
 WM2200_MIXER_ENUMS(LHPF1, WM2200_LHPF1MIX_INPUT_1_SOURCE);
 WM2200_MIXER_ENUMS(LHPF2, WM2200_LHPF2MIX_INPUT_1_SOURCE);
 
@@ -1064,8 +1203,19 @@
 	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_DSP_WIDGETS(name, name_str) \
+	WM2200_MIXER_WIDGETS(name##L, name_str "L"), \
+	WM2200_MIXER_WIDGETS(name##R, name_str "R"), \
+	WM2200_MUX(name_str " Aux 1", &name##_aux1_mux), \
+	WM2200_MUX(name_str " Aux 2", &name##_aux2_mux), \
+	WM2200_MUX(name_str " Aux 3", &name##_aux3_mux), \
+	WM2200_MUX(name_str " Aux 4", &name##_aux4_mux), \
+	WM2200_MUX(name_str " Aux 5", &name##_aux5_mux), \
+	WM2200_MUX(name_str " Aux 6", &name##_aux6_mux)
+
 #define WM2200_MIXER_INPUT_ROUTES(name)	\
 	{ name, "Tone Generator", "Tone Generator" }, \
+	{ name, "AEC Loopback", "AEC Loopback" }, \
         { name, "IN1L", "IN1L PGA" }, \
         { name, "IN1R", "IN1R PGA" }, \
         { name, "IN2L", "IN2L PGA" }, \
@@ -1106,6 +1256,33 @@
 	WM2200_MIXER_INPUT_ROUTES(name " Input 3"), \
 	WM2200_MIXER_INPUT_ROUTES(name " Input 4")
 
+#define WM2200_DSP_AUX_ROUTES(name) \
+	{ name, NULL, name " Aux 1" }, \
+	{ name, NULL, name " Aux 2" }, \
+	{ name, NULL, name " Aux 3" }, \
+	{ name, NULL, name " Aux 4" }, \
+	{ name, NULL, name " Aux 5" }, \
+	{ name, NULL, name " Aux 6" }, \
+	WM2200_MIXER_INPUT_ROUTES(name " Aux 1"), \
+	WM2200_MIXER_INPUT_ROUTES(name " Aux 2"), \
+	WM2200_MIXER_INPUT_ROUTES(name " Aux 3"), \
+	WM2200_MIXER_INPUT_ROUTES(name " Aux 4"), \
+	WM2200_MIXER_INPUT_ROUTES(name " Aux 5"), \
+	WM2200_MIXER_INPUT_ROUTES(name " Aux 6")
+
+static const char *wm2200_aec_loopback_texts[] = {
+	"OUT1L", "OUT1R", "OUT2L", "OUT2R",
+};
+
+static const struct soc_enum wm2200_aec_loopback =
+	SOC_ENUM_SINGLE(WM2200_DAC_AEC_CONTROL_1,
+			WM2200_AEC_LOOPBACK_SRC_SHIFT,
+			ARRAY_SIZE(wm2200_aec_loopback_texts),
+			wm2200_aec_loopback_texts);
+
+static const struct snd_kcontrol_new wm2200_aec_loopback_mux =
+	SOC_DAPM_ENUM("AEC Loopback", wm2200_aec_loopback);
+
 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),
@@ -1165,8 +1342,8 @@
 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),
+WM_ADSP1("DSP1", 0),
+WM_ADSP1("DSP2", 1),
 
 SND_SOC_DAPM_AIF_OUT("AIF1TX1", "Capture", 0,
 		    WM2200_AUDIO_IF_1_22, WM2200_AIF1TX1_ENA_SHIFT, 0),
@@ -1181,6 +1358,9 @@
 SND_SOC_DAPM_AIF_OUT("AIF1TX6", "Capture", 5,
 		    WM2200_AUDIO_IF_1_22, WM2200_AIF1TX6_ENA_SHIFT, 0),
 
+SND_SOC_DAPM_MUX("AEC Loopback", WM2200_DAC_AEC_CONTROL_1,
+		 WM2200_AEC_LOOPBACK_ENA_SHIFT, 0, &wm2200_aec_loopback_mux),
+
 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,
@@ -1231,10 +1411,8 @@
 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_DSP_WIDGETS(DSP1, "DSP1"),
+WM2200_DSP_WIDGETS(DSP2, "DSP2"),
 
 WM2200_MIXER_WIDGETS(AIF1TX1, "AIF1TX1"),
 WM2200_MIXER_WIDGETS(AIF1TX2, "AIF1TX2"),
@@ -1326,11 +1504,19 @@
 	{ "SPK", NULL, "OUT2L" },
 	{ "SPK", NULL, "OUT2R" },
 
+	{ "AEC Loopback", "OUT1L", "OUT1L" },
+	{ "AEC Loopback", "OUT1R", "OUT1R" },
+	{ "AEC Loopback", "OUT2L", "OUT2L" },
+	{ "AEC Loopback", "OUT2R", "OUT2R" },
+
 	WM2200_MIXER_ROUTES("DSP1", "DSP1L"),
 	WM2200_MIXER_ROUTES("DSP1", "DSP1R"),
 	WM2200_MIXER_ROUTES("DSP2", "DSP2L"),
 	WM2200_MIXER_ROUTES("DSP2", "DSP2R"),
 
+	WM2200_DSP_AUX_ROUTES("DSP1"),
+	WM2200_DSP_AUX_ROUTES("DSP2"),
+
 	WM2200_MIXER_ROUTES("OUT1L", "OUT1L"),
 	WM2200_MIXER_ROUTES("OUT1R", "OUT1R"),
 	WM2200_MIXER_ROUTES("OUT2L", "OUT2L"),
@@ -1968,12 +2154,15 @@
 	.reg_bits = 16,
 	.val_bits = 16,
 
-	.max_register = WM2200_MAX_REGISTER,
+	.max_register = WM2200_MAX_REGISTER + (ARRAY_SIZE(wm2200_ranges) *
+					       WM2200_DSP_SPACING),
 	.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,
+	.ranges = wm2200_ranges,
+	.num_ranges = ARRAY_SIZE(wm2200_ranges),
 };
 
 static const unsigned int wm2200_dig_vu[] = {
@@ -1995,8 +2184,8 @@
 	WM2200_IN3L_CONTROL,
 };
 
-static __devinit int wm2200_i2c_probe(struct i2c_client *i2c,
-				      const struct i2c_device_id *id)
+static 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;
@@ -2011,14 +2200,30 @@
 	wm2200->dev = &i2c->dev;
 	init_completion(&wm2200->fll_lock);
 
-	wm2200->regmap = regmap_init_i2c(i2c, &wm2200_regmap);
+	wm2200->regmap = devm_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;
+		return ret;
 	}
 
+	for (i = 0; i < 2; i++) {
+		wm2200->dsp[i].type = WMFW_ADSP1;
+		wm2200->dsp[i].part = "wm2200";
+		wm2200->dsp[i].num = i + 1;
+		wm2200->dsp[i].dev = &i2c->dev;
+		wm2200->dsp[i].regmap = wm2200->regmap;
+	}
+
+	wm2200->dsp[0].base = WM2200_DSP1_CONTROL_1;
+	wm2200->dsp[0].mem = wm2200_dsp1_regions;
+	wm2200->dsp[0].num_mems = ARRAY_SIZE(wm2200_dsp1_regions);
+
+	wm2200->dsp[1].base = WM2200_DSP2_CONTROL_1;
+	wm2200->dsp[1].mem = wm2200_dsp2_regions;
+	wm2200->dsp[1].num_mems = ARRAY_SIZE(wm2200_dsp2_regions);
+
 	if (pdata)
 		wm2200->pdata = *pdata;
 
@@ -2027,12 +2232,13 @@
 	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);
+	ret = devm_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;
+		return ret;
 	}
 
 	ret = regulator_bulk_enable(ARRAY_SIZE(wm2200->core_supplies),
@@ -2040,12 +2246,13 @@
 	if (ret != 0) {
 		dev_err(&i2c->dev, "Failed to enable core supplies: %d\n",
 			ret);
-		goto err_core;
+		return ret;
 	}
 
 	if (wm2200->pdata.ldo_ena) {
-		ret = gpio_request_one(wm2200->pdata.ldo_ena,
-				       GPIOF_OUT_INIT_HIGH, "WM2200 LDOENA");
+		ret = devm_gpio_request_one(&i2c->dev, 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);
@@ -2055,8 +2262,9 @@
 	}
 
 	if (wm2200->pdata.reset) {
-		ret = gpio_request_one(wm2200->pdata.reset,
-				       GPIOF_OUT_INIT_HIGH, "WM2200 /RESET");
+		ret = devm_gpio_request_one(&i2c->dev, 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);
@@ -2166,45 +2374,28 @@
 err_pm_runtime:
 	pm_runtime_disable(&i2c->dev);
 err_reset:
-	if (wm2200->pdata.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) {
+	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)
+static 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) {
+	if (wm2200->pdata.reset)
 		gpio_set_value_cansleep(wm2200->pdata.reset, 0);
-		gpio_free(wm2200->pdata.reset);
-	}
-	if (wm2200->pdata.ldo_ena) {
+	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;
 }
@@ -2267,7 +2458,7 @@
 		.pm = &wm2200_pm,
 	},
 	.probe =    wm2200_i2c_probe,
-	.remove =   __devexit_p(wm2200_i2c_remove),
+	.remove =   wm2200_i2c_remove,
 	.id_table = wm2200_i2c_id,
 };
 
diff --git a/sound/soc/codecs/wm5100.c b/sound/soc/codecs/wm5100.c
index 7f56758..5a5f369 100644
--- a/sound/soc/codecs/wm5100.c
+++ b/sound/soc/codecs/wm5100.c
@@ -1233,7 +1233,7 @@
 	{ "PWM2", NULL, "PWM2 Driver" },
 };
 
-static const __devinitconst struct reg_default wm5100_reva_patches[] = {
+static const struct reg_default wm5100_reva_patches[] = {
 	{ WM5100_AUDIO_IF_1_10, 0 },
 	{ WM5100_AUDIO_IF_1_11, 1 },
 	{ WM5100_AUDIO_IF_1_12, 2 },
@@ -2414,8 +2414,8 @@
 	WM5100_IN4L_CONTROL,
 };
 
-static __devinit int wm5100_i2c_probe(struct i2c_client *i2c,
-				      const struct i2c_device_id *id)
+static int wm5100_i2c_probe(struct i2c_client *i2c,
+			    const struct i2c_device_id *id)
 {
 	struct wm5100_pdata *pdata = dev_get_platdata(&i2c->dev);
 	struct wm5100_priv *wm5100;
@@ -2639,7 +2639,7 @@
 	return ret;
 }
 
-static __devexit int wm5100_i2c_remove(struct i2c_client *i2c)
+static int wm5100_i2c_remove(struct i2c_client *i2c)
 {
 	struct wm5100_priv *wm5100 = i2c_get_clientdata(i2c);
 
@@ -2717,7 +2717,7 @@
 		.pm = &wm5100_pm,
 	},
 	.probe =    wm5100_i2c_probe,
-	.remove =   __devexit_p(wm5100_i2c_remove),
+	.remove =   wm5100_i2c_remove,
 	.id_table = wm5100_i2c_id,
 };
 
diff --git a/sound/soc/codecs/wm5102.c b/sound/soc/codecs/wm5102.c
index 7394e73..688ade0 100644
--- a/sound/soc/codecs/wm5102.c
+++ b/sound/soc/codecs/wm5102.c
@@ -31,6 +31,7 @@
 
 #include "arizona.h"
 #include "wm5102.h"
+#include "wm_adsp.h"
 
 struct wm5102_priv {
 	struct arizona_priv core;
@@ -42,6 +43,13 @@
 static DECLARE_TLV_DB_SCALE(digital_tlv, -6400, 50, 0);
 static DECLARE_TLV_DB_SCALE(noise_tlv, 0, 600, 0);
 
+static const struct wm_adsp_region wm5102_dsp1_regions[] = {
+	{ .type = WMFW_ADSP2_PM, .base = 0x100000 },
+	{ .type = WMFW_ADSP2_ZM, .base = 0x180000 },
+	{ .type = WMFW_ADSP2_XM, .base = 0x190000 },
+	{ .type = WMFW_ADSP2_YM, .base = 0x1a8000 },
+};
+
 static const struct reg_default wm5102_sysclk_reva_patch[] = {
 	{ 0x3000, 0x2225 },
 	{ 0x3001, 0x3a03 },
@@ -627,11 +635,23 @@
 		 ARIZONA_ADC_DIGITAL_VOLUME_3R, ARIZONA_IN3L_DIG_VOL_SHIFT,
 		 0xbf, 0, digital_tlv),
 
+SOC_ENUM("Input Ramp Up", arizona_in_vi_ramp),
+SOC_ENUM("Input Ramp Down", arizona_in_vd_ramp),
+
 ARIZONA_MIXER_CONTROLS("EQ1", ARIZONA_EQ1MIX_INPUT_1_SOURCE),
 ARIZONA_MIXER_CONTROLS("EQ2", ARIZONA_EQ2MIX_INPUT_1_SOURCE),
 ARIZONA_MIXER_CONTROLS("EQ3", ARIZONA_EQ3MIX_INPUT_1_SOURCE),
 ARIZONA_MIXER_CONTROLS("EQ4", ARIZONA_EQ4MIX_INPUT_1_SOURCE),
 
+SND_SOC_BYTES_MASK("EQ1 Coefficeints", ARIZONA_EQ1_1, 21,
+		   ARIZONA_EQ1_ENA_MASK),
+SND_SOC_BYTES_MASK("EQ2 Coefficeints", ARIZONA_EQ2_1, 21,
+		   ARIZONA_EQ2_ENA_MASK),
+SND_SOC_BYTES_MASK("EQ3 Coefficeints", ARIZONA_EQ3_1, 21,
+		   ARIZONA_EQ3_ENA_MASK),
+SND_SOC_BYTES_MASK("EQ4 Coefficeints", ARIZONA_EQ4_1, 21,
+		   ARIZONA_EQ4_ENA_MASK),
+
 SOC_SINGLE_TLV("EQ1 B1 Volume", ARIZONA_EQ1_1, ARIZONA_EQ1_B1_GAIN_SHIFT,
 	       24, 0, eq_tlv),
 SOC_SINGLE_TLV("EQ1 B2 Volume", ARIZONA_EQ1_1, ARIZONA_EQ1_B2_GAIN_SHIFT,
@@ -687,6 +707,14 @@
 ARIZONA_MIXER_CONTROLS("LHPF3", ARIZONA_HPLP3MIX_INPUT_1_SOURCE),
 ARIZONA_MIXER_CONTROLS("LHPF4", ARIZONA_HPLP4MIX_INPUT_1_SOURCE),
 
+SND_SOC_BYTES("LHPF1 Coefficients", ARIZONA_HPLPF1_2, 1),
+SND_SOC_BYTES("LHPF2 Coefficients", ARIZONA_HPLPF2_2, 1),
+SND_SOC_BYTES("LHPF3 Coefficients", ARIZONA_HPLPF3_2, 1),
+SND_SOC_BYTES("LHPF4 Coefficients", ARIZONA_HPLPF4_2, 1),
+
+ARIZONA_MIXER_CONTROLS("DSP1L", ARIZONA_DSP1LMIX_INPUT_1_SOURCE),
+ARIZONA_MIXER_CONTROLS("DSP1R", ARIZONA_DSP1RMIX_INPUT_1_SOURCE),
+
 SOC_ENUM("LHPF1 Mode", arizona_lhpf1_mode),
 SOC_ENUM("LHPF2 Mode", arizona_lhpf2_mode),
 SOC_ENUM("LHPF3 Mode", arizona_lhpf3_mode),
@@ -708,14 +736,6 @@
 ARIZONA_MIXER_CONTROLS("SPKDAT1L", ARIZONA_OUT5LMIX_INPUT_1_SOURCE),
 ARIZONA_MIXER_CONTROLS("SPKDAT1R", ARIZONA_OUT5RMIX_INPUT_1_SOURCE),
 
-SOC_SINGLE("HPOUT1 High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_1L,
-	   ARIZONA_OUT1_OSR_SHIFT, 1, 0),
-SOC_SINGLE("OUT2 High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_2L,
-	   ARIZONA_OUT2_OSR_SHIFT, 1, 0),
-SOC_SINGLE("EPOUT High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_3L,
-	   ARIZONA_OUT3_OSR_SHIFT, 1, 0),
-SOC_SINGLE("Speaker High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_4L,
-	   ARIZONA_OUT4_OSR_SHIFT, 1, 0),
 SOC_SINGLE("SPKDAT1 High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_5L,
 	   ARIZONA_OUT5_OSR_SHIFT, 1, 0),
 
@@ -745,16 +765,8 @@
 		 ARIZONA_DAC_DIGITAL_VOLUME_5R, ARIZONA_OUT5L_VOL_SHIFT,
 		 0xbf, 0, digital_tlv),
 
-SOC_DOUBLE_R_RANGE_TLV("HPOUT1 Volume", ARIZONA_OUTPUT_PATH_CONFIG_1L,
-		       ARIZONA_OUTPUT_PATH_CONFIG_1R,
-		       ARIZONA_OUT1L_PGA_VOL_SHIFT,
-		       0x34, 0x40, 0, ana_tlv),
-SOC_DOUBLE_R_RANGE_TLV("OUT2 Volume", ARIZONA_OUTPUT_PATH_CONFIG_2L,
-		       ARIZONA_OUTPUT_PATH_CONFIG_2R,
-		       ARIZONA_OUT2L_PGA_VOL_SHIFT,
-		       0x34, 0x40, 0, ana_tlv),
-SOC_SINGLE_RANGE_TLV("EPOUT Volume", ARIZONA_OUTPUT_PATH_CONFIG_3L,
-		     ARIZONA_OUT3L_PGA_VOL_SHIFT, 0x34, 0x40, 0, ana_tlv),
+SOC_ENUM("Output Ramp Up", arizona_out_vi_ramp),
+SOC_ENUM("Output Ramp Down", arizona_out_vd_ramp),
 
 SOC_DOUBLE("SPKDAT1 Switch", ARIZONA_PDM_SPK1_CTRL_1, ARIZONA_SPK1L_MUTE_SHIFT,
 	   ARIZONA_SPK1R_MUTE_SHIFT, 1, 1),
@@ -819,11 +831,15 @@
 ARIZONA_MIXER_ENUMS(AIF3TX1, ARIZONA_AIF3TX1MIX_INPUT_1_SOURCE);
 ARIZONA_MIXER_ENUMS(AIF3TX2, ARIZONA_AIF3TX2MIX_INPUT_1_SOURCE);
 
-ARIZONA_MIXER_ENUMS(ASRC1L, ARIZONA_ASRC1LMIX_INPUT_1_SOURCE);
-ARIZONA_MIXER_ENUMS(ASRC1R, ARIZONA_ASRC1RMIX_INPUT_1_SOURCE);
-ARIZONA_MIXER_ENUMS(ASRC2L, ARIZONA_ASRC2LMIX_INPUT_1_SOURCE);
-ARIZONA_MIXER_ENUMS(ASRC2R, ARIZONA_ASRC2RMIX_INPUT_1_SOURCE);
+ARIZONA_MUX_ENUMS(ASRC1L, ARIZONA_ASRC1LMIX_INPUT_1_SOURCE);
+ARIZONA_MUX_ENUMS(ASRC1R, ARIZONA_ASRC1RMIX_INPUT_1_SOURCE);
+ARIZONA_MUX_ENUMS(ASRC2L, ARIZONA_ASRC2LMIX_INPUT_1_SOURCE);
+ARIZONA_MUX_ENUMS(ASRC2R, ARIZONA_ASRC2RMIX_INPUT_1_SOURCE);
 
+ARIZONA_MIXER_ENUMS(DSP1L, ARIZONA_DSP1LMIX_INPUT_1_SOURCE);
+ARIZONA_MIXER_ENUMS(DSP1R, ARIZONA_DSP1RMIX_INPUT_1_SOURCE);
+
+ARIZONA_DSP_AUX_ENUMS(DSP1, ARIZONA_DSP1AUX1MIX_INPUT_1_SOURCE);
 
 static const char *wm5102_aec_loopback_texts[] = {
 	"HPOUT1L", "HPOUT1R", "HPOUT2L", "HPOUT2R", "EPOUT",
@@ -864,6 +880,7 @@
 
 SND_SOC_DAPM_SIGGEN("TONE"),
 SND_SOC_DAPM_SIGGEN("NOISE"),
+SND_SOC_DAPM_SIGGEN("HAPTICS"),
 
 SND_SOC_DAPM_INPUT("IN1L"),
 SND_SOC_DAPM_INPUT("IN1R"),
@@ -894,9 +911,9 @@
 SND_SOC_DAPM_SUPPLY("MICBIAS1", ARIZONA_MIC_BIAS_CTRL_1,
 		    ARIZONA_MICB1_ENA_SHIFT, 0, NULL, 0),
 SND_SOC_DAPM_SUPPLY("MICBIAS2", ARIZONA_MIC_BIAS_CTRL_2,
-		    ARIZONA_MICB1_ENA_SHIFT, 0, NULL, 0),
+		    ARIZONA_MICB2_ENA_SHIFT, 0, NULL, 0),
 SND_SOC_DAPM_SUPPLY("MICBIAS3", ARIZONA_MIC_BIAS_CTRL_3,
-		    ARIZONA_MICB1_ENA_SHIFT, 0, NULL, 0),
+		    ARIZONA_MICB3_ENA_SHIFT, 0, NULL, 0),
 
 SND_SOC_DAPM_PGA("Noise Generator", ARIZONA_COMFORT_NOISE_GENERATOR,
 		 ARIZONA_NOISE_GEN_ENA_SHIFT, 0, NULL, 0),
@@ -996,6 +1013,8 @@
 SND_SOC_DAPM_AIF_IN("AIF3RX2", NULL, 0,
 		    ARIZONA_AIF3_RX_ENABLES, ARIZONA_AIF3RX2_ENA_SHIFT, 0),
 
+ARIZONA_DSP_WIDGETS(DSP1, "DSP1"),
+
 SND_SOC_DAPM_VALUE_MUX("AEC Loopback", ARIZONA_DAC_AEC_CONTROL_1,
 		       ARIZONA_AEC_LOOPBACK_ENA, 0, &wm5102_aec_loopback_mux),
 
@@ -1071,10 +1090,12 @@
 ARIZONA_MIXER_WIDGETS(AIF3TX1, "AIF3TX1"),
 ARIZONA_MIXER_WIDGETS(AIF3TX2, "AIF3TX2"),
 
-ARIZONA_MIXER_WIDGETS(ASRC1L, "ASRC1L"),
-ARIZONA_MIXER_WIDGETS(ASRC1R, "ASRC1R"),
-ARIZONA_MIXER_WIDGETS(ASRC2L, "ASRC2L"),
-ARIZONA_MIXER_WIDGETS(ASRC2R, "ASRC2R"),
+ARIZONA_MUX_WIDGETS(ASRC1L, "ASRC1L"),
+ARIZONA_MUX_WIDGETS(ASRC1R, "ASRC1R"),
+ARIZONA_MUX_WIDGETS(ASRC2L, "ASRC2L"),
+ARIZONA_MUX_WIDGETS(ASRC2R, "ASRC2R"),
+
+WM_ADSP2("DSP1", 0),
 
 SND_SOC_DAPM_OUTPUT("HPOUT1L"),
 SND_SOC_DAPM_OUTPUT("HPOUT1R"),
@@ -1094,6 +1115,7 @@
 	{ name, "Noise Generator", "Noise Generator" }, \
 	{ name, "Tone Generator 1", "Tone Generator 1" }, \
 	{ name, "Tone Generator 2", "Tone Generator 2" }, \
+	{ name, "Haptics", "HAPTICS" }, \
 	{ name, "AEC", "AEC Loopback" }, \
 	{ name, "IN1L", "IN1L PGA" }, \
 	{ name, "IN1R", "IN1R PGA" }, \
@@ -1127,7 +1149,13 @@
 	{ name, "ASRC1L", "ASRC1L" }, \
 	{ name, "ASRC1R", "ASRC1R" }, \
 	{ name, "ASRC2L", "ASRC2L" }, \
-	{ name, "ASRC2R", "ASRC2R" }
+	{ name, "ASRC2R", "ASRC2R" }, \
+	{ name, "DSP1.1", "DSP1" }, \
+	{ name, "DSP1.2", "DSP1" }, \
+	{ name, "DSP1.3", "DSP1" }, \
+	{ name, "DSP1.4", "DSP1" }, \
+	{ name, "DSP1.5", "DSP1" }, \
+	{ name, "DSP1.6", "DSP1" }
 
 static const struct snd_soc_dapm_route wm5102_dapm_routes[] = {
 	{ "AIF2 Capture", NULL, "DBVDD2" },
@@ -1213,6 +1241,11 @@
 	{ "IN3L PGA", NULL, "IN3L" },
 	{ "IN3R PGA", NULL, "IN3R" },
 
+	{ "ASRC1L", NULL, "ASRC1L Input" },
+	{ "ASRC1R", NULL, "ASRC1R Input" },
+	{ "ASRC2L", NULL, "ASRC2L Input" },
+	{ "ASRC2R", NULL, "ASRC2R Input" },
+
 	ARIZONA_MIXER_ROUTES("OUT1L", "HPOUT1L"),
 	ARIZONA_MIXER_ROUTES("OUT1R", "HPOUT1R"),
 	ARIZONA_MIXER_ROUTES("OUT2L", "HPOUT2L"),
@@ -1255,10 +1288,12 @@
 	ARIZONA_MIXER_ROUTES("LHPF3", "LHPF3"),
 	ARIZONA_MIXER_ROUTES("LHPF4", "LHPF4"),
 
-	ARIZONA_MIXER_ROUTES("ASRC1L", "ASRC1L"),
-	ARIZONA_MIXER_ROUTES("ASRC1R", "ASRC1R"),
-	ARIZONA_MIXER_ROUTES("ASRC2L", "ASRC2L"),
-	ARIZONA_MIXER_ROUTES("ASRC2R", "ASRC2R"),
+	ARIZONA_MUX_ROUTES("ASRC1L"),
+	ARIZONA_MUX_ROUTES("ASRC1R"),
+	ARIZONA_MUX_ROUTES("ASRC2L"),
+	ARIZONA_MUX_ROUTES("ASRC2R"),
+
+	ARIZONA_DSP_ROUTES("DSP1"),
 
 	{ "AEC Loopback", "HPOUT1L", "OUT1L" },
 	{ "AEC Loopback", "HPOUT1R", "OUT1R" },
@@ -1377,9 +1412,28 @@
 static int wm5102_codec_probe(struct snd_soc_codec *codec)
 {
 	struct wm5102_priv *priv = snd_soc_codec_get_drvdata(codec);
+	int ret;
 
 	codec->control_data = priv->core.arizona->regmap;
-	return snd_soc_codec_set_cache_io(codec, 32, 16, SND_SOC_REGMAP);
+
+	ret = snd_soc_codec_set_cache_io(codec, 32, 16, SND_SOC_REGMAP);
+	if (ret != 0)
+		return ret;
+
+	snd_soc_dapm_disable_pin(&codec->dapm, "HAPTICS");
+
+	priv->core.arizona->dapm = &codec->dapm;
+
+	return 0;
+}
+
+static int wm5102_codec_remove(struct snd_soc_codec *codec)
+{
+	struct wm5102_priv *priv = snd_soc_codec_get_drvdata(codec);
+
+	priv->core.arizona->dapm = NULL;
+
+	return 0;
 }
 
 #define WM5102_DIG_VU 0x0200
@@ -1406,6 +1460,7 @@
 
 static struct snd_soc_codec_driver soc_codec_dev_wm5102 = {
 	.probe = wm5102_codec_probe,
+	.remove = wm5102_codec_remove,
 
 	.idle_bias_off = true,
 
@@ -1420,11 +1475,11 @@
 	.num_dapm_routes = ARRAY_SIZE(wm5102_dapm_routes),
 };
 
-static int __devinit wm5102_probe(struct platform_device *pdev)
+static int wm5102_probe(struct platform_device *pdev)
 {
 	struct arizona *arizona = dev_get_drvdata(pdev->dev.parent);
 	struct wm5102_priv *wm5102;
-	int i;
+	int i, ret;
 
 	wm5102 = devm_kzalloc(&pdev->dev, sizeof(struct wm5102_priv),
 			      GFP_KERNEL);
@@ -1434,6 +1489,19 @@
 
 	wm5102->core.arizona = arizona;
 
+	wm5102->core.adsp[0].part = "wm5102";
+	wm5102->core.adsp[0].num = 1;
+	wm5102->core.adsp[0].type = WMFW_ADSP2;
+	wm5102->core.adsp[0].base = ARIZONA_DSP1_CONTROL_1;
+	wm5102->core.adsp[0].dev = arizona->dev;
+	wm5102->core.adsp[0].regmap = arizona->regmap;
+	wm5102->core.adsp[0].mem = wm5102_dsp1_regions;
+	wm5102->core.adsp[0].num_mems = ARRAY_SIZE(wm5102_dsp1_regions);
+
+	ret = wm_adsp2_init(&wm5102->core.adsp[0], true);
+	if (ret != 0)
+		return ret;
+
 	for (i = 0; i < ARRAY_SIZE(wm5102->fll); i++)
 		wm5102->fll[i].vco_mult = 1;
 
@@ -1459,7 +1527,7 @@
 				      wm5102_dai, ARRAY_SIZE(wm5102_dai));
 }
 
-static int __devexit wm5102_remove(struct platform_device *pdev)
+static int wm5102_remove(struct platform_device *pdev)
 {
 	snd_soc_unregister_codec(&pdev->dev);
 	pm_runtime_disable(&pdev->dev);
@@ -1473,7 +1541,7 @@
 		.owner = THIS_MODULE,
 	},
 	.probe = wm5102_probe,
-	.remove = __devexit_p(wm5102_remove),
+	.remove = wm5102_remove,
 };
 
 module_platform_driver(wm5102_codec_driver);
diff --git a/sound/soc/codecs/wm5110.c b/sound/soc/codecs/wm5110.c
index 9211e41..ae80c8c 100644
--- a/sound/soc/codecs/wm5110.c
+++ b/sound/soc/codecs/wm5110.c
@@ -84,11 +84,23 @@
 		 ARIZONA_ADC_DIGITAL_VOLUME_4R, ARIZONA_IN4L_DIG_VOL_SHIFT,
 		 0xbf, 0, digital_tlv),
 
+SOC_ENUM("Input Ramp Up", arizona_in_vi_ramp),
+SOC_ENUM("Input Ramp Down", arizona_in_vd_ramp),
+
 ARIZONA_MIXER_CONTROLS("EQ1", ARIZONA_EQ1MIX_INPUT_1_SOURCE),
 ARIZONA_MIXER_CONTROLS("EQ2", ARIZONA_EQ2MIX_INPUT_1_SOURCE),
 ARIZONA_MIXER_CONTROLS("EQ3", ARIZONA_EQ3MIX_INPUT_1_SOURCE),
 ARIZONA_MIXER_CONTROLS("EQ4", ARIZONA_EQ4MIX_INPUT_1_SOURCE),
 
+SND_SOC_BYTES_MASK("EQ1 Coefficeints", ARIZONA_EQ1_1, 21,
+		   ARIZONA_EQ1_ENA_MASK),
+SND_SOC_BYTES_MASK("EQ2 Coefficeints", ARIZONA_EQ2_1, 21,
+		   ARIZONA_EQ2_ENA_MASK),
+SND_SOC_BYTES_MASK("EQ3 Coefficeints", ARIZONA_EQ3_1, 21,
+		   ARIZONA_EQ3_ENA_MASK),
+SND_SOC_BYTES_MASK("EQ4 Coefficeints", ARIZONA_EQ4_1, 21,
+		   ARIZONA_EQ4_ENA_MASK),
+
 SOC_SINGLE_TLV("EQ1 B1 Volume", ARIZONA_EQ1_1, ARIZONA_EQ1_B1_GAIN_SHIFT,
 	       24, 0, eq_tlv),
 SOC_SINGLE_TLV("EQ1 B2 Volume", ARIZONA_EQ1_1, ARIZONA_EQ1_B2_GAIN_SHIFT,
@@ -148,6 +160,11 @@
 ARIZONA_MIXER_CONTROLS("LHPF3", ARIZONA_HPLP3MIX_INPUT_1_SOURCE),
 ARIZONA_MIXER_CONTROLS("LHPF4", ARIZONA_HPLP4MIX_INPUT_1_SOURCE),
 
+SND_SOC_BYTES("LHPF1 Coefficients", ARIZONA_HPLPF1_2, 1),
+SND_SOC_BYTES("LHPF2 Coefficients", ARIZONA_HPLPF2_2, 1),
+SND_SOC_BYTES("LHPF3 Coefficients", ARIZONA_HPLPF3_2, 1),
+SND_SOC_BYTES("LHPF4 Coefficients", ARIZONA_HPLPF4_2, 1),
+
 SOC_ENUM("LHPF1 Mode", arizona_lhpf1_mode),
 SOC_ENUM("LHPF2 Mode", arizona_lhpf2_mode),
 SOC_ENUM("LHPF3 Mode", arizona_lhpf3_mode),
@@ -243,6 +260,9 @@
 SOC_DOUBLE("SPKDAT2 Switch", ARIZONA_PDM_SPK2_CTRL_1, ARIZONA_SPK2L_MUTE_SHIFT,
 	   ARIZONA_SPK2R_MUTE_SHIFT, 1, 1),
 
+SOC_ENUM("Output Ramp Up", arizona_out_vi_ramp),
+SOC_ENUM("Output Ramp Down", arizona_out_vd_ramp),
+
 ARIZONA_MIXER_CONTROLS("AIF1TX1", ARIZONA_AIF1TX1MIX_INPUT_1_SOURCE),
 ARIZONA_MIXER_CONTROLS("AIF1TX2", ARIZONA_AIF1TX2MIX_INPUT_1_SOURCE),
 ARIZONA_MIXER_CONTROLS("AIF1TX3", ARIZONA_AIF1TX3MIX_INPUT_1_SOURCE),
@@ -308,10 +328,10 @@
 ARIZONA_MIXER_ENUMS(AIF3TX1, ARIZONA_AIF3TX1MIX_INPUT_1_SOURCE);
 ARIZONA_MIXER_ENUMS(AIF3TX2, ARIZONA_AIF3TX2MIX_INPUT_1_SOURCE);
 
-ARIZONA_MIXER_ENUMS(ASRC1L, ARIZONA_ASRC1LMIX_INPUT_1_SOURCE);
-ARIZONA_MIXER_ENUMS(ASRC1R, ARIZONA_ASRC1RMIX_INPUT_1_SOURCE);
-ARIZONA_MIXER_ENUMS(ASRC2L, ARIZONA_ASRC2LMIX_INPUT_1_SOURCE);
-ARIZONA_MIXER_ENUMS(ASRC2R, ARIZONA_ASRC2RMIX_INPUT_1_SOURCE);
+ARIZONA_MUX_ENUMS(ASRC1L, ARIZONA_ASRC1LMIX_INPUT_1_SOURCE);
+ARIZONA_MUX_ENUMS(ASRC1R, ARIZONA_ASRC1RMIX_INPUT_1_SOURCE);
+ARIZONA_MUX_ENUMS(ASRC2L, ARIZONA_ASRC2LMIX_INPUT_1_SOURCE);
+ARIZONA_MUX_ENUMS(ASRC2R, ARIZONA_ASRC2RMIX_INPUT_1_SOURCE);
 
 static const char *wm5110_aec_loopback_texts[] = {
 	"HPOUT1L", "HPOUT1R", "HPOUT2L", "HPOUT2R", "HPOUT3L", "HPOUT3R",
@@ -352,6 +372,7 @@
 
 SND_SOC_DAPM_SIGGEN("TONE"),
 SND_SOC_DAPM_SIGGEN("NOISE"),
+SND_SOC_DAPM_SIGGEN("HAPTICS"),
 
 SND_SOC_DAPM_INPUT("IN1L"),
 SND_SOC_DAPM_INPUT("IN1R"),
@@ -585,10 +606,10 @@
 ARIZONA_MIXER_WIDGETS(AIF3TX1, "AIF3TX1"),
 ARIZONA_MIXER_WIDGETS(AIF3TX2, "AIF3TX2"),
 
-ARIZONA_MIXER_WIDGETS(ASRC1L, "ASRC1L"),
-ARIZONA_MIXER_WIDGETS(ASRC1R, "ASRC1R"),
-ARIZONA_MIXER_WIDGETS(ASRC2L, "ASRC2L"),
-ARIZONA_MIXER_WIDGETS(ASRC2R, "ASRC2R"),
+ARIZONA_MUX_WIDGETS(ASRC1L, "ASRC1L"),
+ARIZONA_MUX_WIDGETS(ASRC1R, "ASRC1R"),
+ARIZONA_MUX_WIDGETS(ASRC2L, "ASRC2L"),
+ARIZONA_MUX_WIDGETS(ASRC2R, "ASRC2R"),
 
 SND_SOC_DAPM_OUTPUT("HPOUT1L"),
 SND_SOC_DAPM_OUTPUT("HPOUT1R"),
@@ -610,6 +631,7 @@
 	{ name, "Noise Generator", "Noise Generator" }, \
 	{ name, "Tone Generator 1", "Tone Generator 1" }, \
 	{ name, "Tone Generator 2", "Tone Generator 2" }, \
+	{ name, "Haptics", "HAPTICS" }, \
 	{ name, "AEC", "AEC Loopback" }, \
 	{ name, "IN1L", "IN1L PGA" }, \
 	{ name, "IN1R", "IN1R PGA" }, \
@@ -786,10 +808,10 @@
 	ARIZONA_MIXER_ROUTES("LHPF3", "LHPF3"),
 	ARIZONA_MIXER_ROUTES("LHPF4", "LHPF4"),
 
-	ARIZONA_MIXER_ROUTES("ASRC1L", "ASRC1L"),
-	ARIZONA_MIXER_ROUTES("ASRC1R", "ASRC1R"),
-	ARIZONA_MIXER_ROUTES("ASRC2L", "ASRC2L"),
-	ARIZONA_MIXER_ROUTES("ASRC2R", "ASRC2R"),
+	ARIZONA_MUX_ROUTES("ASRC1L"),
+	ARIZONA_MUX_ROUTES("ASRC1R"),
+	ARIZONA_MUX_ROUTES("ASRC2L"),
+	ARIZONA_MUX_ROUTES("ASRC2R"),
 
 	{ "HPOUT1L", NULL, "OUT1L" },
 	{ "HPOUT1R", NULL, "OUT1R" },
@@ -902,9 +924,29 @@
 static int wm5110_codec_probe(struct snd_soc_codec *codec)
 {
 	struct wm5110_priv *priv = snd_soc_codec_get_drvdata(codec);
+	int ret;
 
 	codec->control_data = priv->core.arizona->regmap;
-	return snd_soc_codec_set_cache_io(codec, 32, 16, SND_SOC_REGMAP);
+	priv->core.arizona->dapm = &codec->dapm;
+
+	ret = snd_soc_codec_set_cache_io(codec, 32, 16, SND_SOC_REGMAP);
+	if (ret != 0)
+		return ret;
+
+	snd_soc_dapm_disable_pin(&codec->dapm, "HAPTICS");
+
+	priv->core.arizona->dapm = &codec->dapm;
+
+	return 0;
+}
+
+static int wm5110_codec_remove(struct snd_soc_codec *codec)
+{
+	struct wm5110_priv *priv = snd_soc_codec_get_drvdata(codec);
+
+	priv->core.arizona->dapm = NULL;
+
+	return 0;
 }
 
 #define WM5110_DIG_VU 0x0200
@@ -935,6 +977,7 @@
 
 static struct snd_soc_codec_driver soc_codec_dev_wm5110 = {
 	.probe = wm5110_codec_probe,
+	.remove = wm5110_codec_remove,
 
 	.idle_bias_off = true,
 
@@ -949,7 +992,7 @@
 	.num_dapm_routes = ARRAY_SIZE(wm5110_dapm_routes),
 };
 
-static int __devinit wm5110_probe(struct platform_device *pdev)
+static int wm5110_probe(struct platform_device *pdev)
 {
 	struct arizona *arizona = dev_get_drvdata(pdev->dev.parent);
 	struct wm5110_priv *wm5110;
@@ -988,7 +1031,7 @@
 				      wm5110_dai, ARRAY_SIZE(wm5110_dai));
 }
 
-static int __devexit wm5110_remove(struct platform_device *pdev)
+static int wm5110_remove(struct platform_device *pdev)
 {
 	snd_soc_unregister_codec(&pdev->dev);
 	pm_runtime_disable(&pdev->dev);
@@ -1002,7 +1045,7 @@
 		.owner = THIS_MODULE,
 	},
 	.probe = wm5110_probe,
-	.remove = __devexit_p(wm5110_remove),
+	.remove = wm5110_remove,
 };
 
 module_platform_driver(wm5110_codec_driver);
diff --git a/sound/soc/codecs/wm8350.c b/sound/soc/codecs/wm8350.c
index a4cae06..fb92fb4 100644
--- a/sound/soc/codecs/wm8350.c
+++ b/sound/soc/codecs/wm8350.c
@@ -1500,7 +1500,7 @@
 	for (i = 0; i < ARRAY_SIZE(supply_names); i++)
 		priv->supplies[i].supply = supply_names[i];
 
-	ret = regulator_bulk_get(wm8350->dev, ARRAY_SIZE(priv->supplies),
+	ret = devm_regulator_bulk_get(wm8350->dev, ARRAY_SIZE(priv->supplies),
 				 priv->supplies);
 	if (ret != 0)
 		return ret;
@@ -1607,8 +1607,6 @@
 
 	wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_5, WM8350_CODEC_ENA);
 
-	regulator_bulk_free(ARRAY_SIZE(priv->supplies), priv->supplies);
-
 	return 0;
 }
 
@@ -1627,13 +1625,13 @@
 	.num_dapm_routes = ARRAY_SIZE(wm8350_dapm_routes),
 };
 
-static int __devinit wm8350_probe(struct platform_device *pdev)
+static int wm8350_probe(struct platform_device *pdev)
 {
 	return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_wm8350,
 			&wm8350_dai, 1);
 }
 
-static int __devexit wm8350_remove(struct platform_device *pdev)
+static int wm8350_remove(struct platform_device *pdev)
 {
 	snd_soc_unregister_codec(&pdev->dev);
 	return 0;
@@ -1645,7 +1643,7 @@
 		   .owner = THIS_MODULE,
 		   },
 	.probe = wm8350_probe,
-	.remove = __devexit_p(wm8350_remove),
+	.remove = wm8350_remove,
 };
 
 module_platform_driver(wm8350_codec_driver);
diff --git a/sound/soc/codecs/wm8400.c b/sound/soc/codecs/wm8400.c
index 5d277a9..af6d227 100644
--- a/sound/soc/codecs/wm8400.c
+++ b/sound/soc/codecs/wm8400.c
@@ -1373,7 +1373,7 @@
 	codec->control_data = priv->wm8400 = wm8400;
 	priv->codec = codec;
 
-	ret = regulator_bulk_get(wm8400->dev,
+	ret = devm_regulator_bulk_get(wm8400->dev,
 				 ARRAY_SIZE(power), &power[0]);
 	if (ret != 0) {
 		dev_err(codec->dev, "Failed to get regulators: %d\n", ret);
@@ -1398,15 +1398,9 @@
 	snd_soc_write(codec, WM8400_LEFT_OUTPUT_VOLUME, 0x50 | (1<<8));
 	snd_soc_write(codec, WM8400_RIGHT_OUTPUT_VOLUME, 0x50 | (1<<8));
 
-	if (!schedule_work(&priv->work)) {
-		ret = -EINVAL;
-		goto err_regulator;
-	}
+	if (!schedule_work(&priv->work))
+		return -EINVAL;
 	return 0;
-
-err_regulator:
-	regulator_bulk_free(ARRAY_SIZE(power), power);
-	return ret;
 }
 
 static int  wm8400_codec_remove(struct snd_soc_codec *codec)
@@ -1417,8 +1411,6 @@
 	snd_soc_write(codec, WM8400_POWER_MANAGEMENT_1,
 		     reg & (~WM8400_CODEC_ENA));
 
-	regulator_bulk_free(ARRAY_SIZE(power), power);
-
 	return 0;
 }
 
@@ -1439,13 +1431,13 @@
 	.num_dapm_routes = ARRAY_SIZE(wm8400_dapm_routes),
 };
 
-static int __devinit wm8400_probe(struct platform_device *pdev)
+static int wm8400_probe(struct platform_device *pdev)
 {
 	return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_wm8400,
 			&wm8400_dai, 1);
 }
 
-static int __devexit wm8400_remove(struct platform_device *pdev)
+static int wm8400_remove(struct platform_device *pdev)
 {
 	snd_soc_unregister_codec(&pdev->dev);
 	return 0;
@@ -1457,7 +1449,7 @@
 		   .owner = THIS_MODULE,
 		   },
 	.probe = wm8400_probe,
-	.remove = __devexit_p(wm8400_remove),
+	.remove = wm8400_remove,
 };
 
 module_platform_driver(wm8400_codec_driver);
diff --git a/sound/soc/codecs/wm8510.c b/sound/soc/codecs/wm8510.c
index c12a54e..6ed5433 100644
--- a/sound/soc/codecs/wm8510.c
+++ b/sound/soc/codecs/wm8510.c
@@ -608,10 +608,7 @@
 /* power down chip */
 static int wm8510_remove(struct snd_soc_codec *codec)
 {
-	struct wm8510_priv *wm8510 = snd_soc_codec_get_drvdata(codec);
-
 	wm8510_set_bias_level(codec, SND_SOC_BIAS_OFF);
-	kfree(wm8510);
 	return 0;
 }
 
@@ -648,7 +645,7 @@
 };
 
 #if defined(CONFIG_SPI_MASTER)
-static int __devinit wm8510_spi_probe(struct spi_device *spi)
+static int wm8510_spi_probe(struct spi_device *spi)
 {
 	struct wm8510_priv *wm8510;
 	int ret;
@@ -670,7 +667,7 @@
 	return ret;
 }
 
-static int __devexit wm8510_spi_remove(struct spi_device *spi)
+static int wm8510_spi_remove(struct spi_device *spi)
 {
 	snd_soc_unregister_codec(&spi->dev);
 	return 0;
@@ -683,13 +680,13 @@
 		.of_match_table = wm8510_of_match,
 	},
 	.probe		= wm8510_spi_probe,
-	.remove		= __devexit_p(wm8510_spi_remove),
+	.remove		= wm8510_spi_remove,
 };
 #endif /* CONFIG_SPI_MASTER */
 
 #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
-static __devinit int wm8510_i2c_probe(struct i2c_client *i2c,
-				      const struct i2c_device_id *id)
+static int wm8510_i2c_probe(struct i2c_client *i2c,
+			    const struct i2c_device_id *id)
 {
 	struct wm8510_priv *wm8510;
 	int ret;
@@ -711,7 +708,7 @@
 	return ret;
 }
 
-static __devexit int wm8510_i2c_remove(struct i2c_client *client)
+static int wm8510_i2c_remove(struct i2c_client *client)
 {
 	snd_soc_unregister_codec(&client->dev);
 	return 0;
@@ -730,7 +727,7 @@
 		.of_match_table = wm8510_of_match,
 	},
 	.probe =    wm8510_i2c_probe,
-	.remove =   __devexit_p(wm8510_i2c_remove),
+	.remove =   wm8510_i2c_remove,
 	.id_table = wm8510_i2c_id,
 };
 #endif
diff --git a/sound/soc/codecs/wm8523.c b/sound/soc/codecs/wm8523.c
index 8d5c276..139bf9a 100644
--- a/sound/soc/codecs/wm8523.c
+++ b/sound/soc/codecs/wm8523.c
@@ -453,8 +453,8 @@
 };
 
 #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
-static __devinit int wm8523_i2c_probe(struct i2c_client *i2c,
-				      const struct i2c_device_id *id)
+static int wm8523_i2c_probe(struct i2c_client *i2c,
+			    const struct i2c_device_id *id)
 {
 	struct wm8523_priv *wm8523;
 	unsigned int val;
@@ -528,7 +528,7 @@
 	return ret;
 }
 
-static __devexit int wm8523_i2c_remove(struct i2c_client *client)
+static int wm8523_i2c_remove(struct i2c_client *client)
 {
 	snd_soc_unregister_codec(&client->dev);
 	return 0;
@@ -547,7 +547,7 @@
 		.of_match_table = wm8523_of_match,
 	},
 	.probe =    wm8523_i2c_probe,
-	.remove =   __devexit_p(wm8523_i2c_remove),
+	.remove =   wm8523_i2c_remove,
 	.id_table = wm8523_i2c_id,
 };
 #endif
diff --git a/sound/soc/codecs/wm8711.c b/sound/soc/codecs/wm8711.c
index 8b8bb70..5b428b0 100644
--- a/sound/soc/codecs/wm8711.c
+++ b/sound/soc/codecs/wm8711.c
@@ -429,7 +429,7 @@
 };
 
 #if defined(CONFIG_SPI_MASTER)
-static int __devinit wm8711_spi_probe(struct spi_device *spi)
+static int wm8711_spi_probe(struct spi_device *spi)
 {
 	struct wm8711_priv *wm8711;
 	int ret;
@@ -451,7 +451,7 @@
 	return ret;
 }
 
-static int __devexit wm8711_spi_remove(struct spi_device *spi)
+static int wm8711_spi_remove(struct spi_device *spi)
 {
 	snd_soc_unregister_codec(&spi->dev);
 
@@ -465,13 +465,13 @@
 		.of_match_table = wm8711_of_match,
 	},
 	.probe		= wm8711_spi_probe,
-	.remove		= __devexit_p(wm8711_spi_remove),
+	.remove		= wm8711_spi_remove,
 };
 #endif /* CONFIG_SPI_MASTER */
 
 #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
-static __devinit int wm8711_i2c_probe(struct i2c_client *client,
-				      const struct i2c_device_id *id)
+static int wm8711_i2c_probe(struct i2c_client *client,
+			    const struct i2c_device_id *id)
 {
 	struct wm8711_priv *wm8711;
 	int ret;
@@ -493,7 +493,7 @@
 	return ret;
 }
 
-static __devexit int wm8711_i2c_remove(struct i2c_client *client)
+static int wm8711_i2c_remove(struct i2c_client *client)
 {
 	snd_soc_unregister_codec(&client->dev);
 	return 0;
@@ -512,7 +512,7 @@
 		.of_match_table = wm8711_of_match,
 	},
 	.probe =    wm8711_i2c_probe,
-	.remove =   __devexit_p(wm8711_i2c_remove),
+	.remove =   wm8711_i2c_remove,
 	.id_table = wm8711_i2c_id,
 };
 #endif
diff --git a/sound/soc/codecs/wm8727.c b/sound/soc/codecs/wm8727.c
index e817056..462f5e4 100644
--- a/sound/soc/codecs/wm8727.c
+++ b/sound/soc/codecs/wm8727.c
@@ -45,13 +45,13 @@
 
 static struct snd_soc_codec_driver soc_codec_dev_wm8727;
 
-static __devinit int wm8727_probe(struct platform_device *pdev)
+static int wm8727_probe(struct platform_device *pdev)
 {
 	return snd_soc_register_codec(&pdev->dev,
 			&soc_codec_dev_wm8727, &wm8727_dai, 1);
 }
 
-static int __devexit wm8727_remove(struct platform_device *pdev)
+static int wm8727_remove(struct platform_device *pdev)
 {
 	snd_soc_unregister_codec(&pdev->dev);
 	return 0;
@@ -64,7 +64,7 @@
 	},
 
 	.probe = wm8727_probe,
-	.remove = __devexit_p(wm8727_remove),
+	.remove = wm8727_remove,
 };
 
 module_platform_driver(wm8727_codec_driver);
diff --git a/sound/soc/codecs/wm8728.c b/sound/soc/codecs/wm8728.c
index 00a12a0..c6a292d 100644
--- a/sound/soc/codecs/wm8728.c
+++ b/sound/soc/codecs/wm8728.c
@@ -280,7 +280,7 @@
 };
 
 #if defined(CONFIG_SPI_MASTER)
-static int __devinit wm8728_spi_probe(struct spi_device *spi)
+static int wm8728_spi_probe(struct spi_device *spi)
 {
 	struct wm8728_priv *wm8728;
 	int ret;
@@ -302,7 +302,7 @@
 	return ret;
 }
 
-static int __devexit wm8728_spi_remove(struct spi_device *spi)
+static int wm8728_spi_remove(struct spi_device *spi)
 {
 	snd_soc_unregister_codec(&spi->dev);
 
@@ -316,13 +316,13 @@
 		.of_match_table = wm8728_of_match,
 	},
 	.probe		= wm8728_spi_probe,
-	.remove		= __devexit_p(wm8728_spi_remove),
+	.remove		= wm8728_spi_remove,
 };
 #endif /* CONFIG_SPI_MASTER */
 
 #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
-static __devinit int wm8728_i2c_probe(struct i2c_client *i2c,
-				      const struct i2c_device_id *id)
+static int wm8728_i2c_probe(struct i2c_client *i2c,
+			    const struct i2c_device_id *id)
 {
 	struct wm8728_priv *wm8728;
 	int ret;
@@ -344,7 +344,7 @@
 	return ret;
 }
 
-static __devexit int wm8728_i2c_remove(struct i2c_client *client)
+static int wm8728_i2c_remove(struct i2c_client *client)
 {
 	snd_soc_unregister_codec(&client->dev);
 	return 0;
@@ -363,7 +363,7 @@
 		.of_match_table = wm8728_of_match,
 	},
 	.probe =    wm8728_i2c_probe,
-	.remove =   __devexit_p(wm8728_i2c_remove),
+	.remove =   wm8728_i2c_remove,
 	.id_table = wm8728_i2c_id,
 };
 #endif
diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c
index bb1d269..5276062 100644
--- a/sound/soc/codecs/wm8731.c
+++ b/sound/soc/codecs/wm8731.c
@@ -631,7 +631,7 @@
 };
 
 #if defined(CONFIG_SPI_MASTER)
-static int __devinit wm8731_spi_probe(struct spi_device *spi)
+static int wm8731_spi_probe(struct spi_device *spi)
 {
 	struct wm8731_priv *wm8731;
 	int ret;
@@ -661,7 +661,7 @@
 	return 0;
 }
 
-static int __devexit wm8731_spi_remove(struct spi_device *spi)
+static int wm8731_spi_remove(struct spi_device *spi)
 {
 	snd_soc_unregister_codec(&spi->dev);
 	return 0;
@@ -674,13 +674,13 @@
 		.of_match_table = wm8731_of_match,
 	},
 	.probe		= wm8731_spi_probe,
-	.remove		= __devexit_p(wm8731_spi_remove),
+	.remove		= wm8731_spi_remove,
 };
 #endif /* CONFIG_SPI_MASTER */
 
 #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
-static __devinit int wm8731_i2c_probe(struct i2c_client *i2c,
-				      const struct i2c_device_id *id)
+static int wm8731_i2c_probe(struct i2c_client *i2c,
+			    const struct i2c_device_id *id)
 {
 	struct wm8731_priv *wm8731;
 	int ret;
@@ -710,7 +710,7 @@
 	return 0;
 }
 
-static __devexit int wm8731_i2c_remove(struct i2c_client *client)
+static int wm8731_i2c_remove(struct i2c_client *client)
 {
 	snd_soc_unregister_codec(&client->dev);
 	return 0;
@@ -729,7 +729,7 @@
 		.of_match_table = wm8731_of_match,
 	},
 	.probe =    wm8731_i2c_probe,
-	.remove =   __devexit_p(wm8731_i2c_remove),
+	.remove =   wm8731_i2c_remove,
 	.id_table = wm8731_i2c_id,
 };
 #endif
diff --git a/sound/soc/codecs/wm8737.c b/sound/soc/codecs/wm8737.c
index 5c9634f..2f167a8 100644
--- a/sound/soc/codecs/wm8737.c
+++ b/sound/soc/codecs/wm8737.c
@@ -645,8 +645,8 @@
 };
 
 #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
-static __devinit int wm8737_i2c_probe(struct i2c_client *i2c,
-				      const struct i2c_device_id *id)
+static int wm8737_i2c_probe(struct i2c_client *i2c,
+			    const struct i2c_device_id *id)
 {
 	struct wm8737_priv *wm8737;
 	int ret, i;
@@ -679,7 +679,7 @@
 
 }
 
-static __devexit int wm8737_i2c_remove(struct i2c_client *client)
+static int wm8737_i2c_remove(struct i2c_client *client)
 {
 	snd_soc_unregister_codec(&client->dev);
 
@@ -699,13 +699,13 @@
 		.of_match_table = wm8737_of_match,
 	},
 	.probe =    wm8737_i2c_probe,
-	.remove =   __devexit_p(wm8737_i2c_remove),
+	.remove =   wm8737_i2c_remove,
 	.id_table = wm8737_i2c_id,
 };
 #endif
 
 #if defined(CONFIG_SPI_MASTER)
-static int __devinit wm8737_spi_probe(struct spi_device *spi)
+static int wm8737_spi_probe(struct spi_device *spi)
 {
 	struct wm8737_priv *wm8737;
 	int ret, i;
@@ -737,7 +737,7 @@
 	return ret;
 }
 
-static int __devexit wm8737_spi_remove(struct spi_device *spi)
+static int wm8737_spi_remove(struct spi_device *spi)
 {
 	snd_soc_unregister_codec(&spi->dev);
 
@@ -751,7 +751,7 @@
 		.of_match_table = wm8737_of_match,
 	},
 	.probe		= wm8737_spi_probe,
-	.remove		= __devexit_p(wm8737_spi_remove),
+	.remove		= wm8737_spi_remove,
 };
 #endif /* CONFIG_SPI_MASTER */
 
diff --git a/sound/soc/codecs/wm8741.c b/sound/soc/codecs/wm8741.c
index 4281a08..b18813c 100644
--- a/sound/soc/codecs/wm8741.c
+++ b/sound/soc/codecs/wm8741.c
@@ -522,7 +522,7 @@
 		return ret;
 	}
 
-	wm8741->regmap = regmap_init_i2c(i2c, &wm8741_regmap);
+	wm8741->regmap = devm_regmap_init_i2c(i2c, &wm8741_regmap);
 	if (IS_ERR(wm8741->regmap)) {
 		ret = PTR_ERR(wm8741->regmap);
 		dev_err(&i2c->dev, "Failed to init regmap: %d\n", ret);
@@ -562,7 +562,7 @@
 #endif
 
 #if defined(CONFIG_SPI_MASTER)
-static int __devinit wm8741_spi_probe(struct spi_device *spi)
+static int wm8741_spi_probe(struct spi_device *spi)
 {
 	struct wm8741_priv *wm8741;
 	int ret, i;
@@ -582,7 +582,7 @@
 		return ret;
 	}
 
-	wm8741->regmap = regmap_init_spi(spi, &wm8741_regmap);
+	wm8741->regmap = devm_regmap_init_spi(spi, &wm8741_regmap);
 	if (IS_ERR(wm8741->regmap)) {
 		ret = PTR_ERR(wm8741->regmap);
 		dev_err(&spi->dev, "Failed to init regmap: %d\n", ret);
@@ -596,7 +596,7 @@
 	return ret;
 }
 
-static int __devexit wm8741_spi_remove(struct spi_device *spi)
+static int wm8741_spi_remove(struct spi_device *spi)
 {
 	snd_soc_unregister_codec(&spi->dev);
 	return 0;
@@ -609,7 +609,7 @@
 		.of_match_table = wm8741_of_match,
 	},
 	.probe		= wm8741_spi_probe,
-	.remove		= __devexit_p(wm8741_spi_remove),
+	.remove		= wm8741_spi_remove,
 };
 #endif /* CONFIG_SPI_MASTER */
 
diff --git a/sound/soc/codecs/wm8750.c b/sound/soc/codecs/wm8750.c
index 89151ca..50d5ff6 100644
--- a/sound/soc/codecs/wm8750.c
+++ b/sound/soc/codecs/wm8750.c
@@ -18,6 +18,7 @@
 #include <linux/delay.h>
 #include <linux/pm.h>
 #include <linux/i2c.h>
+#include <linux/regmap.h>
 #include <linux/spi/spi.h>
 #include <linux/slab.h>
 #include <linux/of_device.h>
@@ -34,24 +35,55 @@
  * We can't read the WM8750 register space when we
  * are using 2 wire for device control, so we cache them instead.
  */
-static const u16 wm8750_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 wm8750_reg_defaults[] = {
+	{  0, 0x0097 },
+	{  1, 0x0097 },
+	{  2, 0x0079 },
+	{  3, 0x0079 },
+	{  4, 0x0000 },
+	{  5, 0x0008 },
+	{  6, 0x0000 },
+	{  7, 0x000a },
+	{  8, 0x0000 },
+	{  9, 0x0000 },
+	{ 10, 0x00ff },
+	{ 11, 0x00ff },
+	{ 12, 0x000f },
+	{ 13, 0x000f },
+	{ 14, 0x0000 },
+	{ 15, 0x0000 },
+	{ 16, 0x0000 },
+	{ 17, 0x007b },
+	{ 18, 0x0000 },
+	{ 19, 0x0032 },
+	{ 20, 0x0000 },
+	{ 21, 0x00c3 },
+	{ 22, 0x00c3 },
+	{ 23, 0x00c0 },
+	{ 24, 0x0000 },
+	{ 25, 0x0000 },
+	{ 26, 0x0000 },
+	{ 27, 0x0000 },
+	{ 28, 0x0000 },
+	{ 29, 0x0000 },
+	{ 30, 0x0000 },
+	{ 31, 0x0000 },
+	{ 32, 0x0000 },
+	{ 33, 0x0000 },
+	{ 34, 0x0050 },
+	{ 35, 0x0050 },
+	{ 36, 0x0050 },
+	{ 37, 0x0050 },
+	{ 38, 0x0050 },
+	{ 39, 0x0050 },
+	{ 40, 0x0079 },
+	{ 41, 0x0079 },
+	{ 42, 0x0079 },
 };
 
 /* codec private data */
 struct wm8750_priv {
 	unsigned int sysclk;
-	enum snd_soc_control_type control_type;
 };
 
 #define wm8750_reset(c)	snd_soc_write(c, WM8750_RESET, 0)
@@ -668,10 +700,9 @@
 
 static int wm8750_probe(struct snd_soc_codec *codec)
 {
-	struct wm8750_priv *wm8750 = snd_soc_codec_get_drvdata(codec);
 	int ret;
 
-	ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8750->control_type);
+	ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP);
 	if (ret < 0) {
 		printk(KERN_ERR "wm8750: failed to set cache I/O: %d\n", ret);
 		return ret;
@@ -711,9 +742,6 @@
 	.suspend =	wm8750_suspend,
 	.resume =	wm8750_resume,
 	.set_bias_level = wm8750_set_bias_level,
-	.reg_cache_size = ARRAY_SIZE(wm8750_reg),
-	.reg_word_size = sizeof(u16),
-	.reg_cache_default = wm8750_reg,
 
 	.controls = wm8750_snd_controls,
 	.num_controls = ARRAY_SIZE(wm8750_snd_controls),
@@ -730,10 +758,21 @@
 };
 MODULE_DEVICE_TABLE(of, wm8750_of_match);
 
+static const struct regmap_config wm8750_regmap = {
+	.reg_bits = 7,
+	.val_bits = 9,
+	.max_register = WM8750_MOUTV,
+
+	.reg_defaults = wm8750_reg_defaults,
+	.num_reg_defaults = ARRAY_SIZE(wm8750_reg_defaults),
+	.cache_type = REGCACHE_RBTREE,
+};
+
 #if defined(CONFIG_SPI_MASTER)
-static int __devinit wm8750_spi_probe(struct spi_device *spi)
+static int wm8750_spi_probe(struct spi_device *spi)
 {
 	struct wm8750_priv *wm8750;
+	struct regmap *regmap;
 	int ret;
 
 	wm8750 = devm_kzalloc(&spi->dev, sizeof(struct wm8750_priv),
@@ -741,7 +780,10 @@
 	if (wm8750 == NULL)
 		return -ENOMEM;
 
-	wm8750->control_type = SND_SOC_SPI;
+	regmap = devm_regmap_init_spi(spi, &wm8750_regmap);
+	if (IS_ERR(regmap))
+		return PTR_ERR(regmap);
+
 	spi_set_drvdata(spi, wm8750);
 
 	ret = snd_soc_register_codec(&spi->dev,
@@ -749,7 +791,7 @@
 	return ret;
 }
 
-static int __devexit wm8750_spi_remove(struct spi_device *spi)
+static int wm8750_spi_remove(struct spi_device *spi)
 {
 	snd_soc_unregister_codec(&spi->dev);
 	return 0;
@@ -770,15 +812,16 @@
 	},
 	.id_table	= wm8750_spi_ids,
 	.probe		= wm8750_spi_probe,
-	.remove		= __devexit_p(wm8750_spi_remove),
+	.remove		= wm8750_spi_remove,
 };
 #endif /* CONFIG_SPI_MASTER */
 
 #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
-static __devinit int wm8750_i2c_probe(struct i2c_client *i2c,
-				      const struct i2c_device_id *id)
+static int wm8750_i2c_probe(struct i2c_client *i2c,
+			    const struct i2c_device_id *id)
 {
 	struct wm8750_priv *wm8750;
+	struct regmap *regmap;
 	int ret;
 
 	wm8750 = devm_kzalloc(&i2c->dev, sizeof(struct wm8750_priv),
@@ -787,14 +830,17 @@
 		return -ENOMEM;
 
 	i2c_set_clientdata(i2c, wm8750);
-	wm8750->control_type = SND_SOC_I2C;
+
+	regmap = devm_regmap_init_i2c(i2c, &wm8750_regmap);
+	if (IS_ERR(regmap))
+		return PTR_ERR(regmap);
 
 	ret =  snd_soc_register_codec(&i2c->dev,
 			&soc_codec_dev_wm8750, &wm8750_dai, 1);
 	return ret;
 }
 
-static __devexit int wm8750_i2c_remove(struct i2c_client *client)
+static int wm8750_i2c_remove(struct i2c_client *client)
 {
 	snd_soc_unregister_codec(&client->dev);
 	return 0;
@@ -814,7 +860,7 @@
 		.of_match_table = wm8750_of_match,
 	},
 	.probe =    wm8750_i2c_probe,
-	.remove =   __devexit_p(wm8750_i2c_remove),
+	.remove =   wm8750_i2c_remove,
 	.id_table = wm8750_i2c_id,
 };
 #endif
diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c
index 2e4a775..0a4ab4c 100644
--- a/sound/soc/codecs/wm8753.c
+++ b/sound/soc/codecs/wm8753.c
@@ -1550,7 +1550,7 @@
 };
 
 #if defined(CONFIG_SPI_MASTER)
-static int __devinit wm8753_spi_probe(struct spi_device *spi)
+static int wm8753_spi_probe(struct spi_device *spi)
 {
 	struct wm8753_priv *wm8753;
 	int ret;
@@ -1562,36 +1562,25 @@
 
 	spi_set_drvdata(spi, wm8753);
 
-	wm8753->regmap = regmap_init_spi(spi, &wm8753_regmap);
+	wm8753->regmap = devm_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;
+		return ret;
 	}
 
 	ret = snd_soc_register_codec(&spi->dev, &soc_codec_dev_wm8753,
 				     wm8753_dai, ARRAY_SIZE(wm8753_dai));
-	if (ret != 0) {
+	if (ret != 0)
 		dev_err(&spi->dev, "Failed to register CODEC: %d\n", ret);
-		goto err_regmap;
-	}
 
-	return 0;
-
-err_regmap:
-	regmap_exit(wm8753->regmap);
-err:
 	return ret;
 }
 
-static int __devexit wm8753_spi_remove(struct spi_device *spi)
+static int wm8753_spi_remove(struct spi_device *spi)
 {
-	struct wm8753_priv *wm8753 = spi_get_drvdata(spi);
-
 	snd_soc_unregister_codec(&spi->dev);
-	regmap_exit(wm8753->regmap);
-	kfree(wm8753);
 	return 0;
 }
 
@@ -1602,13 +1591,13 @@
 		.of_match_table = wm8753_of_match,
 	},
 	.probe		= wm8753_spi_probe,
-	.remove		= __devexit_p(wm8753_spi_remove),
+	.remove		= wm8753_spi_remove,
 };
 #endif /* CONFIG_SPI_MASTER */
 
 #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
-static __devinit int wm8753_i2c_probe(struct i2c_client *i2c,
-				      const struct i2c_device_id *id)
+static int wm8753_i2c_probe(struct i2c_client *i2c,
+			    const struct i2c_device_id *id)
 {
 	struct wm8753_priv *wm8753;
 	int ret;
@@ -1620,35 +1609,25 @@
 
 	i2c_set_clientdata(i2c, wm8753);
 
-	wm8753->regmap = regmap_init_i2c(i2c, &wm8753_regmap);
+	wm8753->regmap = devm_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;
+		return ret;
 	}
 
 	ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm8753,
 				     wm8753_dai, ARRAY_SIZE(wm8753_dai));
-	if (ret != 0) {
+	if (ret != 0)
 		dev_err(&i2c->dev, "Failed to register CODEC: %d\n", ret);
-		goto err_regmap;
-	}
 
-	return 0;
-
-err_regmap:
-	regmap_exit(wm8753->regmap);
-err:
 	return ret;
 }
 
-static __devexit int wm8753_i2c_remove(struct i2c_client *client)
+static int wm8753_i2c_remove(struct i2c_client *client)
 {
-	struct wm8753_priv *wm8753 = i2c_get_clientdata(client);
-
 	snd_soc_unregister_codec(&client->dev);
-	regmap_exit(wm8753->regmap);
 	return 0;
 }
 
@@ -1665,7 +1644,7 @@
 		.of_match_table = wm8753_of_match,
 	},
 	.probe =    wm8753_i2c_probe,
-	.remove =   __devexit_p(wm8753_i2c_remove),
+	.remove =   wm8753_i2c_remove,
 	.id_table = wm8753_i2c_id,
 };
 #endif
diff --git a/sound/soc/codecs/wm8770.c b/sound/soc/codecs/wm8770.c
index c7c0034..89a18d8 100644
--- a/sound/soc/codecs/wm8770.c
+++ b/sound/soc/codecs/wm8770.c
@@ -17,6 +17,7 @@
 #include <linux/of_device.h>
 #include <linux/pm.h>
 #include <linux/spi/spi.h>
+#include <linux/regmap.h>
 #include <linux/regulator/consumer.h>
 #include <linux/slab.h>
 #include <sound/core.h>
@@ -35,19 +36,52 @@
 	"DVDD"
 };
 
-static const u16 wm8770_reg_defs[WM8770_CACHEREGNUM] = {
-	0x7f, 0x7f, 0x7f, 0x7f,
-	0x7f, 0x7f, 0x7f, 0x7f,
-	0x7f, 0xff, 0xff, 0xff,
-	0xff, 0xff, 0xff, 0xff,
-	0xff, 0xff, 0, 0x90, 0,
-	0, 0x22, 0x22, 0x3e,
-	0xc, 0xc, 0x100, 0x189,
-	0x189, 0x8770
+static const struct reg_default wm8770_reg_defaults[] = {
+	{  0, 0x7f },
+	{  1, 0x7f },
+	{  2, 0x7f },
+	{  3, 0x7f },
+	{  4, 0x7f },
+	{  5, 0x7f },
+	{  6, 0x7f },
+	{  7, 0x7f },
+	{  8, 0x7f },
+	{  9, 0xff },
+	{ 10, 0xff },
+	{ 11, 0xff },
+	{ 12, 0xff },
+	{ 13, 0xff },
+	{ 14, 0xff },
+	{ 15, 0xff },
+	{ 16, 0xff },
+	{ 17, 0xff },
+	{ 18, 0    },
+	{ 19, 0x90 },
+	{ 20, 0    },
+	{ 21, 0    },
+	{ 22, 0x22 },
+	{ 23, 0x22 },
+	{ 24, 0x3e },
+	{ 25, 0xc  },
+	{ 26, 0xc  },
+	{ 27, 0x100 },
+	{ 28, 0x189 },
+	{ 29, 0x189 },
+	{ 30, 0x8770 },
 };
 
+static bool wm8770_volatile_reg(struct device *dev, unsigned int reg)
+{
+	switch (reg) {
+	case WM8770_RESET:
+		return true;
+	default:
+		return false;
+	}
+}
+
 struct wm8770_priv {
-	enum snd_soc_control_type control_type;
+	struct regmap *regmap;
 	struct regulator_bulk_data supplies[WM8770_NUM_SUPPLIES];
 	struct notifier_block disable_nb[WM8770_NUM_SUPPLIES];
 	struct snd_soc_codec *codec;
@@ -71,7 +105,7 @@
 	struct wm8770_priv *wm8770 = container_of(nb, struct wm8770_priv, \
 				     disable_nb[n]); \
 	if (event & REGULATOR_EVENT_DISABLE) { \
-		wm8770->codec->cache_sync = 1; \
+		regcache_mark_dirty(wm8770->regmap);	\
 	} \
 	return 0; \
 }
@@ -466,24 +500,6 @@
 	return 0;
 }
 
-static void wm8770_sync_cache(struct snd_soc_codec *codec)
-{
-	int i;
-	u16 *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 == WM8770_RESET || cache[i] == wm8770_reg_defs[i])
-			continue;
-		snd_soc_write(codec, i, cache[i]);
-	}
-	codec->cache_sync = 0;
-}
-
 static int wm8770_set_bias_level(struct snd_soc_codec *codec,
 				 enum snd_soc_bias_level level)
 {
@@ -507,7 +523,9 @@
 					ret);
 				return ret;
 			}
-			wm8770_sync_cache(codec);
+
+			regcache_sync(wm8770->regmap);
+
 			/* global powerup */
 			snd_soc_write(codec, WM8770_PWDNCTRL, 0);
 		}
@@ -554,68 +572,25 @@
 	.symmetric_rates = 1
 };
 
-#ifdef CONFIG_PM
-static int wm8770_suspend(struct snd_soc_codec *codec)
-{
-	wm8770_set_bias_level(codec, SND_SOC_BIAS_OFF);
-	return 0;
-}
-
-static int wm8770_resume(struct snd_soc_codec *codec)
-{
-	wm8770_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-	return 0;
-}
-#else
-#define wm8770_suspend NULL
-#define wm8770_resume NULL
-#endif
-
 static int wm8770_probe(struct snd_soc_codec *codec)
 {
 	struct wm8770_priv *wm8770;
 	int ret;
-	int i;
 
 	wm8770 = snd_soc_codec_get_drvdata(codec);
 	wm8770->codec = codec;
 
-	ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8770->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;
 	}
 
-	for (i = 0; i < ARRAY_SIZE(wm8770->supplies); i++)
-		wm8770->supplies[i].supply = wm8770_supply_names[i];
-
-	ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8770->supplies),
-				 wm8770->supplies);
-	if (ret) {
-		dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
-		return ret;
-	}
-
-	wm8770->disable_nb[0].notifier_call = wm8770_regulator_event_0;
-	wm8770->disable_nb[1].notifier_call = wm8770_regulator_event_1;
-	wm8770->disable_nb[2].notifier_call = wm8770_regulator_event_2;
-
-	/* This should really be moved into the regulator core */
-	for (i = 0; i < ARRAY_SIZE(wm8770->supplies); i++) {
-		ret = regulator_register_notifier(wm8770->supplies[i].consumer,
-						  &wm8770->disable_nb[i]);
-		if (ret) {
-			dev_err(codec->dev,
-				"Failed to register regulator notifier: %d\n",
-				ret);
-		}
-	}
-
 	ret = regulator_bulk_enable(ARRAY_SIZE(wm8770->supplies),
 				    wm8770->supplies);
 	if (ret) {
 		dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
-		goto err_reg_get;
+		return ret;
 	}
 
 	ret = wm8770_reset(codec);
@@ -624,8 +599,6 @@
 		goto err_reg_enable;
 	}
 
-	wm8770_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-
 	/* latch the volume update bits */
 	snd_soc_update_bits(codec, WM8770_MSDIGVOL, 0x100, 0x100);
 	snd_soc_update_bits(codec, WM8770_MSALGVOL, 0x100, 0x100);
@@ -641,46 +614,22 @@
 	/* mute all DACs */
 	snd_soc_update_bits(codec, WM8770_DACMUTE, 0x10, 0x10);
 
-	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));
-	snd_soc_dapm_add_routes(&codec->dapm, wm8770_intercon,
-				ARRAY_SIZE(wm8770_intercon));
-	return 0;
-
 err_reg_enable:
 	regulator_bulk_disable(ARRAY_SIZE(wm8770->supplies), wm8770->supplies);
-err_reg_get:
-	regulator_bulk_free(ARRAY_SIZE(wm8770->supplies), wm8770->supplies);
 	return ret;
 }
 
-static int wm8770_remove(struct snd_soc_codec *codec)
-{
-	struct wm8770_priv *wm8770;
-	int i;
-
-	wm8770 = snd_soc_codec_get_drvdata(codec);
-	wm8770_set_bias_level(codec, SND_SOC_BIAS_OFF);
-
-	for (i = 0; i < ARRAY_SIZE(wm8770->supplies); ++i)
-		regulator_unregister_notifier(wm8770->supplies[i].consumer,
-					      &wm8770->disable_nb[i]);
-	regulator_bulk_free(ARRAY_SIZE(wm8770->supplies), wm8770->supplies);
-	return 0;
-}
-
 static struct snd_soc_codec_driver soc_codec_dev_wm8770 = {
 	.probe = wm8770_probe,
-	.remove = wm8770_remove,
-	.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
+
+	.controls = wm8770_snd_controls,
+	.num_controls = ARRAY_SIZE(wm8770_snd_controls),
+	.dapm_widgets = wm8770_dapm_widgets,
+	.num_dapm_widgets = ARRAY_SIZE(wm8770_dapm_widgets),
+	.dapm_routes = wm8770_intercon,
+	.num_dapm_routes = ARRAY_SIZE(wm8770_intercon),
 };
 
 static const struct of_device_id wm8770_of_match[] = {
@@ -689,17 +638,57 @@
 };
 MODULE_DEVICE_TABLE(of, wm8770_of_match);
 
-static int __devinit wm8770_spi_probe(struct spi_device *spi)
+static const struct regmap_config wm8770_regmap = {
+	.reg_bits = 7,
+	.val_bits = 9,
+	.max_register = WM8770_RESET,
+
+	.reg_defaults = wm8770_reg_defaults,
+	.num_reg_defaults = ARRAY_SIZE(wm8770_reg_defaults),
+	.cache_type = REGCACHE_RBTREE,
+
+	.volatile_reg = wm8770_volatile_reg,
+};
+
+static int wm8770_spi_probe(struct spi_device *spi)
 {
 	struct wm8770_priv *wm8770;
-	int ret;
+	int ret, i;
 
 	wm8770 = devm_kzalloc(&spi->dev, sizeof(struct wm8770_priv),
 			      GFP_KERNEL);
 	if (!wm8770)
 		return -ENOMEM;
 
-	wm8770->control_type = SND_SOC_SPI;
+	for (i = 0; i < ARRAY_SIZE(wm8770->supplies); i++)
+		wm8770->supplies[i].supply = wm8770_supply_names[i];
+
+	ret = devm_regulator_bulk_get(&spi->dev, ARRAY_SIZE(wm8770->supplies),
+				      wm8770->supplies);
+	if (ret) {
+		dev_err(&spi->dev, "Failed to request supplies: %d\n", ret);
+		return ret;
+	}
+
+	wm8770->disable_nb[0].notifier_call = wm8770_regulator_event_0;
+	wm8770->disable_nb[1].notifier_call = wm8770_regulator_event_1;
+	wm8770->disable_nb[2].notifier_call = wm8770_regulator_event_2;
+
+	/* This should really be moved into the regulator core */
+	for (i = 0; i < ARRAY_SIZE(wm8770->supplies); i++) {
+		ret = regulator_register_notifier(wm8770->supplies[i].consumer,
+						  &wm8770->disable_nb[i]);
+		if (ret) {
+			dev_err(&spi->dev,
+				"Failed to register regulator notifier: %d\n",
+				ret);
+		}
+	}
+
+	wm8770->regmap = devm_regmap_init_spi(spi, &wm8770_regmap);
+	if (IS_ERR(wm8770->regmap))
+		return PTR_ERR(wm8770->regmap);
+
 	spi_set_drvdata(spi, wm8770);
 
 	ret = snd_soc_register_codec(&spi->dev,
@@ -708,9 +697,17 @@
 	return ret;
 }
 
-static int __devexit wm8770_spi_remove(struct spi_device *spi)
+static int wm8770_spi_remove(struct spi_device *spi)
 {
+	struct wm8770_priv *wm8770 = spi_get_drvdata(spi);
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(wm8770->supplies); ++i)
+		regulator_unregister_notifier(wm8770->supplies[i].consumer,
+					      &wm8770->disable_nb[i]);
+
 	snd_soc_unregister_codec(&spi->dev);
+
 	return 0;
 }
 
@@ -721,7 +718,7 @@
 		.of_match_table = wm8770_of_match,
 	},
 	.probe = wm8770_spi_probe,
-	.remove = __devexit_p(wm8770_spi_remove)
+	.remove = wm8770_spi_remove
 };
 
 module_spi_driver(wm8770_spi_driver);
diff --git a/sound/soc/codecs/wm8776.c b/sound/soc/codecs/wm8776.c
index c32249d..f31017e 100644
--- a/sound/soc/codecs/wm8776.c
+++ b/sound/soc/codecs/wm8776.c
@@ -492,7 +492,7 @@
 };
 
 #if defined(CONFIG_SPI_MASTER)
-static int __devinit wm8776_spi_probe(struct spi_device *spi)
+static int wm8776_spi_probe(struct spi_device *spi)
 {
 	struct wm8776_priv *wm8776;
 	int ret;
@@ -514,7 +514,7 @@
 	return ret;
 }
 
-static int __devexit wm8776_spi_remove(struct spi_device *spi)
+static int wm8776_spi_remove(struct spi_device *spi)
 {
 	snd_soc_unregister_codec(&spi->dev);
 	return 0;
@@ -527,13 +527,13 @@
 		.of_match_table = wm8776_of_match,
 	},
 	.probe		= wm8776_spi_probe,
-	.remove		= __devexit_p(wm8776_spi_remove),
+	.remove		= wm8776_spi_remove,
 };
 #endif /* CONFIG_SPI_MASTER */
 
 #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
-static __devinit int wm8776_i2c_probe(struct i2c_client *i2c,
-				      const struct i2c_device_id *id)
+static int wm8776_i2c_probe(struct i2c_client *i2c,
+			    const struct i2c_device_id *id)
 {
 	struct wm8776_priv *wm8776;
 	int ret;
@@ -555,7 +555,7 @@
 	return ret;
 }
 
-static __devexit int wm8776_i2c_remove(struct i2c_client *client)
+static int wm8776_i2c_remove(struct i2c_client *client)
 {
 	snd_soc_unregister_codec(&client->dev);
 	return 0;
@@ -575,7 +575,7 @@
 		.of_match_table = wm8776_of_match,
 	},
 	.probe =    wm8776_i2c_probe,
-	.remove =   __devexit_p(wm8776_i2c_remove),
+	.remove =   wm8776_i2c_remove,
 	.id_table = wm8776_i2c_id,
 };
 #endif
diff --git a/sound/soc/codecs/wm8782.c b/sound/soc/codecs/wm8782.c
index 3fdea98..f1fdbf6 100644
--- a/sound/soc/codecs/wm8782.c
+++ b/sound/soc/codecs/wm8782.c
@@ -42,13 +42,13 @@
 
 static struct snd_soc_codec_driver soc_codec_dev_wm8782;
 
-static __devinit int wm8782_probe(struct platform_device *pdev)
+static int wm8782_probe(struct platform_device *pdev)
 {
 	return snd_soc_register_codec(&pdev->dev,
 			&soc_codec_dev_wm8782, &wm8782_dai, 1);
 }
 
-static int __devexit wm8782_remove(struct platform_device *pdev)
+static int wm8782_remove(struct platform_device *pdev)
 {
 	snd_soc_unregister_codec(&pdev->dev);
 	return 0;
@@ -60,7 +60,7 @@
 		.owner = THIS_MODULE,
 	},
 	.probe = wm8782_probe,
-	.remove = __devexit_p(wm8782_remove),
+	.remove = wm8782_remove,
 };
 
 module_platform_driver(wm8782_codec_driver);
diff --git a/sound/soc/codecs/wm8804.c b/sound/soc/codecs/wm8804.c
index c088020..d321a87 100644
--- a/sound/soc/codecs/wm8804.c
+++ b/sound/soc/codecs/wm8804.c
@@ -702,7 +702,7 @@
 };
 
 #if defined(CONFIG_SPI_MASTER)
-static int __devinit wm8804_spi_probe(struct spi_device *spi)
+static int wm8804_spi_probe(struct spi_device *spi)
 {
 	struct wm8804_priv *wm8804;
 	int ret;
@@ -711,7 +711,7 @@
 	if (!wm8804)
 		return -ENOMEM;
 
-	wm8804->regmap = regmap_init_spi(spi, &wm8804_regmap_config);
+	wm8804->regmap = devm_regmap_init_spi(spi, &wm8804_regmap_config);
 	if (IS_ERR(wm8804->regmap)) {
 		ret = PTR_ERR(wm8804->regmap);
 		return ret;
@@ -725,11 +725,9 @@
 	return ret;
 }
 
-static int __devexit wm8804_spi_remove(struct spi_device *spi)
+static int wm8804_spi_remove(struct spi_device *spi)
 {
-	struct wm8804_priv *wm8804 = spi_get_drvdata(spi);
 	snd_soc_unregister_codec(&spi->dev);
-	regmap_exit(wm8804->regmap);
 	return 0;
 }
 
@@ -740,13 +738,13 @@
 		.of_match_table = wm8804_of_match,
 	},
 	.probe = wm8804_spi_probe,
-	.remove = __devexit_p(wm8804_spi_remove)
+	.remove = wm8804_spi_remove
 };
 #endif
 
 #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
-static __devinit int wm8804_i2c_probe(struct i2c_client *i2c,
-				      const struct i2c_device_id *id)
+static int wm8804_i2c_probe(struct i2c_client *i2c,
+			    const struct i2c_device_id *id)
 {
 	struct wm8804_priv *wm8804;
 	int ret;
@@ -755,7 +753,7 @@
 	if (!wm8804)
 		return -ENOMEM;
 
-	wm8804->regmap = regmap_init_i2c(i2c, &wm8804_regmap_config);
+	wm8804->regmap = devm_regmap_init_i2c(i2c, &wm8804_regmap_config);
 	if (IS_ERR(wm8804->regmap)) {
 		ret = PTR_ERR(wm8804->regmap);
 		return ret;
@@ -765,23 +763,12 @@
 
 	ret = snd_soc_register_codec(&i2c->dev,
 				     &soc_codec_dev_wm8804, &wm8804_dai, 1);
-	if (ret != 0)
-		goto err;
-
-	return 0;
-
-err:
-	regmap_exit(wm8804->regmap);
 	return ret;
 }
 
-static __devexit int wm8804_i2c_remove(struct i2c_client *i2c)
+static int wm8804_i2c_remove(struct i2c_client *i2c)
 {
-	struct wm8804_priv *wm8804 = i2c_get_clientdata(i2c);
-
 	snd_soc_unregister_codec(&i2c->dev);
-	regmap_exit(wm8804->regmap);
-
 	return 0;
 }
 
@@ -798,7 +785,7 @@
 		.of_match_table = wm8804_of_match,
 	},
 	.probe = wm8804_i2c_probe,
-	.remove = __devexit_p(wm8804_i2c_remove),
+	.remove = wm8804_i2c_remove,
 	.id_table = wm8804_i2c_id
 };
 #endif
diff --git a/sound/soc/codecs/wm8900.c b/sound/soc/codecs/wm8900.c
index e781f86..7c8257c 100644
--- a/sound/soc/codecs/wm8900.c
+++ b/sound/soc/codecs/wm8900.c
@@ -1247,7 +1247,7 @@
 };
 
 #if defined(CONFIG_SPI_MASTER)
-static int __devinit wm8900_spi_probe(struct spi_device *spi)
+static int wm8900_spi_probe(struct spi_device *spi)
 {
 	struct wm8900_priv *wm8900;
 	int ret;
@@ -1269,7 +1269,7 @@
 	return ret;
 }
 
-static int __devexit wm8900_spi_remove(struct spi_device *spi)
+static int wm8900_spi_remove(struct spi_device *spi)
 {
 	snd_soc_unregister_codec(&spi->dev);
 	return 0;
@@ -1281,13 +1281,13 @@
 		.owner	= THIS_MODULE,
 	},
 	.probe		= wm8900_spi_probe,
-	.remove		= __devexit_p(wm8900_spi_remove),
+	.remove		= wm8900_spi_remove,
 };
 #endif /* CONFIG_SPI_MASTER */
 
 #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
-static __devinit int wm8900_i2c_probe(struct i2c_client *i2c,
-				      const struct i2c_device_id *id)
+static int wm8900_i2c_probe(struct i2c_client *i2c,
+			    const struct i2c_device_id *id)
 {
 	struct wm8900_priv *wm8900;
 	int ret;
@@ -1309,7 +1309,7 @@
 	return ret;
 }
 
-static __devexit int wm8900_i2c_remove(struct i2c_client *client)
+static int wm8900_i2c_remove(struct i2c_client *client)
 {
 	snd_soc_unregister_codec(&client->dev);
 	return 0;
@@ -1327,7 +1327,7 @@
 		.owner = THIS_MODULE,
 	},
 	.probe =    wm8900_i2c_probe,
-	.remove =   __devexit_p(wm8900_i2c_remove),
+	.remove =   wm8900_i2c_remove,
 	.id_table = wm8900_i2c_id,
 };
 #endif
diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c
index 839414f..134e41c 100644
--- a/sound/soc/codecs/wm8903.c
+++ b/sound/soc/codecs/wm8903.c
@@ -2020,8 +2020,8 @@
 	return 0;
 }
 
-static __devinit int wm8903_i2c_probe(struct i2c_client *i2c,
-				      const struct i2c_device_id *id)
+static int wm8903_i2c_probe(struct i2c_client *i2c,
+			    const struct i2c_device_id *id)
 {
 	struct wm8903_platform_data *pdata = dev_get_platdata(&i2c->dev);
 	struct wm8903_priv *wm8903;
@@ -2206,7 +2206,7 @@
 	return ret;
 }
 
-static __devexit int wm8903_i2c_remove(struct i2c_client *client)
+static int wm8903_i2c_remove(struct i2c_client *client)
 {
 	struct wm8903_priv *wm8903 = i2c_get_clientdata(client);
 
@@ -2237,7 +2237,7 @@
 		.of_match_table = wm8903_of_match,
 	},
 	.probe =    wm8903_i2c_probe,
-	.remove =   __devexit_p(wm8903_i2c_remove),
+	.remove =   wm8903_i2c_remove,
 	.id_table = wm8903_i2c_id,
 };
 
diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c
index 7c8df52..3ff195c 100644
--- a/sound/soc/codecs/wm8904.c
+++ b/sound/soc/codecs/wm8904.c
@@ -2111,8 +2111,8 @@
 	.num_reg_defaults = ARRAY_SIZE(wm8904_reg_defaults),
 };
 
-static __devinit int wm8904_i2c_probe(struct i2c_client *i2c,
-				      const struct i2c_device_id *id)
+static int wm8904_i2c_probe(struct i2c_client *i2c,
+			    const struct i2c_device_id *id)
 {
 	struct wm8904_priv *wm8904;
 	unsigned int val;
@@ -2247,7 +2247,7 @@
 	return ret;
 }
 
-static __devexit int wm8904_i2c_remove(struct i2c_client *client)
+static int wm8904_i2c_remove(struct i2c_client *client)
 {
 	snd_soc_unregister_codec(&client->dev);
 	return 0;
@@ -2267,7 +2267,7 @@
 		.owner = THIS_MODULE,
 	},
 	.probe =    wm8904_i2c_probe,
-	.remove =   __devexit_p(wm8904_i2c_remove),
+	.remove =   wm8904_i2c_remove,
 	.id_table = wm8904_i2c_id,
 };
 
diff --git a/sound/soc/codecs/wm8940.c b/sound/soc/codecs/wm8940.c
index b20aa4e..b1591c61 100644
--- a/sound/soc/codecs/wm8940.c
+++ b/sound/soc/codecs/wm8940.c
@@ -742,8 +742,8 @@
 	.volatile_register = wm8940_volatile_register,
 };
 
-static __devinit int wm8940_i2c_probe(struct i2c_client *i2c,
-				      const struct i2c_device_id *id)
+static int wm8940_i2c_probe(struct i2c_client *i2c,
+			    const struct i2c_device_id *id)
 {
 	struct wm8940_priv *wm8940;
 	int ret;
@@ -762,7 +762,7 @@
 	return ret;
 }
 
-static __devexit int wm8940_i2c_remove(struct i2c_client *client)
+static int wm8940_i2c_remove(struct i2c_client *client)
 {
 	snd_soc_unregister_codec(&client->dev);
 
@@ -781,7 +781,7 @@
 		.owner = THIS_MODULE,
 	},
 	.probe =    wm8940_i2c_probe,
-	.remove =   __devexit_p(wm8940_i2c_remove),
+	.remove =   wm8940_i2c_remove,
 	.id_table = wm8940_i2c_id,
 };
 
diff --git a/sound/soc/codecs/wm8955.c b/sound/soc/codecs/wm8955.c
index 2f1c075..82c8ba9 100644
--- a/sound/soc/codecs/wm8955.c
+++ b/sound/soc/codecs/wm8955.c
@@ -1012,8 +1012,8 @@
 	.num_reg_defaults = ARRAY_SIZE(wm8955_reg_defaults),
 };
 
-static __devinit int wm8955_i2c_probe(struct i2c_client *i2c,
-				      const struct i2c_device_id *id)
+static int wm8955_i2c_probe(struct i2c_client *i2c,
+			    const struct i2c_device_id *id)
 {
 	struct wm8955_priv *wm8955;
 	int ret;
@@ -1023,7 +1023,7 @@
 	if (wm8955 == NULL)
 		return -ENOMEM;
 
-	wm8955->regmap = regmap_init_i2c(i2c, &wm8955_regmap);
+	wm8955->regmap = devm_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",
@@ -1035,22 +1035,13 @@
 
 	ret = snd_soc_register_codec(&i2c->dev,
 			&soc_codec_dev_wm8955, &wm8955_dai, 1);
-	if (ret != 0)
-		goto err;
 
 	return ret;
-
-err:
-	regmap_exit(wm8955->regmap);
-	return ret;
 }
 
-static __devexit int wm8955_i2c_remove(struct i2c_client *client)
+static int wm8955_i2c_remove(struct i2c_client *client)
 {
-	struct wm8955_priv *wm8955 = i2c_get_clientdata(client);
-
 	snd_soc_unregister_codec(&client->dev);
-	regmap_exit(wm8955->regmap);
 
 	return 0;
 }
@@ -1067,7 +1058,7 @@
 		.owner = THIS_MODULE,
 	},
 	.probe =    wm8955_i2c_probe,
-	.remove =   __devexit_p(wm8955_i2c_remove),
+	.remove =   wm8955_i2c_remove,
 	.id_table = wm8955_i2c_id,
 };
 
diff --git a/sound/soc/codecs/wm8958-dsp2.c b/sound/soc/codecs/wm8958-dsp2.c
index 00121ba..b0710d8 100644
--- a/sound/soc/codecs/wm8958-dsp2.c
+++ b/sound/soc/codecs/wm8958-dsp2.c
@@ -195,7 +195,7 @@
 static void wm8958_dsp_start_mbc(struct snd_soc_codec *codec, int path)
 {
 	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
-	struct wm8994_pdata *pdata = wm8994->pdata;
+	struct wm8994 *control = wm8994->wm8994;
 	int i;
 
 	/* If the DSP is already running then noop */
@@ -210,9 +210,9 @@
 			    WM8958_DSP2_ENA, WM8958_DSP2_ENA);
 
 	/* If we've got user supplied MBC settings use them */
-	if (pdata && pdata->num_mbc_cfgs) {
+	if (control->pdata.num_mbc_cfgs) {
 		struct wm8958_mbc_cfg *cfg
-			= &pdata->mbc_cfgs[wm8994->mbc_cfg];
+			= &control->pdata.mbc_cfgs[wm8994->mbc_cfg];
 
 		for (i = 0; i < ARRAY_SIZE(cfg->coeff_regs); i++)
 			snd_soc_write(codec, i + WM8958_MBC_BAND_1_K_1,
@@ -239,7 +239,7 @@
 static void wm8958_dsp_start_vss(struct snd_soc_codec *codec, int path)
 {
 	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
-	struct wm8994_pdata *pdata = wm8994->pdata;
+	struct wm8994 *control = wm8994->wm8994;
 	int i, ena;
 
 	if (wm8994->mbc_vss)
@@ -249,26 +249,26 @@
 			    WM8958_DSP2_ENA, WM8958_DSP2_ENA);
 
 	/* If we've got user supplied settings use them */
-	if (pdata && pdata->num_mbc_cfgs) {
+	if (control->pdata.num_mbc_cfgs) {
 		struct wm8958_mbc_cfg *cfg
-			= &pdata->mbc_cfgs[wm8994->mbc_cfg];
+			= &control->pdata.mbc_cfgs[wm8994->mbc_cfg];
 
 		for (i = 0; i < ARRAY_SIZE(cfg->combined_regs); i++)
 			snd_soc_write(codec, i + 0x2800,
 				      cfg->combined_regs[i]);
 	}
 
-	if (pdata && pdata->num_vss_cfgs) {
+	if (control->pdata.num_vss_cfgs) {
 		struct wm8958_vss_cfg *cfg
-			= &pdata->vss_cfgs[wm8994->vss_cfg];
+			= &control->pdata.vss_cfgs[wm8994->vss_cfg];
 
 		for (i = 0; i < ARRAY_SIZE(cfg->regs); i++)
 			snd_soc_write(codec, i + 0x2600, cfg->regs[i]);
 	}
 
-	if (pdata && pdata->num_vss_hpf_cfgs) {
+	if (control->pdata.num_vss_hpf_cfgs) {
 		struct wm8958_vss_hpf_cfg *cfg
-			= &pdata->vss_hpf_cfgs[wm8994->vss_hpf_cfg];
+			= &control->pdata.vss_hpf_cfgs[wm8994->vss_hpf_cfg];
 
 		for (i = 0; i < ARRAY_SIZE(cfg->regs); i++)
 			snd_soc_write(codec, i + 0x2400, cfg->regs[i]);
@@ -300,7 +300,7 @@
 static void wm8958_dsp_start_enh_eq(struct snd_soc_codec *codec, int path)
 {
 	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
-	struct wm8994_pdata *pdata = wm8994->pdata;
+	struct wm8994 *control = wm8994->wm8994;
 	int i;
 
 	wm8958_dsp2_fw(codec, "ENH_EQ", wm8994->enh_eq, false);
@@ -309,9 +309,9 @@
 			    WM8958_DSP2_ENA, WM8958_DSP2_ENA);
 
 	/* If we've got user supplied settings use them */
-	if (pdata && pdata->num_enh_eq_cfgs) {
+	if (control->pdata.num_enh_eq_cfgs) {
 		struct wm8958_enh_eq_cfg *cfg
-			= &pdata->enh_eq_cfgs[wm8994->enh_eq_cfg];
+			= &control->pdata.enh_eq_cfgs[wm8994->enh_eq_cfg];
 
 		for (i = 0; i < ARRAY_SIZE(cfg->regs); i++)
 			snd_soc_write(codec, i + 0x2200,
@@ -458,7 +458,7 @@
 {
 	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
 	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
-	struct wm8994_pdata *pdata = wm8994->pdata;
+	struct wm8994 *control = wm8994->wm8994;
 	int value = ucontrol->value.integer.value[0];
 	int reg;
 
@@ -467,7 +467,7 @@
 	if (reg < 0 || reg & WM8958_DSP2CLK_ENA)
 		return -EBUSY;
 
-	if (value >= pdata->num_mbc_cfgs)
+	if (value >= control->pdata.num_mbc_cfgs)
 		return -EINVAL;
 
 	wm8994->mbc_cfg = value;
@@ -548,7 +548,7 @@
 {
 	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
 	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
-	struct wm8994_pdata *pdata = wm8994->pdata;
+	struct wm8994 *control = wm8994->wm8994;
 	int value = ucontrol->value.integer.value[0];
 	int reg;
 
@@ -557,7 +557,7 @@
 	if (reg < 0 || reg & WM8958_DSP2CLK_ENA)
 		return -EBUSY;
 
-	if (value >= pdata->num_vss_cfgs)
+	if (value >= control->pdata.num_vss_cfgs)
 		return -EINVAL;
 
 	wm8994->vss_cfg = value;
@@ -581,7 +581,7 @@
 {
 	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
 	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
-	struct wm8994_pdata *pdata = wm8994->pdata;
+	struct wm8994 *control = wm8994->wm8994;
 	int value = ucontrol->value.integer.value[0];
 	int reg;
 
@@ -590,7 +590,7 @@
 	if (reg < 0 || reg & WM8958_DSP2CLK_ENA)
 		return -EBUSY;
 
-	if (value >= pdata->num_vss_hpf_cfgs)
+	if (value >= control->pdata.num_vss_hpf_cfgs)
 		return -EINVAL;
 
 	wm8994->vss_hpf_cfg = value;
@@ -748,7 +748,7 @@
 {
 	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
 	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
-	struct wm8994_pdata *pdata = wm8994->pdata;
+	struct wm8994 *control = wm8994->wm8994;
 	int value = ucontrol->value.integer.value[0];
 	int reg;
 
@@ -757,7 +757,7 @@
 	if (reg < 0 || reg & WM8958_DSP2CLK_ENA)
 		return -EBUSY;
 
-	if (value >= pdata->num_enh_eq_cfgs)
+	if (value >= control->pdata.num_enh_eq_cfgs)
 		return -EINVAL;
 
 	wm8994->enh_eq_cfg = value;
@@ -883,13 +883,6 @@
 		wm8994->mbc_vss = fw;
 		mutex_unlock(&codec->mutex);
 	}
-
-	/* We can't have more than one request outstanding at once so
-	 * we daisy chain.
-	 */
-	request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG,
-				"wm8958_enh_eq.wfw", codec->dev, GFP_KERNEL,
-				codec, wm8958_enh_eq_loaded);
 }
 
 static void wm8958_mbc_loaded(const struct firmware *fw, void *context)
@@ -897,25 +890,18 @@
 	struct snd_soc_codec *codec = context;
 	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
 
-	if (wm8958_dsp2_fw(codec, "MBC", fw, true) != 0)
-		return;
-
-	mutex_lock(&codec->mutex);
-	wm8994->mbc = fw;
-	mutex_unlock(&codec->mutex);
-
-	/* We can't have more than one request outstanding at once so
-	 * we daisy chain.
-	 */
-	request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG,
-				"wm8958_mbc_vss.wfw", codec->dev, GFP_KERNEL,
-				codec, wm8958_mbc_vss_loaded);
+	if (fw && (wm8958_dsp2_fw(codec, "MBC", fw, true) == 0)) {
+		mutex_lock(&codec->mutex);
+		wm8994->mbc = fw;
+		mutex_unlock(&codec->mutex);
+	}
 }
 
 void wm8958_dsp2_init(struct snd_soc_codec *codec)
 {
 	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
-	struct wm8994_pdata *pdata = wm8994->pdata;
+	struct wm8994 *control = wm8994->wm8994;
+	struct wm8994_pdata *pdata = &control->pdata;
 	int ret, i;
 
 	wm8994->dsp_active = -1;
@@ -932,9 +918,12 @@
 	request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG,
 				"wm8958_mbc.wfw", codec->dev, GFP_KERNEL,
 				codec, wm8958_mbc_loaded);
-
-	if (!pdata)
-		return;
+	request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG,
+				"wm8958_mbc_vss.wfw", codec->dev, GFP_KERNEL,
+				codec, wm8958_mbc_vss_loaded);
+	request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG,
+				"wm8958_enh_eq.wfw", codec->dev, GFP_KERNEL,
+				codec, wm8958_enh_eq_loaded);
 
 	if (pdata->num_mbc_cfgs) {
 		struct snd_kcontrol_new control[] = {
diff --git a/sound/soc/codecs/wm8960.c b/sound/soc/codecs/wm8960.c
index f0f6f660..9bb9273 100644
--- a/sound/soc/codecs/wm8960.c
+++ b/sound/soc/codecs/wm8960.c
@@ -1028,8 +1028,8 @@
 	.volatile_reg = wm8960_volatile,
 };
 
-static __devinit int wm8960_i2c_probe(struct i2c_client *i2c,
-				      const struct i2c_device_id *id)
+static int wm8960_i2c_probe(struct i2c_client *i2c,
+			    const struct i2c_device_id *id)
 {
 	struct wm8960_data *pdata = dev_get_platdata(&i2c->dev);
 	struct wm8960_priv *wm8960;
@@ -1040,7 +1040,7 @@
 	if (wm8960 == NULL)
 		return -ENOMEM;
 
-	wm8960->regmap = regmap_init_i2c(i2c, &wm8960_regmap);
+	wm8960->regmap = devm_regmap_init_i2c(i2c, &wm8960_regmap);
 	if (IS_ERR(wm8960->regmap))
 		return PTR_ERR(wm8960->regmap);
 
@@ -1062,7 +1062,7 @@
 	return ret;
 }
 
-static __devexit int wm8960_i2c_remove(struct i2c_client *client)
+static int wm8960_i2c_remove(struct i2c_client *client)
 {
 	snd_soc_unregister_codec(&client->dev);
 	return 0;
@@ -1080,7 +1080,7 @@
 		.owner = THIS_MODULE,
 	},
 	.probe =    wm8960_i2c_probe,
-	.remove =   __devexit_p(wm8960_i2c_remove),
+	.remove =   wm8960_i2c_remove,
 	.id_table = wm8960_i2c_id,
 };
 
diff --git a/sound/soc/codecs/wm8961.c b/sound/soc/codecs/wm8961.c
index f387670..900328e 100644
--- a/sound/soc/codecs/wm8961.c
+++ b/sound/soc/codecs/wm8961.c
@@ -937,8 +937,8 @@
 	.readable_reg = wm8961_readable,
 };
 
-static __devinit int wm8961_i2c_probe(struct i2c_client *i2c,
-				      const struct i2c_device_id *id)
+static int wm8961_i2c_probe(struct i2c_client *i2c,
+			    const struct i2c_device_id *id)
 {
 	struct wm8961_priv *wm8961;
 	unsigned int val;
@@ -993,7 +993,7 @@
 	return ret;
 }
 
-static __devexit int wm8961_i2c_remove(struct i2c_client *client)
+static int wm8961_i2c_remove(struct i2c_client *client)
 {
 	snd_soc_unregister_codec(&client->dev);
 
@@ -1012,7 +1012,7 @@
 		.owner = THIS_MODULE,
 	},
 	.probe =    wm8961_i2c_probe,
-	.remove =   __devexit_p(wm8961_i2c_remove),
+	.remove =   wm8961_i2c_remove,
 	.id_table = wm8961_i2c_id,
 };
 
diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c
index ce67200..bd4b0db 100644
--- a/sound/soc/codecs/wm8962.c
+++ b/sound/soc/codecs/wm8962.c
@@ -3588,8 +3588,8 @@
 	.cache_type = REGCACHE_RBTREE,
 };
 
-static __devinit int wm8962_i2c_probe(struct i2c_client *i2c,
-				      const struct i2c_device_id *id)
+static 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;
@@ -3610,7 +3610,7 @@
 	for (i = 0; i < ARRAY_SIZE(wm8962->supplies); i++)
 		wm8962->supplies[i].supply = wm8962_supply_names[i];
 
-	ret = regulator_bulk_get(&i2c->dev, ARRAY_SIZE(wm8962->supplies),
+	ret = devm_regulator_bulk_get(&i2c->dev, ARRAY_SIZE(wm8962->supplies),
 				 wm8962->supplies);
 	if (ret != 0) {
 		dev_err(&i2c->dev, "Failed to request supplies: %d\n", ret);
@@ -3621,10 +3621,10 @@
 				    wm8962->supplies);
 	if (ret != 0) {
 		dev_err(&i2c->dev, "Failed to enable supplies: %d\n", ret);
-		goto err_get;
+		return ret;
 	}
 
-	wm8962->regmap = regmap_init_i2c(i2c, &wm8962_regmap);
+	wm8962->regmap = devm_regmap_init_i2c(i2c, &wm8962_regmap);
 	if (IS_ERR(wm8962->regmap)) {
 		ret = PTR_ERR(wm8962->regmap);
 		dev_err(&i2c->dev, "Failed to allocate regmap: %d\n", ret);
@@ -3641,20 +3641,20 @@
 	ret = regmap_read(wm8962->regmap, WM8962_SOFTWARE_RESET, &reg);
 	if (ret < 0) {
 		dev_err(&i2c->dev, "Failed to read ID register\n");
-		goto err_regmap;
+		goto err_enable;
 	}
 	if (reg != 0x6243) {
 		dev_err(&i2c->dev,
 			"Device is not a WM8962, ID %x != 0x6243\n", reg);
 		ret = -EINVAL;
-		goto err_regmap;
+		goto err_enable;
 	}
 
 	ret = regmap_read(wm8962->regmap, WM8962_RIGHT_INPUT_VOLUME, &reg);
 	if (ret < 0) {
 		dev_err(&i2c->dev, "Failed to read device revision: %d\n",
 			ret);
-		goto err_regmap;
+		goto err_enable;
 	}
 
 	dev_info(&i2c->dev, "customer id %x revision %c\n",
@@ -3667,7 +3667,7 @@
 	ret = wm8962_reset(wm8962);
 	if (ret < 0) {
 		dev_err(&i2c->dev, "Failed to issue reset\n");
-		goto err_regmap;
+		goto err_enable;
 	}
 
 	if (pdata && pdata->in4_dc_measure) {
@@ -3686,30 +3686,22 @@
 	ret = snd_soc_register_codec(&i2c->dev,
 				     &soc_codec_dev_wm8962, &wm8962_dai, 1);
 	if (ret < 0)
-		goto err_regmap;
+		goto err_enable;
 
 	/* The drivers should power up as needed */
 	regulator_bulk_disable(ARRAY_SIZE(wm8962->supplies), wm8962->supplies);
 
 	return 0;
 
-err_regmap:
-	regmap_exit(wm8962->regmap);
 err_enable:
 	regulator_bulk_disable(ARRAY_SIZE(wm8962->supplies), wm8962->supplies);
-err_get:
-	regulator_bulk_free(ARRAY_SIZE(wm8962->supplies), wm8962->supplies);
 err:
 	return ret;
 }
 
-static __devexit int wm8962_i2c_remove(struct i2c_client *client)
+static int wm8962_i2c_remove(struct i2c_client *client)
 {
-	struct wm8962_priv *wm8962 = dev_get_drvdata(&client->dev);
-
 	snd_soc_unregister_codec(&client->dev);
-	regmap_exit(wm8962->regmap);
-	regulator_bulk_free(ARRAY_SIZE(wm8962->supplies), wm8962->supplies);
 	return 0;
 }
 
@@ -3773,7 +3765,7 @@
 		.pm = &wm8962_pm,
 	},
 	.probe =    wm8962_i2c_probe,
-	.remove =   __devexit_p(wm8962_i2c_remove),
+	.remove =   wm8962_i2c_remove,
 	.id_table = wm8962_i2c_id,
 };
 
diff --git a/sound/soc/codecs/wm8971.c b/sound/soc/codecs/wm8971.c
index 5ce6477..67aba78 100644
--- a/sound/soc/codecs/wm8971.c
+++ b/sound/soc/codecs/wm8971.c
@@ -19,6 +19,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>
@@ -34,7 +35,6 @@
 
 /* codec private data */
 struct wm8971_priv {
-	enum snd_soc_control_type control_type;
 	unsigned int sysclk;
 };
 
@@ -43,18 +43,50 @@
  * We can't read the WM8971 register space when we
  * are using 2 wire for device control, so we cache them instead.
  */
-static const u16 wm8971_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 wm8971_reg_defaults[] = {
+	{  0, 0x0097 },
+	{  1, 0x0097 },
+	{  2, 0x0079 },
+	{  3, 0x0079 },
+	{  4, 0x0000 },
+	{  5, 0x0008 },
+	{  6, 0x0000 },
+	{  7, 0x000a },
+	{  8, 0x0000 },
+	{  9, 0x0000 },
+	{ 10, 0x00ff },
+	{ 11, 0x00ff },
+	{ 12, 0x000f },
+	{ 13, 0x000f },
+	{ 14, 0x0000 },
+	{ 15, 0x0000 },
+	{ 16, 0x0000 },
+	{ 17, 0x007b },
+	{ 18, 0x0000 },
+	{ 19, 0x0032 },
+	{ 20, 0x0000 },
+	{ 21, 0x00c3 },
+	{ 22, 0x00c3 },
+	{ 23, 0x00c0 },
+	{ 24, 0x0000 },
+	{ 25, 0x0000 },
+	{ 26, 0x0000 },
+	{ 27, 0x0000 },
+	{ 28, 0x0000 },
+	{ 29, 0x0000 },
+	{ 30, 0x0000 },
+	{ 31, 0x0000 },
+	{ 32, 0x0000 },
+	{ 33, 0x0000 },
+	{ 34, 0x0050 },
+	{ 35, 0x0050 },
+	{ 36, 0x0050 },
+	{ 37, 0x0050 },
+	{ 38, 0x0050 },
+	{ 39, 0x0050 },
+	{ 40, 0x0079 },
+	{ 41, 0x0079 },
+	{ 42, 0x0079 },
 };
 
 #define wm8971_reset(c)	snd_soc_write(c, WM8971_RESET, 0)
@@ -613,11 +645,10 @@
 
 static int wm8971_probe(struct snd_soc_codec *codec)
 {
-	struct wm8971_priv *wm8971 = snd_soc_codec_get_drvdata(codec);
 	int ret = 0;
 	u16 reg;
 
-	ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8971->control_type);
+	ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP);
 	if (ret < 0) {
 		printk(KERN_ERR "wm8971: failed to set cache I/O: %d\n", ret);
 		return ret;
@@ -667,9 +698,6 @@
 	.suspend =	wm8971_suspend,
 	.resume =	wm8971_resume,
 	.set_bias_level = wm8971_set_bias_level,
-	.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),
@@ -679,10 +707,21 @@
 	.num_dapm_routes = ARRAY_SIZE(wm8971_dapm_routes),
 };
 
-static __devinit int wm8971_i2c_probe(struct i2c_client *i2c,
-				      const struct i2c_device_id *id)
+static const struct regmap_config wm8971_regmap = {
+	.reg_bits = 7,
+	.val_bits = 9,
+	.max_register = WM8971_MOUTV,
+
+	.reg_defaults = wm8971_reg_defaults,
+	.num_reg_defaults = ARRAY_SIZE(wm8971_reg_defaults),
+	.cache_type = REGCACHE_RBTREE,
+};
+
+static int wm8971_i2c_probe(struct i2c_client *i2c,
+			    const struct i2c_device_id *id)
 {
 	struct wm8971_priv *wm8971;
+	struct regmap *regmap;
 	int ret;
 
 	wm8971 = devm_kzalloc(&i2c->dev, sizeof(struct wm8971_priv),
@@ -690,7 +729,10 @@
 	if (wm8971 == NULL)
 		return -ENOMEM;
 
-	wm8971->control_type = SND_SOC_I2C;
+	regmap = devm_regmap_init_i2c(i2c, &wm8971_regmap);
+	if (IS_ERR(regmap))
+		return PTR_ERR(regmap);
+
 	i2c_set_clientdata(i2c, wm8971);
 
 	ret = snd_soc_register_codec(&i2c->dev,
@@ -699,7 +741,7 @@
 	return ret;
 }
 
-static __devexit int wm8971_i2c_remove(struct i2c_client *client)
+static int wm8971_i2c_remove(struct i2c_client *client)
 {
 	snd_soc_unregister_codec(&client->dev);
 	return 0;
@@ -717,7 +759,7 @@
 		.owner = THIS_MODULE,
 	},
 	.probe =    wm8971_i2c_probe,
-	.remove =   __devexit_p(wm8971_i2c_remove),
+	.remove =   wm8971_i2c_remove,
 	.id_table = wm8971_i2c_id,
 };
 
diff --git a/sound/soc/codecs/wm8974.c b/sound/soc/codecs/wm8974.c
index 9a39511..ea58b73 100644
--- a/sound/soc/codecs/wm8974.c
+++ b/sound/soc/codecs/wm8974.c
@@ -625,8 +625,8 @@
 	.num_dapm_routes = ARRAY_SIZE(wm8974_dapm_routes),
 };
 
-static __devinit int wm8974_i2c_probe(struct i2c_client *i2c,
-				      const struct i2c_device_id *id)
+static int wm8974_i2c_probe(struct i2c_client *i2c,
+			    const struct i2c_device_id *id)
 {
 	int ret;
 
@@ -636,7 +636,7 @@
 	return ret;
 }
 
-static __devexit int wm8974_i2c_remove(struct i2c_client *client)
+static int wm8974_i2c_remove(struct i2c_client *client)
 {
 	snd_soc_unregister_codec(&client->dev);
 
@@ -655,7 +655,7 @@
 		.owner = THIS_MODULE,
 	},
 	.probe =    wm8974_i2c_probe,
-	.remove =   __devexit_p(wm8974_i2c_remove),
+	.remove =   wm8974_i2c_remove,
 	.id_table = wm8974_i2c_id,
 };
 
diff --git a/sound/soc/codecs/wm8978.c b/sound/soc/codecs/wm8978.c
index 4c0a8e4..f347af3 100644
--- a/sound/soc/codecs/wm8978.c
+++ b/sound/soc/codecs/wm8978.c
@@ -527,9 +527,6 @@
 			return idx;
 
 		wm8978->mclk_idx = idx;
-
-		/* GPIO1 into default mode as input - before configuring PLL */
-		snd_soc_update_bits(codec, WM8978_GPIO_CONTROL, 7, 0);
 	} else {
 		return -EINVAL;
 	}
@@ -1038,8 +1035,8 @@
 	.num_reg_defaults = ARRAY_SIZE(wm8978_reg_defaults),
 };
 
-static __devinit int wm8978_i2c_probe(struct i2c_client *i2c,
-				      const struct i2c_device_id *id)
+static int wm8978_i2c_probe(struct i2c_client *i2c,
+			    const struct i2c_device_id *id)
 {
 	struct wm8978_priv *wm8978;
 	int ret;
@@ -1049,7 +1046,7 @@
 	if (wm8978 == NULL)
 		return -ENOMEM;
 
-	wm8978->regmap = regmap_init_i2c(i2c, &wm8978_regmap_config);
+	wm8978->regmap = devm_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);
@@ -1062,29 +1059,22 @@
 	ret = regmap_write(wm8978->regmap, WM8978_RESET, 0);
 	if (ret != 0) {
 		dev_err(&i2c->dev, "Failed to issue reset: %d\n", ret);
-		goto err;
+		return ret;
 	}
 
 	ret = snd_soc_register_codec(&i2c->dev,
 			&soc_codec_dev_wm8978, &wm8978_dai, 1);
 	if (ret != 0) {
 		dev_err(&i2c->dev, "Failed to register CODEC: %d\n", ret);
-		goto err;
+		return ret;
 	}
 
 	return 0;
-
-err:
-	regmap_exit(wm8978->regmap);
-	return ret;
 }
 
-static __devexit int wm8978_i2c_remove(struct i2c_client *client)
+static int wm8978_i2c_remove(struct i2c_client *client)
 {
-	struct wm8978_priv *wm8978 = i2c_get_clientdata(client);
-
 	snd_soc_unregister_codec(&client->dev);
-	regmap_exit(wm8978->regmap);
 
 	return 0;
 }
@@ -1101,7 +1091,7 @@
 		.owner = THIS_MODULE,
 	},
 	.probe =    wm8978_i2c_probe,
-	.remove =   __devexit_p(wm8978_i2c_remove),
+	.remove =   wm8978_i2c_remove,
 	.id_table = wm8978_i2c_id,
 };
 
diff --git a/sound/soc/codecs/wm8983.c b/sound/soc/codecs/wm8983.c
index d8879f2..9fe1e04 100644
--- a/sound/soc/codecs/wm8983.c
+++ b/sound/soc/codecs/wm8983.c
@@ -1087,7 +1087,7 @@
 };
 
 #if defined(CONFIG_SPI_MASTER)
-static int __devinit wm8983_spi_probe(struct spi_device *spi)
+static int wm8983_spi_probe(struct spi_device *spi)
 {
 	struct wm8983_priv *wm8983;
 	int ret;
@@ -1110,7 +1110,7 @@
 	return ret;
 }
 
-static int __devexit wm8983_spi_remove(struct spi_device *spi)
+static int wm8983_spi_remove(struct spi_device *spi)
 {
 	snd_soc_unregister_codec(&spi->dev);
 	return 0;
@@ -1122,13 +1122,13 @@
 		.owner = THIS_MODULE,
 	},
 	.probe = wm8983_spi_probe,
-	.remove = __devexit_p(wm8983_spi_remove)
+	.remove = wm8983_spi_remove
 };
 #endif
 
 #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
-static __devinit int wm8983_i2c_probe(struct i2c_client *i2c,
-				      const struct i2c_device_id *id)
+static int wm8983_i2c_probe(struct i2c_client *i2c,
+			    const struct i2c_device_id *id)
 {
 	struct wm8983_priv *wm8983;
 	int ret;
@@ -1152,7 +1152,7 @@
 	return ret;
 }
 
-static __devexit int wm8983_i2c_remove(struct i2c_client *client)
+static int wm8983_i2c_remove(struct i2c_client *client)
 {
 	snd_soc_unregister_codec(&client->dev);
 	return 0;
@@ -1170,7 +1170,7 @@
 		.owner = THIS_MODULE,
 	},
 	.probe = wm8983_i2c_probe,
-	.remove = __devexit_p(wm8983_i2c_remove),
+	.remove = wm8983_i2c_remove,
 	.id_table = wm8983_i2c_id
 };
 #endif
diff --git a/sound/soc/codecs/wm8985.c b/sound/soc/codecs/wm8985.c
index 14f6663..ab37826 100644
--- a/sound/soc/codecs/wm8985.c
+++ b/sound/soc/codecs/wm8985.c
@@ -1111,7 +1111,7 @@
 };
 
 #if defined(CONFIG_SPI_MASTER)
-static int __devinit wm8985_spi_probe(struct spi_device *spi)
+static int wm8985_spi_probe(struct spi_device *spi)
 {
 	struct wm8985_priv *wm8985;
 	int ret;
@@ -1122,33 +1122,22 @@
 
 	spi_set_drvdata(spi, wm8985);
 
-	wm8985->regmap = regmap_init_spi(spi, &wm8985_regmap);
+	wm8985->regmap = devm_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;
+		return ret;
 	}
 
 	ret = snd_soc_register_codec(&spi->dev,
 				     &soc_codec_dev_wm8985, &wm8985_dai, 1);
-	if (ret != 0)
-		goto err;
-
-	return 0;
-
-err:
-	regmap_exit(wm8985->regmap);
 	return ret;
 }
 
-static int __devexit wm8985_spi_remove(struct spi_device *spi)
+static int wm8985_spi_remove(struct spi_device *spi)
 {
-	struct wm8985_priv *wm8985 = spi_get_drvdata(spi);
-
 	snd_soc_unregister_codec(&spi->dev);
-	regmap_exit(wm8985->regmap);
-
 	return 0;
 }
 
@@ -1158,13 +1147,13 @@
 		.owner = THIS_MODULE,
 	},
 	.probe = wm8985_spi_probe,
-	.remove = __devexit_p(wm8985_spi_remove)
+	.remove = wm8985_spi_remove
 };
 #endif
 
 #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
-static __devinit int wm8985_i2c_probe(struct i2c_client *i2c,
-				      const struct i2c_device_id *id)
+static int wm8985_i2c_probe(struct i2c_client *i2c,
+			    const struct i2c_device_id *id)
 {
 	struct wm8985_priv *wm8985;
 	int ret;
@@ -1175,33 +1164,22 @@
 
 	i2c_set_clientdata(i2c, wm8985);
 
-	wm8985->regmap = regmap_init_i2c(i2c, &wm8985_regmap);
+	wm8985->regmap = devm_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;
+		return ret;
 	}
 
 	ret = snd_soc_register_codec(&i2c->dev,
 				     &soc_codec_dev_wm8985, &wm8985_dai, 1);
-	if (ret != 0)
-		goto err;
-
-	return 0;
-
-err:
-	regmap_exit(wm8985->regmap);
 	return ret;
 }
 
-static __devexit int wm8985_i2c_remove(struct i2c_client *i2c)
+static int wm8985_i2c_remove(struct i2c_client *i2c)
 {
-	struct wm8985_priv *wm8985 = i2c_get_clientdata(i2c);
-
 	snd_soc_unregister_codec(&i2c->dev);
-	regmap_exit(wm8985->regmap);
-
 	return 0;
 }
 
@@ -1217,7 +1195,7 @@
 		.owner = THIS_MODULE,
 	},
 	.probe = wm8985_i2c_probe,
-	.remove = __devexit_p(wm8985_i2c_remove),
+	.remove = wm8985_i2c_remove,
 	.id_table = wm8985_i2c_id
 };
 #endif
diff --git a/sound/soc/codecs/wm8988.c b/sound/soc/codecs/wm8988.c
index 1d4c5cf..39b9acc 100644
--- a/sound/soc/codecs/wm8988.c
+++ b/sound/soc/codecs/wm8988.c
@@ -872,7 +872,7 @@
 };
 
 #if defined(CONFIG_SPI_MASTER)
-static int __devinit wm8988_spi_probe(struct spi_device *spi)
+static int wm8988_spi_probe(struct spi_device *spi)
 {
 	struct wm8988_priv *wm8988;
 	int ret;
@@ -882,7 +882,7 @@
 	if (wm8988 == NULL)
 		return -ENOMEM;
 
-	wm8988->regmap = regmap_init_spi(spi, &wm8988_regmap);
+	wm8988->regmap = devm_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);
@@ -893,17 +893,12 @@
 
 	ret = snd_soc_register_codec(&spi->dev,
 			&soc_codec_dev_wm8988, &wm8988_dai, 1);
-	if (ret != 0)
-		regmap_exit(wm8988->regmap);
-
 	return ret;
 }
 
-static int __devexit wm8988_spi_remove(struct spi_device *spi)
+static int wm8988_spi_remove(struct spi_device *spi)
 {
-	struct wm8988_priv *wm8988 = spi_get_drvdata(spi);
 	snd_soc_unregister_codec(&spi->dev);
-	regmap_exit(wm8988->regmap);
 	return 0;
 }
 
@@ -913,13 +908,13 @@
 		.owner	= THIS_MODULE,
 	},
 	.probe		= wm8988_spi_probe,
-	.remove		= __devexit_p(wm8988_spi_remove),
+	.remove		= wm8988_spi_remove,
 };
 #endif /* CONFIG_SPI_MASTER */
 
 #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
-static __devinit int wm8988_i2c_probe(struct i2c_client *i2c,
-				      const struct i2c_device_id *id)
+static int wm8988_i2c_probe(struct i2c_client *i2c,
+			    const struct i2c_device_id *id)
 {
 	struct wm8988_priv *wm8988;
 	int ret;
@@ -931,7 +926,7 @@
 
 	i2c_set_clientdata(i2c, wm8988);
 
-	wm8988->regmap = regmap_init_i2c(i2c, &wm8988_regmap);
+	wm8988->regmap = devm_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);
@@ -940,17 +935,12 @@
 
 	ret =  snd_soc_register_codec(&i2c->dev,
 			&soc_codec_dev_wm8988, &wm8988_dai, 1);
-	if (ret != 0)
-		regmap_exit(wm8988->regmap);
-
 	return ret;
 }
 
-static __devexit int wm8988_i2c_remove(struct i2c_client *client)
+static int wm8988_i2c_remove(struct i2c_client *client)
 {
-	struct wm8988_priv *wm8988 = i2c_get_clientdata(client);
 	snd_soc_unregister_codec(&client->dev);
-	regmap_exit(wm8988->regmap);
 	return 0;
 }
 
@@ -966,7 +956,7 @@
 		.owner = THIS_MODULE,
 	},
 	.probe =    wm8988_i2c_probe,
-	.remove =   __devexit_p(wm8988_i2c_remove),
+	.remove =   wm8988_i2c_remove,
 	.id_table = wm8988_i2c_id,
 };
 #endif
diff --git a/sound/soc/codecs/wm8990.c b/sound/soc/codecs/wm8990.c
index c28c83e..837978e 100644
--- a/sound/soc/codecs/wm8990.c
+++ b/sound/soc/codecs/wm8990.c
@@ -1382,8 +1382,8 @@
 };
 
 #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
-static __devinit int wm8990_i2c_probe(struct i2c_client *i2c,
-				      const struct i2c_device_id *id)
+static int wm8990_i2c_probe(struct i2c_client *i2c,
+			    const struct i2c_device_id *id)
 {
 	struct wm8990_priv *wm8990;
 	int ret;
@@ -1401,7 +1401,7 @@
 	return ret;
 }
 
-static __devexit int wm8990_i2c_remove(struct i2c_client *client)
+static int wm8990_i2c_remove(struct i2c_client *client)
 {
 	snd_soc_unregister_codec(&client->dev);
 
@@ -1420,7 +1420,7 @@
 		.owner = THIS_MODULE,
 	},
 	.probe =    wm8990_i2c_probe,
-	.remove =   __devexit_p(wm8990_i2c_remove),
+	.remove =   wm8990_i2c_remove,
 	.id_table = wm8990_i2c_id,
 };
 #endif
diff --git a/sound/soc/codecs/wm8991.c b/sound/soc/codecs/wm8991.c
index fe439f02..3a39df7 100644
--- a/sound/soc/codecs/wm8991.c
+++ b/sound/soc/codecs/wm8991.c
@@ -1357,8 +1357,8 @@
 	.reg_cache_default = wm8991_reg_defs
 };
 
-static __devinit int wm8991_i2c_probe(struct i2c_client *i2c,
-				      const struct i2c_device_id *id)
+static int wm8991_i2c_probe(struct i2c_client *i2c,
+			    const struct i2c_device_id *id)
 {
 	struct wm8991_priv *wm8991;
 	int ret;
@@ -1376,7 +1376,7 @@
 	return ret;
 }
 
-static __devexit int wm8991_i2c_remove(struct i2c_client *client)
+static int wm8991_i2c_remove(struct i2c_client *client)
 {
 	snd_soc_unregister_codec(&client->dev);
 
@@ -1395,7 +1395,7 @@
 		.owner = THIS_MODULE,
 	},
 	.probe = wm8991_i2c_probe,
-	.remove = __devexit_p(wm8991_i2c_remove),
+	.remove = wm8991_i2c_remove,
 	.id_table = wm8991_i2c_id,
 };
 
diff --git a/sound/soc/codecs/wm8993.c b/sound/soc/codecs/wm8993.c
index 94737a3..433d59a 100644
--- a/sound/soc/codecs/wm8993.c
+++ b/sound/soc/codecs/wm8993.c
@@ -1645,8 +1645,8 @@
 	.set_bias_level = wm8993_set_bias_level,
 };
 
-static __devinit int wm8993_i2c_probe(struct i2c_client *i2c,
-				      const struct i2c_device_id *id)
+static int wm8993_i2c_probe(struct i2c_client *i2c,
+			    const struct i2c_device_id *id)
 {
 	struct wm8993_priv *wm8993;
 	unsigned int reg;
@@ -1660,7 +1660,7 @@
 	wm8993->dev = &i2c->dev;
 	init_completion(&wm8993->fll_lock);
 
-	wm8993->regmap = regmap_init_i2c(i2c, &wm8993_regmap);
+	wm8993->regmap = devm_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);
@@ -1672,18 +1672,18 @@
 	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),
+	ret = devm_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;
+		return ret;
 	}
 
 	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;
+		return ret;
 	}
 
 	ret = regmap_read(wm8993->regmap, WM8993_SOFTWARE_RESET, &reg);
@@ -1742,23 +1742,17 @@
 		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 *i2c)
+static int wm8993_i2c_remove(struct i2c_client *i2c)
 {
 	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;
 }
@@ -1775,7 +1769,7 @@
 		.owner = THIS_MODULE,
 	},
 	.probe =    wm8993_i2c_probe,
-	.remove =   __devexit_p(wm8993_i2c_remove),
+	.remove =   wm8993_i2c_remove,
 	.id_table = wm8993_i2c_id,
 };
 
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c
index b2b2b37..3b269fa 100644
--- a/sound/soc/codecs/wm8994.c
+++ b/sound/soc/codecs/wm8994.c
@@ -91,8 +91,6 @@
 	WM8994_AIF2_EQ_GAINS_1,
 };
 
-static void wm8958_default_micdet(u16 status, void *data);
-
 static const struct wm8958_micd_rate micdet_rates[] = {
 	{ 32768,       true,  1, 4 },
 	{ 32768,       false, 1, 1 },
@@ -110,15 +108,12 @@
 static void wm8958_micd_set_rate(struct snd_soc_codec *codec)
 {
 	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+	struct wm8994 *control = wm8994->wm8994;
 	int best, i, sysclk, val;
 	bool idle;
 	const struct wm8958_micd_rate *rates;
 	int num_rates;
 
-	if (!(wm8994->pdata && wm8994->pdata->micd_rates) &&
-	    wm8994->jack_cb != wm8958_default_micdet)
-		return;
-
 	idle = !wm8994->jack_mic;
 
 	sysclk = snd_soc_read(codec, WM8994_CLOCKING_1);
@@ -127,9 +122,9 @@
 	else
 		sysclk = wm8994->aifclk[0];
 
-	if (wm8994->pdata && wm8994->pdata->micd_rates) {
-		rates = wm8994->pdata->micd_rates;
-		num_rates = wm8994->pdata->num_micd_rates;
+	if (control->pdata.micd_rates) {
+		rates = control->pdata.micd_rates;
+		num_rates = control->pdata.num_micd_rates;
 	} else if (wm8994->jackdet) {
 		rates = jackdet_rates;
 		num_rates = ARRAY_SIZE(jackdet_rates);
@@ -326,7 +321,8 @@
 static void wm8994_set_drc(struct snd_soc_codec *codec, int drc)
 {
 	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
-	struct wm8994_pdata *pdata = wm8994->pdata;
+	struct wm8994 *control = wm8994->wm8994;
+	struct wm8994_pdata *pdata = &control->pdata;
 	int base = wm8994_drc_base[drc];
 	int cfg = wm8994->drc_cfg[drc];
 	int save, i;
@@ -362,7 +358,8 @@
 {
 	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
 	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
-	struct wm8994_pdata *pdata = wm8994->pdata;
+	struct wm8994 *control = wm8994->wm8994;
+	struct wm8994_pdata *pdata = &control->pdata;
 	int drc = wm8994_get_drc(kcontrol->id.name);
 	int value = ucontrol->value.integer.value[0];
 
@@ -394,7 +391,8 @@
 static void wm8994_set_retune_mobile(struct snd_soc_codec *codec, int block)
 {
 	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
-	struct wm8994_pdata *pdata = wm8994->pdata;
+	struct wm8994 *control = wm8994->wm8994;
+	struct wm8994_pdata *pdata = &control->pdata;
 	int base = wm8994_retune_mobile_base[block];
 	int iface, best, best_val, save, i, cfg;
 
@@ -465,7 +463,8 @@
 {
 	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
 	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
-	struct wm8994_pdata *pdata = wm8994->pdata;
+	struct wm8994 *control = wm8994->wm8994;
+	struct wm8994_pdata *pdata = &control->pdata;
 	int block = wm8994_get_retune_mobile_block(kcontrol->id.name);
 	int value = ucontrol->value.integer.value[0];
 
@@ -736,7 +735,7 @@
 {
 	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
 
-	if (!wm8994->jackdet || !wm8994->jack_cb)
+	if (!wm8994->jackdet || !wm8994->micdet[0].jack)
 		return;
 
 	if (wm8994->active_refcount)
@@ -862,7 +861,7 @@
 					    WM8994_BIAS_SRC |
 					    WM8994_STARTUP_BIAS_ENA |
 					    WM8994_VMID_BUF_ENA |
-					    (0x3 << WM8994_VMID_RAMP_SHIFT));
+					    (0x2 << WM8994_VMID_RAMP_SHIFT));
 
 			/* Main bias enable, VMID=2x40k */
 			snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1,
@@ -870,7 +869,7 @@
 					    WM8994_VMID_SEL_MASK,
 					    WM8994_BIAS_ENA | 0x2);
 
-			msleep(50);
+			msleep(300);
 
 			snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
 					    WM8994_VMID_RAMP_MASK |
@@ -939,16 +938,10 @@
 				    WM8994_BIAS_SRC |
 				    WM8994_VMID_DISCH);
 
-		switch (wm8994->vmid_mode) {
-		case WM8994_VMID_FORCE:
-			msleep(350);
-			break;
-		default:
-			break;
-		}
+		snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1,
+				    WM8994_VMID_SEL_MASK, 0);
 
-		snd_soc_update_bits(codec, WM8994_ADDITIONAL_CONTROL,
-				    WM8994_VROI, WM8994_VROI);
+		msleep(400);
 
 		/* Active discharge */
 		snd_soc_update_bits(codec, WM8994_ANTIPOP_1,
@@ -957,17 +950,12 @@
 				    WM8994_LINEOUT1_DISCH |
 				    WM8994_LINEOUT2_DISCH);
 
-		msleep(150);
-
 		snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_3,
 				    WM8994_LINEOUT1N_ENA |
 				    WM8994_LINEOUT1P_ENA |
 				    WM8994_LINEOUT2N_ENA |
 				    WM8994_LINEOUT2P_ENA, 0);
 
-		snd_soc_update_bits(codec, WM8994_ADDITIONAL_CONTROL,
-				    WM8994_VROI, 0);
-
 		/* Switch off startup biases */
 		snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
 				    WM8994_BIAS_SRC |
@@ -976,10 +964,7 @@
 				    WM8994_VMID_RAMP_MASK, 0);
 
 		snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1,
-				    WM8994_BIAS_ENA | WM8994_VMID_SEL_MASK, 0);
-
-		snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
-				    WM8994_VMID_RAMP_MASK, 0);
+				    WM8994_VMID_SEL_MASK, 0);
 	}
 
 	pm_runtime_put(codec->dev);
@@ -2277,6 +2262,18 @@
 
 	configure_clock(codec);
 
+	/*
+	 * If SYSCLK will be less than 50kHz adjust AIFnCLK dividers
+	 * for detection.
+	 */
+	if (max(wm8994->aifclk[0], wm8994->aifclk[1]) < 50000) {
+		dev_dbg(codec->dev, "Configuring AIFs for 128fs\n");
+		snd_soc_update_bits(codec, WM8994_AIF1_RATE,
+				    WM8994_AIF1CLK_RATE_MASK, 0x1);
+		snd_soc_update_bits(codec, WM8994_AIF2_RATE,
+				    WM8994_AIF2CLK_RATE_MASK, 0x1);
+	}
+
 	return 0;
 }
 
@@ -2365,6 +2362,18 @@
 
 	configure_clock(codec);
 
+	/*
+	 * If SYSCLK will be less than 50kHz adjust AIFnCLK dividers
+	 * for detection.
+	 */
+	if (max(wm8994->aifclk[0], wm8994->aifclk[1]) < 50000) {
+		dev_dbg(codec->dev, "Configuring AIFs for 128fs\n");
+		snd_soc_update_bits(codec, WM8994_AIF1_RATE,
+				    WM8994_AIF1CLK_RATE_MASK, 0x1);
+		snd_soc_update_bits(codec, WM8994_AIF2_RATE,
+				    WM8994_AIF2CLK_RATE_MASK, 0x1);
+	}
+
 	return 0;
 }
 
@@ -3082,7 +3091,8 @@
 static void wm8994_handle_retune_mobile_pdata(struct wm8994_priv *wm8994)
 {
 	struct snd_soc_codec *codec = wm8994->hubs.codec;
-	struct wm8994_pdata *pdata = wm8994->pdata;
+	struct wm8994 *control = wm8994->wm8994;
+	struct wm8994_pdata *pdata = &control->pdata;
 	struct snd_kcontrol_new controls[] = {
 		SOC_ENUM_EXT("AIF1.1 EQ Mode",
 			     wm8994->retune_mobile_enum,
@@ -3149,7 +3159,8 @@
 static void wm8994_handle_pdata(struct wm8994_priv *wm8994)
 {
 	struct snd_soc_codec *codec = wm8994->hubs.codec;
-	struct wm8994_pdata *pdata = wm8994->pdata;
+	struct wm8994 *control = wm8994->wm8994;
+	struct wm8994_pdata *pdata = &control->pdata;
 	int ret, i;
 
 	if (!pdata)
@@ -3389,38 +3400,80 @@
 	return IRQ_HANDLED;
 }
 
-/* Default microphone detection handler for WM8958 - the user can
- * override this if they wish.
- */
-static void wm8958_default_micdet(u16 status, void *data)
+static void wm1811_micd_stop(struct snd_soc_codec *codec)
 {
-	struct snd_soc_codec *codec = data;
+	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+
+	if (!wm8994->jackdet)
+		return;
+
+	mutex_lock(&wm8994->accdet_lock);
+
+	snd_soc_update_bits(codec, WM8958_MIC_DETECT_1, WM8958_MICD_ENA, 0);
+
+	wm1811_jackdet_set_mode(codec, WM1811_JACKDET_MODE_JACK);
+
+	mutex_unlock(&wm8994->accdet_lock);
+
+	if (wm8994->wm8994->pdata.jd_ext_cap)
+		snd_soc_dapm_disable_pin(&codec->dapm,
+					 "MICBIAS2");
+}
+
+static void wm8958_button_det(struct snd_soc_codec *codec, u16 status)
+{
 	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
 	int report;
 
-	dev_dbg(codec->dev, "MICDET %x\n", status);
+	report = 0;
+	if (status & 0x4)
+		report |= SND_JACK_BTN_0;
+
+	if (status & 0x8)
+		report |= SND_JACK_BTN_1;
+
+	if (status & 0x10)
+		report |= SND_JACK_BTN_2;
+
+	if (status & 0x20)
+		report |= SND_JACK_BTN_3;
+
+	if (status & 0x40)
+		report |= SND_JACK_BTN_4;
+
+	if (status & 0x80)
+		report |= SND_JACK_BTN_5;
+
+	snd_soc_jack_report(wm8994->micdet[0].jack, report,
+			    wm8994->btn_mask);
+}
+
+static void wm8958_mic_id(void *data, u16 status)
+{
+	struct snd_soc_codec *codec = data;
+	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
 
 	/* Either nothing present or just starting detection */
 	if (!(status & WM8958_MICD_STS)) {
-		if (!wm8994->jackdet) {
-			/* If nothing present then clear our statuses */
-			dev_dbg(codec->dev, "Detected open circuit\n");
-			wm8994->jack_mic = false;
-			wm8994->mic_detecting = true;
+		/* If nothing present then clear our statuses */
+		dev_dbg(codec->dev, "Detected open circuit\n");
+		wm8994->jack_mic = false;
+		wm8994->mic_detecting = true;
 
-			wm8958_micd_set_rate(codec);
+		wm1811_micd_stop(codec);
 
-			snd_soc_jack_report(wm8994->micdet[0].jack, 0,
-					    wm8994->btn_mask |
-					    SND_JACK_HEADSET);
-		}
+		wm8958_micd_set_rate(codec);
+
+		snd_soc_jack_report(wm8994->micdet[0].jack, 0,
+				    wm8994->btn_mask |
+				    SND_JACK_HEADSET);
 		return;
 	}
 
 	/* If the measurement is showing a high impedence we've got a
 	 * microphone.
 	 */
-	if (wm8994->mic_detecting && (status & 0x600)) {
+	if (status & 0x600) {
 		dev_dbg(codec->dev, "Detected microphone\n");
 
 		wm8994->mic_detecting = false;
@@ -3433,64 +3486,67 @@
 	}
 
 
-	if (wm8994->mic_detecting && status & 0xfc) {
+	if (status & 0xfc) {
 		dev_dbg(codec->dev, "Detected headphone\n");
 		wm8994->mic_detecting = false;
 
 		wm8958_micd_set_rate(codec);
 
 		/* If we have jackdet that will detect removal */
-		if (wm8994->jackdet) {
-			mutex_lock(&wm8994->accdet_lock);
-
-			snd_soc_update_bits(codec, WM8958_MIC_DETECT_1,
-					    WM8958_MICD_ENA, 0);
-
-			wm1811_jackdet_set_mode(codec,
-						WM1811_JACKDET_MODE_JACK);
-
-			mutex_unlock(&wm8994->accdet_lock);
-
-			if (wm8994->pdata->jd_ext_cap)
-				snd_soc_dapm_disable_pin(&codec->dapm,
-							 "MICBIAS2");
-		}
+		wm1811_micd_stop(codec);
 
 		snd_soc_jack_report(wm8994->micdet[0].jack, SND_JACK_HEADPHONE,
 				    SND_JACK_HEADSET);
 	}
+}
 
-	/* Report short circuit as a button */
-	if (wm8994->jack_mic) {
-		report = 0;
-		if (status & 0x4)
-			report |= SND_JACK_BTN_0;
+/* Deferred mic detection to allow for extra settling time */
+static void wm1811_mic_work(struct work_struct *work)
+{
+	struct wm8994_priv *wm8994 = container_of(work, struct wm8994_priv,
+						  mic_work.work);
+	struct wm8994 *control = wm8994->wm8994;
+	struct snd_soc_codec *codec = wm8994->hubs.codec;
 
-		if (status & 0x8)
-			report |= SND_JACK_BTN_1;
+	pm_runtime_get_sync(codec->dev);
 
-		if (status & 0x10)
-			report |= SND_JACK_BTN_2;
-
-		if (status & 0x20)
-			report |= SND_JACK_BTN_3;
-
-		if (status & 0x40)
-			report |= SND_JACK_BTN_4;
-
-		if (status & 0x80)
-			report |= SND_JACK_BTN_5;
-
-		snd_soc_jack_report(wm8994->micdet[0].jack, report,
-				    wm8994->btn_mask);
+	/* If required for an external cap force MICBIAS on */
+	if (control->pdata.jd_ext_cap) {
+		snd_soc_dapm_force_enable_pin(&codec->dapm,
+					      "MICBIAS2");
+		snd_soc_dapm_sync(&codec->dapm);
 	}
+
+	mutex_lock(&wm8994->accdet_lock);
+
+	dev_dbg(codec->dev, "Starting mic detection\n");
+
+	/* Use a user-supplied callback if we have one */
+	if (wm8994->micd_cb) {
+		wm8994->micd_cb(wm8994->micd_cb_data);
+	} else {
+		/*
+		 * Start off measument of microphone impedence to find out
+		 * what's actually there.
+		 */
+		wm8994->mic_detecting = true;
+		wm1811_jackdet_set_mode(codec, WM1811_JACKDET_MODE_MIC);
+
+		snd_soc_update_bits(codec, WM8958_MIC_DETECT_1,
+				    WM8958_MICD_ENA, WM8958_MICD_ENA);
+	}
+
+	mutex_unlock(&wm8994->accdet_lock);
+
+	pm_runtime_put(codec->dev);
 }
 
 static irqreturn_t wm1811_jackdet_irq(int irq, void *data)
 {
 	struct wm8994_priv *wm8994 = data;
+	struct wm8994 *control = wm8994->wm8994;
 	struct snd_soc_codec *codec = wm8994->hubs.codec;
-	int reg;
+	int reg, delay;
 	bool present;
 
 	pm_runtime_get_sync(codec->dev);
@@ -3521,18 +3577,14 @@
 		snd_soc_update_bits(codec, WM1811_JACKDET_CTRL,
 				    WM1811_JACKDET_DB, 0);
 
-		/*
-		 * Start off measument of microphone impedence to find
-		 * out what's actually there.
-		 */
-		wm8994->mic_detecting = true;
-		wm1811_jackdet_set_mode(codec, WM1811_JACKDET_MODE_MIC);
-
-		snd_soc_update_bits(codec, WM8958_MIC_DETECT_1,
-				    WM8958_MICD_ENA, WM8958_MICD_ENA);
+		delay = control->pdata.micdet_delay;
+		schedule_delayed_work(&wm8994->mic_work,
+				      msecs_to_jiffies(delay));
 	} else {
 		dev_dbg(codec->dev, "Jack not detected\n");
 
+		cancel_delayed_work_sync(&wm8994->mic_work);
+
 		snd_soc_update_bits(codec, WM8958_MICBIAS2,
 				    WM8958_MICB2_DISCH, WM8958_MICB2_DISCH);
 
@@ -3549,14 +3601,9 @@
 
 	mutex_unlock(&wm8994->accdet_lock);
 
-	/* If required for an external cap force MICBIAS on */
-	if (wm8994->pdata->jd_ext_cap) {
-		if (present)
-			snd_soc_dapm_force_enable_pin(&codec->dapm,
-						      "MICBIAS2");
-		else
-			snd_soc_dapm_disable_pin(&codec->dapm, "MICBIAS2");
-	}
+	/* Turn off MICBIAS if it was on for an external cap */
+	if (control->pdata.jd_ext_cap && !present)
+		snd_soc_dapm_disable_pin(&codec->dapm, "MICBIAS2");
 
 	if (present)
 		snd_soc_jack_report(wm8994->micdet[0].jack,
@@ -3599,7 +3646,8 @@
  * detection algorithm.
  */
 int wm8958_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
-		      wm8958_micdet_cb cb, void *cb_data)
+		      wm1811_micdet_cb det_cb, void *det_cb_data,
+		      wm1811_mic_id_cb id_cb, void *id_cb_data)
 {
 	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
 	struct wm8994 *control = wm8994->wm8994;
@@ -3614,27 +3662,32 @@
 	}
 
 	if (jack) {
-		if (!cb) {
-			dev_dbg(codec->dev, "Using default micdet callback\n");
-			cb = wm8958_default_micdet;
-			cb_data = codec;
-		}
-
 		snd_soc_dapm_force_enable_pin(&codec->dapm, "CLK_SYS");
 		snd_soc_dapm_sync(&codec->dapm);
 
 		wm8994->micdet[0].jack = jack;
-		wm8994->jack_cb = cb;
-		wm8994->jack_cb_data = cb_data;
 
-		wm8994->mic_detecting = true;
-		wm8994->jack_mic = false;
+		if (det_cb) {
+			wm8994->micd_cb = det_cb;
+			wm8994->micd_cb_data = det_cb_data;
+		} else {
+			wm8994->mic_detecting = true;
+			wm8994->jack_mic = false;
+		}
+
+		if (id_cb) {
+			wm8994->mic_id_cb = id_cb;
+			wm8994->mic_id_cb_data = id_cb_data;
+		} else {
+			wm8994->mic_id_cb = wm8958_mic_id;
+			wm8994->mic_id_cb_data = codec;
+		}
 
 		wm8958_micd_set_rate(codec);
 
 		/* Detect microphones and short circuits by default */
-		if (wm8994->pdata->micd_lvl_sel)
-			micd_lvl_sel = wm8994->pdata->micd_lvl_sel;
+		if (control->pdata.micd_lvl_sel)
+			micd_lvl_sel = control->pdata.micd_lvl_sel;
 		else
 			micd_lvl_sel = 0x41;
 
@@ -3728,10 +3781,22 @@
 	trace_snd_soc_jack_irq(dev_name(codec->dev));
 #endif
 
-	if (wm8994->jack_cb)
-		wm8994->jack_cb(reg, wm8994->jack_cb_data);
+	/* Avoid a transient report when the accessory is being removed */
+	if (wm8994->jackdet) {
+		reg = snd_soc_read(codec, WM1811_JACKDET_CTRL);
+		if (reg < 0) {
+			dev_err(codec->dev, "Failed to read jack status: %d\n",
+				reg);
+		} else if (!(reg & WM1811_JACKDET_LVL)) {
+			dev_dbg(codec->dev, "Ignoring removed jack\n");
+			return IRQ_HANDLED;
+		}
+	}
+
+	if (wm8994->mic_detecting)
+		wm8994->mic_id_cb(wm8994->mic_id_cb_data, reg);
 	else
-		dev_warn(codec->dev, "Accessory detection with no callback\n");
+		wm8958_button_det(codec, reg);
 
 out:
 	pm_runtime_put(codec->dev);
@@ -3779,15 +3844,24 @@
 	snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_REGMAP);
 
 	mutex_init(&wm8994->accdet_lock);
-	INIT_DELAYED_WORK(&wm8994->mic_work, wm8994_mic_work);
 	INIT_DELAYED_WORK(&wm8994->jackdet_bootstrap,
 			  wm1811_jackdet_bootstrap);
 
+	switch (control->type) {
+	case WM8994:
+		INIT_DELAYED_WORK(&wm8994->mic_work, wm8994_mic_work);
+		break;
+	case WM1811:
+		INIT_DELAYED_WORK(&wm8994->mic_work, wm1811_mic_work);
+		break;
+	default:
+		break;
+	}
+
 	for (i = 0; i < ARRAY_SIZE(wm8994->fll_locked); i++)
 		init_completion(&wm8994->fll_locked[i]);
 
-	if (wm8994->pdata && wm8994->pdata->micdet_irq)
-		wm8994->micdet_irq = wm8994->pdata->micdet_irq;
+	wm8994->micdet_irq = control->pdata.micdet_irq;
 
 	pm_runtime_enable(codec->dev);
 	pm_runtime_idle(codec->dev);
@@ -3800,8 +3874,8 @@
 	switch (control->type) {
 	case WM8994:
 		/* Single ended line outputs should have VMID on. */
-		if (!wm8994->pdata->lineout1_diff ||
-		    !wm8994->pdata->lineout2_diff)
+		if (!control->pdata.lineout1_diff ||
+		    !control->pdata.lineout2_diff)
 			codec->dapm.idle_bias_off = 0;
 
 		switch (wm8994->revision) {
@@ -3839,20 +3913,8 @@
 		wm8994->hubs.no_cache_dac_hp_direct = true;
 		wm8994->fll_byp = true;
 
-		switch (control->cust_id) {
-		case 0:
-		case 2:
-			wm8994->hubs.dcs_codes_l = -9;
-			wm8994->hubs.dcs_codes_r = -7;
-			break;
-		case 1:
-		case 3:
-			wm8994->hubs.dcs_codes_l = -8;
-			wm8994->hubs.dcs_codes_r = -7;
-			break;
-		default:
-			break;
-		}
+		wm8994->hubs.dcs_codes_l = -9;
+		wm8994->hubs.dcs_codes_r = -7;
 
 		snd_soc_update_bits(codec, WM8994_ANALOGUE_HP_1,
 				    WM1811_HPOUT1_ATTN, WM1811_HPOUT1_ATTN);
@@ -4225,7 +4287,7 @@
 	.set_bias_level = wm8994_set_bias_level,
 };
 
-static int __devinit wm8994_probe(struct platform_device *pdev)
+static int wm8994_probe(struct platform_device *pdev)
 {
 	struct wm8994_priv *wm8994;
 
@@ -4236,13 +4298,12 @@
 	platform_set_drvdata(pdev, wm8994);
 
 	wm8994->wm8994 = dev_get_drvdata(pdev->dev.parent);
-	wm8994->pdata = dev_get_platdata(pdev->dev.parent);
 
 	return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_wm8994,
 			wm8994_dai, ARRAY_SIZE(wm8994_dai));
 }
 
-static int __devexit wm8994_remove(struct platform_device *pdev)
+static int wm8994_remove(struct platform_device *pdev)
 {
 	snd_soc_unregister_codec(&pdev->dev);
 	return 0;
@@ -4266,7 +4327,7 @@
 {
 	struct wm8994_priv *wm8994 = dev_get_drvdata(dev);
 
-	if (wm8994->jackdet && wm8994->jack_cb)
+	if (wm8994->jackdet && wm8994->jackdet_mode)
 		regmap_update_bits(wm8994->wm8994->regmap, WM8994_ANTIPOP_2,
 				   WM1811_JACKDET_MODE_MASK,
 				   WM1811_JACKDET_MODE_AUDIO);
@@ -4286,7 +4347,7 @@
 		.pm = &wm8994_pm_ops,
 	},
 	.probe = wm8994_probe,
-	.remove = __devexit_p(wm8994_remove),
+	.remove = wm8994_remove,
 };
 
 module_platform_driver(wm8994_codec_driver);
diff --git a/sound/soc/codecs/wm8994.h b/sound/soc/codecs/wm8994.h
index ccbce57..45f1927 100644
--- a/sound/soc/codecs/wm8994.h
+++ b/sound/soc/codecs/wm8994.h
@@ -39,12 +39,14 @@
 	WM8994_VMID_FORCE,
 };
 
-typedef void (*wm8958_micdet_cb)(u16 status, void *data);
+typedef void (*wm1811_micdet_cb)(void *data);
+typedef void (*wm1811_mic_id_cb)(void *data, u16 status);
 
 int wm8994_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
 		      int micbias);
 int wm8958_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
-		      wm8958_micdet_cb cb, void *cb_data);
+		      wm1811_micdet_cb cb, void *det_cb_data,
+		      wm1811_mic_id_cb id_cb, void *id_cb_data);
 
 int wm8994_vmid_mode(struct snd_soc_codec *codec, enum wm8994_vmid_mode mode);
 
@@ -138,12 +140,13 @@
 	int jackdet_mode;
 	struct delayed_work jackdet_bootstrap;
 
-	wm8958_micdet_cb jack_cb;
-	void *jack_cb_data;
 	int micdet_irq;
+	wm1811_micdet_cb micd_cb;
+	void *micd_cb_data;
+	wm1811_mic_id_cb mic_id_cb;
+	void *mic_id_cb_data;
 
 	int revision;
-	struct wm8994_pdata *pdata;
 
 	unsigned int aif1clk_enable:1;
 	unsigned int aif2clk_enable:1;
diff --git a/sound/soc/codecs/wm8995.c b/sound/soc/codecs/wm8995.c
index 28c89b0..90a65c4 100644
--- a/sound/soc/codecs/wm8995.c
+++ b/sound/soc/codecs/wm8995.c
@@ -2256,46 +2256,33 @@
 };
 
 #if defined(CONFIG_SPI_MASTER)
-static int __devinit wm8995_spi_probe(struct spi_device *spi)
+static int wm8995_spi_probe(struct spi_device *spi)
 {
 	struct wm8995_priv *wm8995;
 	int ret;
 
-	wm8995 = kzalloc(sizeof *wm8995, GFP_KERNEL);
+	wm8995 = devm_kzalloc(&spi->dev, sizeof(*wm8995), GFP_KERNEL);
 	if (!wm8995)
 		return -ENOMEM;
 
 	spi_set_drvdata(spi, wm8995);
 
-	wm8995->regmap = regmap_init_spi(spi, &wm8995_regmap);
+	wm8995->regmap = devm_regmap_init_spi(spi, &wm8995_regmap);
 	if (IS_ERR(wm8995->regmap)) {
 		ret = PTR_ERR(wm8995->regmap);
 		dev_err(&spi->dev, "Failed to register regmap: %d\n", ret);
-		goto err_alloc;
+		return ret;
 	}
 
 	ret = snd_soc_register_codec(&spi->dev,
 				     &soc_codec_dev_wm8995, wm8995_dai,
 				     ARRAY_SIZE(wm8995_dai));
-	if (ret < 0)
-		goto err_regmap;
-
-	return ret;
-
-err_regmap:
-	regmap_exit(wm8995->regmap);
-err_alloc:
-	kfree(wm8995);
-
 	return ret;
 }
 
-static int __devexit wm8995_spi_remove(struct spi_device *spi)
+static int wm8995_spi_remove(struct spi_device *spi)
 {
-	struct wm8995_priv *wm8995 = spi_get_drvdata(spi);
 	snd_soc_unregister_codec(&spi->dev);
-	regmap_exit(wm8995->regmap);
-	kfree(wm8995);
 	return 0;
 }
 
@@ -2305,55 +2292,42 @@
 		.owner = THIS_MODULE,
 	},
 	.probe = wm8995_spi_probe,
-	.remove = __devexit_p(wm8995_spi_remove)
+	.remove = wm8995_spi_remove
 };
 #endif
 
 #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
-static __devinit int wm8995_i2c_probe(struct i2c_client *i2c,
-				      const struct i2c_device_id *id)
+static int wm8995_i2c_probe(struct i2c_client *i2c,
+			    const struct i2c_device_id *id)
 {
 	struct wm8995_priv *wm8995;
 	int ret;
 
-	wm8995 = kzalloc(sizeof *wm8995, GFP_KERNEL);
+	wm8995 = devm_kzalloc(&i2c->dev, sizeof(*wm8995), GFP_KERNEL);
 	if (!wm8995)
 		return -ENOMEM;
 
 	i2c_set_clientdata(i2c, wm8995);
 
-	wm8995->regmap = regmap_init_i2c(i2c, &wm8995_regmap);
+	wm8995->regmap = devm_regmap_init_i2c(i2c, &wm8995_regmap);
 	if (IS_ERR(wm8995->regmap)) {
 		ret = PTR_ERR(wm8995->regmap);
 		dev_err(&i2c->dev, "Failed to register regmap: %d\n", ret);
-		goto err_alloc;
+		return ret;
 	}
 
 	ret = snd_soc_register_codec(&i2c->dev,
 				     &soc_codec_dev_wm8995, wm8995_dai,
 				     ARRAY_SIZE(wm8995_dai));
-	if (ret < 0) {
+	if (ret < 0)
 		dev_err(&i2c->dev, "Failed to register CODEC: %d\n", ret);
-		goto err_regmap;
-	}
-
-	return ret;
-
-err_regmap:
-	regmap_exit(wm8995->regmap);
-err_alloc:
-	kfree(wm8995);
 
 	return ret;
 }
 
-static __devexit int wm8995_i2c_remove(struct i2c_client *client)
+static int wm8995_i2c_remove(struct i2c_client *client)
 {
-	struct wm8995_priv *wm8995 = i2c_get_clientdata(client);
-
 	snd_soc_unregister_codec(&client->dev);
-	regmap_exit(wm8995->regmap);
-	kfree(wm8995);
 	return 0;
 }
 
@@ -2370,7 +2344,7 @@
 		.owner = THIS_MODULE,
 	},
 	.probe = wm8995_i2c_probe,
-	.remove = __devexit_p(wm8995_i2c_remove),
+	.remove = wm8995_i2c_remove,
 	.id_table = wm8995_i2c_id
 };
 #endif
diff --git a/sound/soc/codecs/wm8996.c b/sound/soc/codecs/wm8996.c
index 6dcb02c..46fe83d 100644
--- a/sound/soc/codecs/wm8996.c
+++ b/sound/soc/codecs/wm8996.c
@@ -2765,8 +2765,8 @@
 	},
 };
 
-static __devinit int wm8996_i2c_probe(struct i2c_client *i2c,
-				      const struct i2c_device_id *id)
+static int wm8996_i2c_probe(struct i2c_client *i2c,
+			    const struct i2c_device_id *id)
 {
 	struct wm8996_priv *wm8996;
 	int ret, i;
@@ -3077,7 +3077,7 @@
 	return ret;
 }
 
-static __devexit int wm8996_i2c_remove(struct i2c_client *client)
+static int wm8996_i2c_remove(struct i2c_client *client)
 {
 	struct wm8996_priv *wm8996 = i2c_get_clientdata(client);
 	int i;
@@ -3107,7 +3107,7 @@
 		.owner = THIS_MODULE,
 	},
 	.probe =    wm8996_i2c_probe,
-	.remove =   __devexit_p(wm8996_i2c_remove),
+	.remove =   wm8996_i2c_remove,
 	.id_table = wm8996_i2c_id,
 };
 
diff --git a/sound/soc/codecs/wm9081.c b/sound/soc/codecs/wm9081.c
index 2de74e1..630b3d7 100644
--- a/sound/soc/codecs/wm9081.c
+++ b/sound/soc/codecs/wm9081.c
@@ -1327,8 +1327,8 @@
 };
 
 #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
-static __devinit int wm9081_i2c_probe(struct i2c_client *i2c,
-				      const struct i2c_device_id *id)
+static int wm9081_i2c_probe(struct i2c_client *i2c,
+			    const struct i2c_device_id *id)
 {
 	struct wm9081_priv *wm9081;
 	unsigned int reg;
@@ -1341,28 +1341,27 @@
 
 	i2c_set_clientdata(i2c, wm9081);
 
-	wm9081->regmap = regmap_init_i2c(i2c, &wm9081_regmap);
+	wm9081->regmap = devm_regmap_init_i2c(i2c, &wm9081_regmap);
 	if (IS_ERR(wm9081->regmap)) {
 		ret = PTR_ERR(wm9081->regmap);
 		dev_err(&i2c->dev, "regmap_init() failed: %d\n", ret);
-		goto err;
+		return ret;
 	}
 
 	ret = regmap_read(wm9081->regmap, WM9081_SOFTWARE_RESET, &reg);
 	if (ret != 0) {
 		dev_err(&i2c->dev, "Failed to read chip ID: %d\n", ret);
-		goto err_regmap;
+		return ret;
 	}
 	if (reg != 0x9081) {
 		dev_err(&i2c->dev, "Device is not a WM9081: ID=0x%x\n", reg);
-		ret = -EINVAL;
-		goto err_regmap;
+		return -EINVAL;
 	}
 
 	ret = wm9081_reset(wm9081->regmap);
 	if (ret < 0) {
 		dev_err(&i2c->dev, "Failed to issue reset\n");
-		goto err_regmap;
+		return ret;
 	}
 
 	if (dev_get_platdata(&i2c->dev))
@@ -1382,23 +1381,14 @@
 	ret = snd_soc_register_codec(&i2c->dev,
 			&soc_codec_dev_wm9081, &wm9081_dai, 1);
 	if (ret < 0)
-		goto err_regmap;
+		return ret;
 
 	return 0;
-
-err_regmap:
-	regmap_exit(wm9081->regmap);
-err:
-
-	return ret;
 }
 
-static __devexit int wm9081_i2c_remove(struct i2c_client *client)
+static int wm9081_i2c_remove(struct i2c_client *client)
 {
-	struct wm9081_priv *wm9081 = i2c_get_clientdata(client);
-
 	snd_soc_unregister_codec(&client->dev);
-	regmap_exit(wm9081->regmap);
 	return 0;
 }
 
@@ -1414,7 +1404,7 @@
 		.owner = THIS_MODULE,
 	},
 	.probe =    wm9081_i2c_probe,
-	.remove =   __devexit_p(wm9081_i2c_remove),
+	.remove =   wm9081_i2c_remove,
 	.id_table = wm9081_i2c_id,
 };
 #endif
diff --git a/sound/soc/codecs/wm9090.c b/sound/soc/codecs/wm9090.c
index c7ddc56..a07fe16 100644
--- a/sound/soc/codecs/wm9090.c
+++ b/sound/soc/codecs/wm9090.c
@@ -628,7 +628,7 @@
 		return -ENOMEM;
 	}
 
-	wm9090->regmap = regmap_init_i2c(i2c, &wm9090_regmap);
+	wm9090->regmap = devm_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);
@@ -637,16 +637,16 @@
 
 	ret = regmap_read(wm9090->regmap, WM9090_SOFTWARE_RESET, &reg);
 	if (ret < 0)
-		goto err;
+		return ret;
+
 	if (reg != 0x9093) {
 		dev_err(&i2c->dev, "Device is not a WM9090, ID=%x\n", reg);
-		ret = -ENODEV;
-		goto err;
+		return -ENODEV;
 	}
 
 	ret = regmap_write(wm9090->regmap, WM9090_SOFTWARE_RESET, 0);
 	if (ret < 0)
-		goto err;
+		return ret;
 
 	if (i2c->dev.platform_data)
 		memcpy(&wm9090->pdata, i2c->dev.platform_data,
@@ -658,23 +658,15 @@
 			&soc_codec_dev_wm9090,  NULL, 0);
 	if (ret != 0) {
 		dev_err(&i2c->dev, "Failed to register CODEC: %d\n", ret);
-		goto err;
+		return ret;
 	}
 
 	return 0;
-
-err:
-	regmap_exit(wm9090->regmap);
-	return ret;
 }
 
-static int __devexit wm9090_i2c_remove(struct i2c_client *i2c)
+static int 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;
 }
 
@@ -691,7 +683,7 @@
 		.owner = THIS_MODULE,
 	},
 	.probe = wm9090_i2c_probe,
-	.remove = __devexit_p(wm9090_i2c_remove),
+	.remove = wm9090_i2c_remove,
 	.id_table = wm9090_id,
 };
 
diff --git a/sound/soc/codecs/wm9705.c b/sound/soc/codecs/wm9705.c
index e8e782a..05b1f34 100644
--- a/sound/soc/codecs/wm9705.c
+++ b/sound/soc/codecs/wm9705.c
@@ -382,13 +382,13 @@
 	.num_dapm_routes = ARRAY_SIZE(wm9705_audio_map),
 };
 
-static __devinit int wm9705_probe(struct platform_device *pdev)
+static int wm9705_probe(struct platform_device *pdev)
 {
 	return snd_soc_register_codec(&pdev->dev,
 			&soc_codec_dev_wm9705, wm9705_dai, ARRAY_SIZE(wm9705_dai));
 }
 
-static int __devexit wm9705_remove(struct platform_device *pdev)
+static int wm9705_remove(struct platform_device *pdev)
 {
 	snd_soc_unregister_codec(&pdev->dev);
 	return 0;
@@ -401,7 +401,7 @@
 	},
 
 	.probe = wm9705_probe,
-	.remove = __devexit_p(wm9705_remove),
+	.remove = wm9705_remove,
 };
 
 module_platform_driver(wm9705_codec_driver);
diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c
index 4dd73ea..8e9a6a3 100644
--- a/sound/soc/codecs/wm9712.c
+++ b/sound/soc/codecs/wm9712.c
@@ -685,13 +685,13 @@
 	.num_dapm_routes = ARRAY_SIZE(wm9712_audio_map),
 };
 
-static __devinit int wm9712_probe(struct platform_device *pdev)
+static int wm9712_probe(struct platform_device *pdev)
 {
 	return snd_soc_register_codec(&pdev->dev,
 			&soc_codec_dev_wm9712, wm9712_dai, ARRAY_SIZE(wm9712_dai));
 }
 
-static int __devexit wm9712_remove(struct platform_device *pdev)
+static int wm9712_remove(struct platform_device *pdev)
 {
 	snd_soc_unregister_codec(&pdev->dev);
 	return 0;
@@ -704,7 +704,7 @@
 	},
 
 	.probe = wm9712_probe,
-	.remove = __devexit_p(wm9712_remove),
+	.remove = wm9712_remove,
 };
 
 module_platform_driver(wm9712_codec_driver);
diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c
index 3eb19fb..f7afa68 100644
--- a/sound/soc/codecs/wm9713.c
+++ b/sound/soc/codecs/wm9713.c
@@ -1254,13 +1254,13 @@
 	.num_dapm_routes = ARRAY_SIZE(wm9713_audio_map),
 };
 
-static __devinit int wm9713_probe(struct platform_device *pdev)
+static int wm9713_probe(struct platform_device *pdev)
 {
 	return snd_soc_register_codec(&pdev->dev,
 			&soc_codec_dev_wm9713, wm9713_dai, ARRAY_SIZE(wm9713_dai));
 }
 
-static int __devexit wm9713_remove(struct platform_device *pdev)
+static int wm9713_remove(struct platform_device *pdev)
 {
 	snd_soc_unregister_codec(&pdev->dev);
 	return 0;
@@ -1273,7 +1273,7 @@
 	},
 
 	.probe = wm9713_probe,
-	.remove = __devexit_p(wm9713_remove),
+	.remove = wm9713_remove,
 };
 
 module_platform_driver(wm9713_codec_driver);
diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c
new file mode 100644
index 0000000..ffc89fa
--- /dev/null
+++ b/sound/soc/codecs/wm_adsp.c
@@ -0,0 +1,699 @@
+/*
+ * wm_adsp.c  --  Wolfson ADSP support
+ *
+ * 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/firmware.h>
+#include <linux/pm.h>
+#include <linux/pm_runtime.h>
+#include <linux/regmap.h>
+#include <linux/regulator/consumer.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 <linux/mfd/arizona/registers.h>
+
+#include "wm_adsp.h"
+
+#define adsp_crit(_dsp, fmt, ...) \
+	dev_crit(_dsp->dev, "DSP%d: " fmt, _dsp->num, ##__VA_ARGS__)
+#define adsp_err(_dsp, fmt, ...) \
+	dev_err(_dsp->dev, "DSP%d: " fmt, _dsp->num, ##__VA_ARGS__)
+#define adsp_warn(_dsp, fmt, ...) \
+	dev_warn(_dsp->dev, "DSP%d: " fmt, _dsp->num, ##__VA_ARGS__)
+#define adsp_info(_dsp, fmt, ...) \
+	dev_info(_dsp->dev, "DSP%d: " fmt, _dsp->num, ##__VA_ARGS__)
+#define adsp_dbg(_dsp, fmt, ...) \
+	dev_dbg(_dsp->dev, "DSP%d: " fmt, _dsp->num, ##__VA_ARGS__)
+
+#define ADSP1_CONTROL_1                   0x00
+#define ADSP1_CONTROL_2                   0x02
+#define ADSP1_CONTROL_3                   0x03
+#define ADSP1_CONTROL_4                   0x04
+#define ADSP1_CONTROL_5                   0x06
+#define ADSP1_CONTROL_6                   0x07
+#define ADSP1_CONTROL_7                   0x08
+#define ADSP1_CONTROL_8                   0x09
+#define ADSP1_CONTROL_9                   0x0A
+#define ADSP1_CONTROL_10                  0x0B
+#define ADSP1_CONTROL_11                  0x0C
+#define ADSP1_CONTROL_12                  0x0D
+#define ADSP1_CONTROL_13                  0x0F
+#define ADSP1_CONTROL_14                  0x10
+#define ADSP1_CONTROL_15                  0x11
+#define ADSP1_CONTROL_16                  0x12
+#define ADSP1_CONTROL_17                  0x13
+#define ADSP1_CONTROL_18                  0x14
+#define ADSP1_CONTROL_19                  0x16
+#define ADSP1_CONTROL_20                  0x17
+#define ADSP1_CONTROL_21                  0x18
+#define ADSP1_CONTROL_22                  0x1A
+#define ADSP1_CONTROL_23                  0x1B
+#define ADSP1_CONTROL_24                  0x1C
+#define ADSP1_CONTROL_25                  0x1E
+#define ADSP1_CONTROL_26                  0x20
+#define ADSP1_CONTROL_27                  0x21
+#define ADSP1_CONTROL_28                  0x22
+#define ADSP1_CONTROL_29                  0x23
+#define ADSP1_CONTROL_30                  0x24
+#define ADSP1_CONTROL_31                  0x26
+
+/*
+ * ADSP1 Control 19
+ */
+#define ADSP1_WDMA_BUFFER_LENGTH_MASK     0x00FF  /* DSP1_WDMA_BUFFER_LENGTH - [7:0] */
+#define ADSP1_WDMA_BUFFER_LENGTH_SHIFT         0  /* DSP1_WDMA_BUFFER_LENGTH - [7:0] */
+#define ADSP1_WDMA_BUFFER_LENGTH_WIDTH         8  /* DSP1_WDMA_BUFFER_LENGTH - [7:0] */
+
+
+/*
+ * ADSP1 Control 30
+ */
+#define ADSP1_DBG_CLK_ENA                 0x0008  /* DSP1_DBG_CLK_ENA */
+#define ADSP1_DBG_CLK_ENA_MASK            0x0008  /* DSP1_DBG_CLK_ENA */
+#define ADSP1_DBG_CLK_ENA_SHIFT                3  /* DSP1_DBG_CLK_ENA */
+#define ADSP1_DBG_CLK_ENA_WIDTH                1  /* DSP1_DBG_CLK_ENA */
+#define ADSP1_SYS_ENA                     0x0004  /* DSP1_SYS_ENA */
+#define ADSP1_SYS_ENA_MASK                0x0004  /* DSP1_SYS_ENA */
+#define ADSP1_SYS_ENA_SHIFT                    2  /* DSP1_SYS_ENA */
+#define ADSP1_SYS_ENA_WIDTH                    1  /* DSP1_SYS_ENA */
+#define ADSP1_CORE_ENA                    0x0002  /* DSP1_CORE_ENA */
+#define ADSP1_CORE_ENA_MASK               0x0002  /* DSP1_CORE_ENA */
+#define ADSP1_CORE_ENA_SHIFT                   1  /* DSP1_CORE_ENA */
+#define ADSP1_CORE_ENA_WIDTH                   1  /* DSP1_CORE_ENA */
+#define ADSP1_START                       0x0001  /* DSP1_START */
+#define ADSP1_START_MASK                  0x0001  /* DSP1_START */
+#define ADSP1_START_SHIFT                      0  /* DSP1_START */
+#define ADSP1_START_WIDTH                      1  /* DSP1_START */
+
+#define ADSP2_CONTROL  0
+#define ADSP2_CLOCKING 1
+#define ADSP2_STATUS1  4
+
+/*
+ * ADSP2 Control
+ */
+
+#define ADSP2_MEM_ENA                     0x0010  /* DSP1_MEM_ENA */
+#define ADSP2_MEM_ENA_MASK                0x0010  /* DSP1_MEM_ENA */
+#define ADSP2_MEM_ENA_SHIFT                    4  /* DSP1_MEM_ENA */
+#define ADSP2_MEM_ENA_WIDTH                    1  /* DSP1_MEM_ENA */
+#define ADSP2_SYS_ENA                     0x0004  /* DSP1_SYS_ENA */
+#define ADSP2_SYS_ENA_MASK                0x0004  /* DSP1_SYS_ENA */
+#define ADSP2_SYS_ENA_SHIFT                    2  /* DSP1_SYS_ENA */
+#define ADSP2_SYS_ENA_WIDTH                    1  /* DSP1_SYS_ENA */
+#define ADSP2_CORE_ENA                    0x0002  /* DSP1_CORE_ENA */
+#define ADSP2_CORE_ENA_MASK               0x0002  /* DSP1_CORE_ENA */
+#define ADSP2_CORE_ENA_SHIFT                   1  /* DSP1_CORE_ENA */
+#define ADSP2_CORE_ENA_WIDTH                   1  /* DSP1_CORE_ENA */
+#define ADSP2_START                       0x0001  /* DSP1_START */
+#define ADSP2_START_MASK                  0x0001  /* DSP1_START */
+#define ADSP2_START_SHIFT                      0  /* DSP1_START */
+#define ADSP2_START_WIDTH                      1  /* DSP1_START */
+
+/*
+ * ADSP2 clocking
+ */
+#define ADSP2_CLK_SEL_MASK                0x0007  /* CLK_SEL_ENA */
+#define ADSP2_CLK_SEL_SHIFT                    0  /* CLK_SEL_ENA */
+#define ADSP2_CLK_SEL_WIDTH                    3  /* CLK_SEL_ENA */
+
+/*
+ * ADSP2 Status 1
+ */
+#define ADSP2_RAM_RDY                     0x0001
+#define ADSP2_RAM_RDY_MASK                0x0001
+#define ADSP2_RAM_RDY_SHIFT                    0
+#define ADSP2_RAM_RDY_WIDTH                    1
+
+
+static struct wm_adsp_region const *wm_adsp_find_region(struct wm_adsp *dsp,
+							int type)
+{
+	int i;
+
+	for (i = 0; i < dsp->num_mems; i++)
+		if (dsp->mem[i].type == type)
+			return &dsp->mem[i];
+
+	return NULL;
+}
+
+static int wm_adsp_load(struct wm_adsp *dsp)
+{
+	const struct firmware *firmware;
+	struct regmap *regmap = dsp->regmap;
+	unsigned int pos = 0;
+	const struct wmfw_header *header;
+	const struct wmfw_adsp1_sizes *adsp1_sizes;
+	const struct wmfw_adsp2_sizes *adsp2_sizes;
+	const struct wmfw_footer *footer;
+	const struct wmfw_region *region;
+	const struct wm_adsp_region *mem;
+	const char *region_name;
+	char *file, *text;
+	unsigned int reg;
+	int regions = 0;
+	int ret, offset, type, sizes;
+
+	file = kzalloc(PAGE_SIZE, GFP_KERNEL);
+	if (file == NULL)
+		return -ENOMEM;
+
+	snprintf(file, PAGE_SIZE, "%s-dsp%d.wmfw", dsp->part, dsp->num);
+	file[PAGE_SIZE - 1] = '\0';
+
+	ret = request_firmware(&firmware, file, dsp->dev);
+	if (ret != 0) {
+		adsp_err(dsp, "Failed to request '%s'\n", file);
+		goto out;
+	}
+	ret = -EINVAL;
+
+	pos = sizeof(*header) + sizeof(*adsp1_sizes) + sizeof(*footer);
+	if (pos >= firmware->size) {
+		adsp_err(dsp, "%s: file too short, %zu bytes\n",
+			 file, firmware->size);
+		goto out_fw;
+	}
+
+	header = (void*)&firmware->data[0];
+
+	if (memcmp(&header->magic[0], "WMFW", 4) != 0) {
+		adsp_err(dsp, "%s: invalid magic\n", file);
+		goto out_fw;
+	}
+
+	if (header->ver != 0) {
+		adsp_err(dsp, "%s: unknown file format %d\n",
+			 file, header->ver);
+		goto out_fw;
+	}
+
+	if (header->core != dsp->type) {
+		adsp_err(dsp, "%s: invalid core %d != %d\n",
+			 file, header->core, dsp->type);
+		goto out_fw;
+	}
+
+	switch (dsp->type) {
+	case WMFW_ADSP1:
+		pos = sizeof(*header) + sizeof(*adsp1_sizes) + sizeof(*footer);
+		adsp1_sizes = (void *)&(header[1]);
+		footer = (void *)&(adsp1_sizes[1]);
+		sizes = sizeof(*adsp1_sizes);
+
+		adsp_dbg(dsp, "%s: %d DM, %d PM, %d ZM\n",
+			 file, le32_to_cpu(adsp1_sizes->dm),
+			 le32_to_cpu(adsp1_sizes->pm),
+			 le32_to_cpu(adsp1_sizes->zm));
+		break;
+
+	case WMFW_ADSP2:
+		pos = sizeof(*header) + sizeof(*adsp2_sizes) + sizeof(*footer);
+		adsp2_sizes = (void *)&(header[1]);
+		footer = (void *)&(adsp2_sizes[1]);
+		sizes = sizeof(*adsp2_sizes);
+
+		adsp_dbg(dsp, "%s: %d XM, %d YM %d PM, %d ZM\n",
+			 file, le32_to_cpu(adsp2_sizes->xm),
+			 le32_to_cpu(adsp2_sizes->ym),
+			 le32_to_cpu(adsp2_sizes->pm),
+			 le32_to_cpu(adsp2_sizes->zm));
+		break;
+
+	default:
+		BUG_ON(NULL == "Unknown DSP type");
+		goto out_fw;
+	}
+
+	if (le32_to_cpu(header->len) != sizeof(*header) +
+	    sizes + sizeof(*footer)) {
+		adsp_err(dsp, "%s: unexpected header length %d\n",
+			 file, le32_to_cpu(header->len));
+		goto out_fw;
+	}
+
+	adsp_dbg(dsp, "%s: timestamp %llu\n", file,
+		 le64_to_cpu(footer->timestamp));
+
+	while (pos < firmware->size &&
+	       pos - firmware->size > sizeof(*region)) {
+		region = (void *)&(firmware->data[pos]);
+		region_name = "Unknown";
+		reg = 0;
+		text = NULL;
+		offset = le32_to_cpu(region->offset) & 0xffffff;
+		type = be32_to_cpu(region->type) & 0xff;
+		mem = wm_adsp_find_region(dsp, type);
+		
+		switch (type) {
+		case WMFW_NAME_TEXT:
+			region_name = "Firmware name";
+			text = kzalloc(le32_to_cpu(region->len) + 1,
+				       GFP_KERNEL);
+			break;
+		case WMFW_INFO_TEXT:
+			region_name = "Information";
+			text = kzalloc(le32_to_cpu(region->len) + 1,
+				       GFP_KERNEL);
+			break;
+		case WMFW_ABSOLUTE:
+			region_name = "Absolute";
+			reg = offset;
+			break;
+		case WMFW_ADSP1_PM:
+			BUG_ON(!mem);
+			region_name = "PM";
+			reg = mem->base + (offset * 3);
+			break;
+		case WMFW_ADSP1_DM:
+			BUG_ON(!mem);
+			region_name = "DM";
+			reg = mem->base + (offset * 2);
+			break;
+		case WMFW_ADSP2_XM:
+			BUG_ON(!mem);
+			region_name = "XM";
+			reg = mem->base + (offset * 2);
+			break;
+		case WMFW_ADSP2_YM:
+			BUG_ON(!mem);
+			region_name = "YM";
+			reg = mem->base + (offset * 2);
+			break;
+		case WMFW_ADSP1_ZM:
+			BUG_ON(!mem);
+			region_name = "ZM";
+			reg = mem->base + (offset * 2);
+			break;
+		default:
+			adsp_warn(dsp,
+				  "%s.%d: Unknown region type %x at %d(%x)\n",
+				  file, regions, type, pos, pos);
+			break;
+		}
+
+		adsp_dbg(dsp, "%s.%d: %d bytes at %d in %s\n", file,
+			 regions, le32_to_cpu(region->len), offset,
+			 region_name);
+
+		if (text) {
+			memcpy(text, region->data, le32_to_cpu(region->len));
+			adsp_info(dsp, "%s: %s\n", file, text);
+			kfree(text);
+		}
+
+		if (reg) {
+			ret = regmap_raw_write(regmap, reg, region->data,
+					       le32_to_cpu(region->len));
+			if (ret != 0) {
+				adsp_err(dsp,
+					"%s.%d: Failed to write %d bytes at %d in %s: %d\n",
+					file, regions,
+					le32_to_cpu(region->len), offset,
+					region_name, ret);
+				goto out_fw;
+			}
+		}
+
+		pos += le32_to_cpu(region->len) + sizeof(*region);
+		regions++;
+	}
+	
+	if (pos > firmware->size)
+		adsp_warn(dsp, "%s.%d: %zu bytes at end of file\n",
+			  file, regions, pos - firmware->size);
+
+out_fw:
+	release_firmware(firmware);
+out:
+	kfree(file);
+
+	return ret;
+}
+
+static int wm_adsp_load_coeff(struct wm_adsp *dsp)
+{
+	struct regmap *regmap = dsp->regmap;
+	struct wmfw_coeff_hdr *hdr;
+	struct wmfw_coeff_item *blk;
+	const struct firmware *firmware;
+	const char *region_name;
+	int ret, pos, blocks, type, offset, reg;
+	char *file;
+
+	file = kzalloc(PAGE_SIZE, GFP_KERNEL);
+	if (file == NULL)
+		return -ENOMEM;
+
+	snprintf(file, PAGE_SIZE, "%s-dsp%d.bin", dsp->part, dsp->num);
+	file[PAGE_SIZE - 1] = '\0';
+
+	ret = request_firmware(&firmware, file, dsp->dev);
+	if (ret != 0) {
+		adsp_warn(dsp, "Failed to request '%s'\n", file);
+		ret = 0;
+		goto out;
+	}
+	ret = -EINVAL;
+
+	if (sizeof(*hdr) >= firmware->size) {
+		adsp_err(dsp, "%s: file too short, %zu bytes\n",
+			file, firmware->size);
+		goto out_fw;
+	}
+
+	hdr = (void*)&firmware->data[0];
+	if (memcmp(hdr->magic, "WMDR", 4) != 0) {
+		adsp_err(dsp, "%s: invalid magic\n", file);
+		return -EINVAL;
+	}
+
+	adsp_dbg(dsp, "%s: v%d.%d.%d\n", file,
+		(le32_to_cpu(hdr->ver) >> 16) & 0xff,
+		(le32_to_cpu(hdr->ver) >>  8) & 0xff,
+		le32_to_cpu(hdr->ver) & 0xff);
+
+	pos = le32_to_cpu(hdr->len);
+
+	blocks = 0;
+	while (pos < firmware->size &&
+	       pos - firmware->size > sizeof(*blk)) {
+		blk = (void*)(&firmware->data[pos]);
+
+		type = be32_to_cpu(blk->type) & 0xff;
+		offset = le32_to_cpu(blk->offset) & 0xffffff;
+
+		adsp_dbg(dsp, "%s.%d: %x v%d.%d.%d\n",
+			 file, blocks, le32_to_cpu(blk->id),
+			 (le32_to_cpu(blk->ver) >> 16) & 0xff,
+			 (le32_to_cpu(blk->ver) >>  8) & 0xff,
+			 le32_to_cpu(blk->ver) & 0xff);
+		adsp_dbg(dsp, "%s.%d: %d bytes at 0x%x in %x\n",
+			 file, blocks, le32_to_cpu(blk->len), offset, type);
+
+		reg = 0;
+		region_name = "Unknown";
+		switch (type) {
+		case WMFW_NAME_TEXT:
+		case WMFW_INFO_TEXT:
+			break;
+		case WMFW_ABSOLUTE:
+			region_name = "register";
+			reg = offset;
+			break;
+		default:
+			adsp_err(dsp, "Unknown region type %x\n", type);
+			break;
+		}
+
+		if (reg) {
+			ret = regmap_raw_write(regmap, reg, blk->data,
+					       le32_to_cpu(blk->len));
+			if (ret != 0) {
+				adsp_err(dsp,
+					"%s.%d: Failed to write to %x in %s\n",
+					file, blocks, reg, region_name);
+			}
+		}
+
+		pos += le32_to_cpu(blk->len) + sizeof(*blk);
+		blocks++;
+	}
+
+	if (pos > firmware->size)
+		adsp_warn(dsp, "%s.%d: %zu bytes at end of file\n",
+			  file, blocks, pos - firmware->size);
+
+out_fw:
+	release_firmware(firmware);
+out:
+	kfree(file);
+	return 0;
+}
+
+int wm_adsp1_event(struct snd_soc_dapm_widget *w,
+		   struct snd_kcontrol *kcontrol,
+		   int event)
+{
+	struct snd_soc_codec *codec = w->codec;
+	struct wm_adsp *dsps = snd_soc_codec_get_drvdata(codec);
+	struct wm_adsp *dsp = &dsps[w->shift];
+	int ret;
+
+	switch (event) {
+	case SND_SOC_DAPM_POST_PMU:
+		regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30,
+				   ADSP1_SYS_ENA, ADSP1_SYS_ENA);
+
+		ret = wm_adsp_load(dsp);
+		if (ret != 0)
+			goto err;
+
+		ret = wm_adsp_load_coeff(dsp);
+		if (ret != 0)
+			goto err;
+
+		/* Start the core running */
+		regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30,
+				   ADSP1_CORE_ENA | ADSP1_START,
+				   ADSP1_CORE_ENA | ADSP1_START);
+		break;
+
+	case SND_SOC_DAPM_PRE_PMD:
+		/* Halt the core */
+		regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30,
+				   ADSP1_CORE_ENA | ADSP1_START, 0);
+
+		regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_19,
+				   ADSP1_WDMA_BUFFER_LENGTH_MASK, 0);
+
+		regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30,
+				   ADSP1_SYS_ENA, 0);
+		break;
+
+	default:
+		break;
+	}
+
+	return 0;
+
+err:
+	regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30,
+			   ADSP1_SYS_ENA, 0);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(wm_adsp1_event);
+
+static int wm_adsp2_ena(struct wm_adsp *dsp)
+{
+	unsigned int val;
+	int ret, count;
+
+	ret = regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL,
+				 ADSP2_SYS_ENA, ADSP2_SYS_ENA);
+	if (ret != 0)
+		return ret;
+
+	/* Wait for the RAM to start, should be near instantaneous */
+	count = 0;
+	do {
+		ret = regmap_read(dsp->regmap, dsp->base + ADSP2_STATUS1,
+				  &val);
+		if (ret != 0)
+			return ret;
+	} while (!(val & ADSP2_RAM_RDY) && ++count < 10);
+
+	if (!(val & ADSP2_RAM_RDY)) {
+		adsp_err(dsp, "Failed to start DSP RAM\n");
+		return -EBUSY;
+	}
+
+	adsp_dbg(dsp, "RAM ready after %d polls\n", count);
+	adsp_info(dsp, "RAM ready after %d polls\n", count);
+
+	return 0;
+}
+
+int wm_adsp2_event(struct snd_soc_dapm_widget *w,
+		   struct snd_kcontrol *kcontrol, int event)
+{
+	struct snd_soc_codec *codec = w->codec;
+	struct wm_adsp *dsps = snd_soc_codec_get_drvdata(codec);
+	struct wm_adsp *dsp = &dsps[w->shift];
+	unsigned int val;
+	int ret;
+
+	switch (event) {
+	case SND_SOC_DAPM_POST_PMU:
+		/*
+		 * For simplicity set the DSP clock rate to be the
+		 * SYSCLK rate rather than making it configurable.
+		 */
+		ret = regmap_read(dsp->regmap, ARIZONA_SYSTEM_CLOCK_1, &val);
+		if (ret != 0) {
+			adsp_err(dsp, "Failed to read SYSCLK state: %d\n",
+				 ret);
+			return ret;
+		}
+		val = (val & ARIZONA_SYSCLK_FREQ_MASK)
+			>> ARIZONA_SYSCLK_FREQ_SHIFT;
+
+		ret = regmap_update_bits(dsp->regmap,
+					 dsp->base + ADSP2_CLOCKING,
+					 ADSP2_CLK_SEL_MASK, val);
+		if (ret != 0) {
+			adsp_err(dsp, "Failed to set clock rate: %d\n",
+				 ret);
+			return ret;
+		}
+
+		if (dsp->dvfs) {
+			ret = regmap_read(dsp->regmap,
+					  dsp->base + ADSP2_CLOCKING, &val);
+			if (ret != 0) {
+				dev_err(dsp->dev,
+					"Failed to read clocking: %d\n", ret);
+				return ret;
+			}
+
+			if ((val & ADSP2_CLK_SEL_MASK) >= 3) {
+				ret = regulator_enable(dsp->dvfs);
+				if (ret != 0) {
+					dev_err(dsp->dev,
+						"Failed to enable supply: %d\n",
+						ret);
+					return ret;
+				}
+
+				ret = regulator_set_voltage(dsp->dvfs,
+							    1800000,
+							    1800000);
+				if (ret != 0) {
+					dev_err(dsp->dev,
+						"Failed to raise supply: %d\n",
+						ret);
+					return ret;
+				}
+			}
+		}
+
+		ret = wm_adsp2_ena(dsp);
+		if (ret != 0)
+			return ret;
+
+		ret = wm_adsp_load(dsp);
+		if (ret != 0)
+			goto err;
+
+		ret = wm_adsp_load_coeff(dsp);
+		if (ret != 0)
+			goto err;
+
+		ret = regmap_update_bits(dsp->regmap,
+					 dsp->base + ADSP2_CONTROL,
+					 ADSP2_CORE_ENA | ADSP2_START,
+					 ADSP2_CORE_ENA | ADSP2_START);
+		if (ret != 0)
+			goto err;
+		break;
+
+	case SND_SOC_DAPM_PRE_PMD:
+		regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL,
+				   ADSP2_SYS_ENA | ADSP2_CORE_ENA |
+				   ADSP2_START, 0);
+
+		if (dsp->dvfs) {
+			ret = regulator_set_voltage(dsp->dvfs, 1200000,
+						    1800000);
+			if (ret != 0)
+				dev_warn(dsp->dev,
+					 "Failed to lower supply: %d\n",
+					 ret);
+
+			ret = regulator_disable(dsp->dvfs);
+			if (ret != 0)
+				dev_err(dsp->dev,
+					"Failed to enable supply: %d\n",
+					ret);
+		}
+		break;
+
+	default:
+		break;
+	}
+
+	return 0;
+err:
+	regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL,
+			   ADSP2_SYS_ENA | ADSP2_CORE_ENA | ADSP2_START, 0);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(wm_adsp2_event);
+
+int wm_adsp2_init(struct wm_adsp *adsp, bool dvfs)
+{
+	int ret;
+
+	/*
+	 * Disable the DSP memory by default when in reset for a small
+	 * power saving.
+	 */
+	ret = regmap_update_bits(adsp->regmap, adsp->base + ADSP2_CONTROL,
+				 ADSP2_MEM_ENA, 0);
+	if (ret != 0) {
+		adsp_err(adsp, "Failed to clear memory retention: %d\n", ret);
+		return ret;
+	}
+
+	if (dvfs) {
+		adsp->dvfs = devm_regulator_get(adsp->dev, "DCVDD");
+		if (IS_ERR(adsp->dvfs)) {
+			ret = PTR_ERR(adsp->dvfs);
+			dev_err(adsp->dev, "Failed to get DCVDD: %d\n", ret);
+			return ret;
+		}
+
+		ret = regulator_enable(adsp->dvfs);
+		if (ret != 0) {
+			dev_err(adsp->dev, "Failed to enable DCVDD: %d\n",
+				ret);
+			return ret;
+		}
+
+		ret = regulator_set_voltage(adsp->dvfs, 1200000, 1800000);
+		if (ret != 0) {
+			dev_err(adsp->dev, "Failed to initialise DVFS: %d\n",
+				ret);
+			return ret;
+		}
+
+		ret = regulator_disable(adsp->dvfs);
+		if (ret != 0) {
+			dev_err(adsp->dev, "Failed to disable DCVDD: %d\n",
+				ret);
+			return ret;
+		}
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(wm_adsp2_init);
diff --git a/sound/soc/codecs/wm_adsp.h b/sound/soc/codecs/wm_adsp.h
new file mode 100644
index 0000000..ffd29a4
--- /dev/null
+++ b/sound/soc/codecs/wm_adsp.h
@@ -0,0 +1,59 @@
+/*
+ * wm_adsp.h  --  Wolfson ADSP support
+ *
+ * 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.
+ */
+
+#ifndef __WM_ADSP_H
+#define __WM_ADSP_H
+
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+
+#include "wmfw.h"
+
+struct regulator;
+
+struct wm_adsp_region {
+	int type;
+	unsigned int base;
+};
+
+struct wm_adsp {
+	const char *part;
+	int num;
+	int type;
+	struct device *dev;
+	struct regmap *regmap;
+
+	int base;
+
+	const struct wm_adsp_region *mem;
+	int num_mems;
+
+	struct regulator *dvfs;
+};
+
+#define WM_ADSP1(wname, num) \
+	{ .id = snd_soc_dapm_pga, .name = wname, .reg = SND_SOC_NOPM, \
+	.shift = num, .event = wm_adsp1_event, \
+	.event_flags = SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD }
+
+#define WM_ADSP2(wname, num) \
+{	.id = snd_soc_dapm_pga, .name = wname, .reg = SND_SOC_NOPM, \
+	.shift = num, .event = wm_adsp2_event, \
+	.event_flags = SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD }
+
+int wm_adsp2_init(struct wm_adsp *adsp, bool dvfs);
+int wm_adsp1_event(struct snd_soc_dapm_widget *w,
+		   struct snd_kcontrol *kcontrol, int event);
+int wm_adsp2_event(struct snd_soc_dapm_widget *w,
+		   struct snd_kcontrol *kcontrol, int event);
+
+#endif
diff --git a/sound/soc/codecs/wmfw.h b/sound/soc/codecs/wmfw.h
new file mode 100644
index 0000000..5632ded
--- /dev/null
+++ b/sound/soc/codecs/wmfw.h
@@ -0,0 +1,128 @@
+/*
+ * wmfw.h - Wolfson firmware format information
+ *
+ * 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.
+ */
+
+#ifndef __WMFW_H
+#define __WMFW_H
+
+#include <linux/types.h>
+
+struct wmfw_header {
+	char magic[4];
+	__le32 len;
+	__le16 rev;
+	u8 core;
+	u8 ver;
+} __packed;
+
+struct wmfw_footer {
+	__le64 timestamp;
+	__le32 checksum;
+} __packed;
+
+struct wmfw_adsp1_sizes {
+	__le32 dm;
+	__le32 pm;
+	__le32 zm;
+} __packed;
+
+struct wmfw_adsp2_sizes {
+	__le32 xm;
+	__le32 ym;
+	__le32 pm;
+	__le32 zm;
+} __packed;
+
+struct wmfw_region {
+	union {
+		__be32 type;
+		__le32 offset;
+	};
+	__le32 len;
+	u8 data[];
+} __packed;
+
+struct wmfw_id_hdr {
+	__be32 core_id;
+	__be32 core_rev;
+	__be32 id;
+	__be32 ver;
+} __packed;
+
+struct wmfw_adsp1_id_hdr {
+	struct wmfw_id_hdr fw;
+	__be32 zm;
+	__be32 dm;
+	__be32 algs;
+} __packed;
+
+struct wmfw_adsp2_id_hdr {
+	struct wmfw_id_hdr fw;
+	__be32 zm;
+	__be32 xm;
+	__be32 ym;
+	__be32 algs;
+} __packed;
+
+struct wmfw_alg_hdr {
+	__be32 id;
+	__be32 ver;
+} __packed;
+
+struct wmfw_adsp1_alg_hdr {
+	struct wmfw_alg_hdr alg;
+	__be32 zm;
+	__be32 dm;
+} __packed;
+
+struct wmfw_adsp2_alg_hdr {
+	struct wmfw_alg_hdr alg;
+	__be32 zm;
+	__be32 xm;
+	__be32 ym;
+} __packed;
+
+struct wmfw_coeff_hdr {
+	u8 magic[4];
+	__le32 len;
+	__le32 ver;
+	u8 data[];
+} __packed;
+
+struct wmfw_coeff_item {
+	union {
+		__be32 type;
+		__le32 offset;
+	};
+	__le32 id;
+	__le32 ver;
+	__le32 sr;
+	__le32 len;
+	u8 data[];
+} __packed;
+
+#define WMFW_ADSP1 1
+#define WMFW_ADSP2 2
+
+#define WMFW_ABSOLUTE  0xf0
+#define WMFW_NAME_TEXT 0xfe
+#define WMFW_INFO_TEXT 0xff
+
+#define WMFW_ADSP1_PM 2
+#define WMFW_ADSP1_DM 3
+#define WMFW_ADSP1_ZM 4
+
+#define WMFW_ADSP2_PM 2
+#define WMFW_ADSP2_ZM 4
+#define WMFW_ADSP2_XM 5
+#define WMFW_ADSP2_YM 6
+
+#endif
diff --git a/sound/soc/davinci/davinci-evm.c b/sound/soc/davinci/davinci-evm.c
index 6fac5af..d55e647 100644
--- a/sound/soc/davinci/davinci-evm.c
+++ b/sound/soc/davinci/davinci-evm.c
@@ -71,6 +71,11 @@
 	if (ret < 0)
 		return ret;
 
+	/* set the CPU system clock */
+	ret = snd_soc_dai_set_sysclk(cpu_dai, 0, sysclk, SND_SOC_CLOCK_OUT);
+	if (ret < 0)
+		return ret;
+
 	return 0;
 }
 
diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c
index 714e51e..55e2bf6 100644
--- a/sound/soc/davinci/davinci-mcasp.c
+++ b/sound/soc/davinci/davinci-mcasp.c
@@ -199,6 +199,7 @@
 #define ACLKXE		BIT(5)
 #define TX_ASYNC	BIT(6)
 #define ACLKXPOL	BIT(7)
+#define ACLKXDIV_MASK	0x1f
 
 /*
  * DAVINCI_MCASP_ACLKRCTL_REG Receive Clock Control Register Bits
@@ -207,6 +208,7 @@
 #define ACLKRE		BIT(5)
 #define RX_ASYNC	BIT(6)
 #define ACLKRPOL	BIT(7)
+#define ACLKRDIV_MASK	0x1f
 
 /*
  * DAVINCI_MCASP_AHCLKXCTL_REG - High Frequency Transmit Clock Control
@@ -215,6 +217,7 @@
 #define AHCLKXDIV(val)	(val)
 #define AHCLKXPOL	BIT(14)
 #define AHCLKXE		BIT(15)
+#define AHCLKXDIV_MASK	0xfff
 
 /*
  * DAVINCI_MCASP_AHCLKRCTL_REG - High Frequency Receive Clock Control
@@ -223,6 +226,7 @@
 #define AHCLKRDIV(val)	(val)
 #define AHCLKRPOL	BIT(14)
 #define AHCLKRE		BIT(15)
+#define AHCLKRDIV_MASK	0xfff
 
 /*
  * DAVINCI_MCASP_XRSRCTL_BASE_REG -  Serializer Control Register Bits
@@ -473,6 +477,23 @@
 	struct davinci_audio_dev *dev = snd_soc_dai_get_drvdata(cpu_dai);
 	void __iomem *base = dev->base;
 
+	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+	case SND_SOC_DAIFMT_DSP_B:
+	case SND_SOC_DAIFMT_AC97:
+		mcasp_clr_bits(dev->base + DAVINCI_MCASP_TXFMCTL_REG, FSXDUR);
+		mcasp_clr_bits(dev->base + DAVINCI_MCASP_RXFMCTL_REG, FSRDUR);
+		break;
+	default:
+		/* configure a full-word SYNC pulse (LRCLK) */
+		mcasp_set_bits(dev->base + DAVINCI_MCASP_TXFMCTL_REG, FSXDUR);
+		mcasp_set_bits(dev->base + DAVINCI_MCASP_RXFMCTL_REG, FSRDUR);
+
+		/* make 1st data bit occur one ACLK cycle after the frame sync */
+		mcasp_set_bits(dev->base + DAVINCI_MCASP_TXFMT_REG, FSXDLY(1));
+		mcasp_set_bits(dev->base + DAVINCI_MCASP_RXFMT_REG, FSRDLY(1));
+		break;
+	}
+
 	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
 	case SND_SOC_DAIFMT_CBS_CFS:
 		/* codec is clock and frame slave */
@@ -482,8 +503,7 @@
 		mcasp_set_bits(base + DAVINCI_MCASP_ACLKRCTL_REG, ACLKRE);
 		mcasp_set_bits(base + DAVINCI_MCASP_RXFMCTL_REG, AFSRE);
 
-		mcasp_set_bits(base + DAVINCI_MCASP_PDIR_REG,
-				ACLKX | AHCLKX | AFSX);
+		mcasp_set_bits(base + DAVINCI_MCASP_PDIR_REG, ACLKX | AFSX);
 		break;
 	case SND_SOC_DAIFMT_CBM_CFS:
 		/* codec is clock master and frame slave */
@@ -554,59 +574,75 @@
 	return 0;
 }
 
-static int davinci_config_channel_size(struct davinci_audio_dev *dev,
-				       int channel_size)
+static int davinci_mcasp_set_clkdiv(struct snd_soc_dai *dai, int div_id, int div)
 {
-	u32 fmt = 0;
-	u32 mask, rotate;
+	struct davinci_audio_dev *dev = snd_soc_dai_get_drvdata(dai);
 
-	switch (channel_size) {
-	case DAVINCI_AUDIO_WORD_8:
-		fmt = 0x03;
-		rotate = 6;
-		mask = 0x000000ff;
+	switch (div_id) {
+	case 0:		/* MCLK divider */
+		mcasp_mod_bits(dev->base + DAVINCI_MCASP_AHCLKXCTL_REG,
+			       AHCLKXDIV(div - 1), AHCLKXDIV_MASK);
+		mcasp_mod_bits(dev->base + DAVINCI_MCASP_AHCLKRCTL_REG,
+			       AHCLKRDIV(div - 1), AHCLKRDIV_MASK);
 		break;
 
-	case DAVINCI_AUDIO_WORD_12:
-		fmt = 0x05;
-		rotate = 5;
-		mask = 0x00000fff;
+	case 1:		/* BCLK divider */
+		mcasp_mod_bits(dev->base + DAVINCI_MCASP_ACLKXCTL_REG,
+			       ACLKXDIV(div - 1), ACLKXDIV_MASK);
+		mcasp_mod_bits(dev->base + DAVINCI_MCASP_ACLKRCTL_REG,
+			       ACLKRDIV(div - 1), ACLKRDIV_MASK);
 		break;
 
-	case DAVINCI_AUDIO_WORD_16:
-		fmt = 0x07;
-		rotate = 4;
-		mask = 0x0000ffff;
-		break;
-
-	case DAVINCI_AUDIO_WORD_20:
-		fmt = 0x09;
-		rotate = 3;
-		mask = 0x000fffff;
-		break;
-
-	case DAVINCI_AUDIO_WORD_24:
-		fmt = 0x0B;
-		rotate = 2;
-		mask = 0x00ffffff;
-		break;
-
-	case DAVINCI_AUDIO_WORD_28:
-		fmt = 0x0D;
-		rotate = 1;
-		mask = 0x0fffffff;
-		break;
-
-	case DAVINCI_AUDIO_WORD_32:
-		fmt = 0x0F;
-		rotate = 0;
-		mask = 0xffffffff;
+	case 2:		/* BCLK/LRCLK ratio */
+		dev->bclk_lrclk_ratio = div;
 		break;
 
 	default:
 		return -EINVAL;
 	}
 
+	return 0;
+}
+
+static int davinci_mcasp_set_sysclk(struct snd_soc_dai *dai, int clk_id,
+				    unsigned int freq, int dir)
+{
+	struct davinci_audio_dev *dev = snd_soc_dai_get_drvdata(dai);
+
+	if (dir == SND_SOC_CLOCK_OUT) {
+		mcasp_set_bits(dev->base + DAVINCI_MCASP_AHCLKXCTL_REG, AHCLKXE);
+		mcasp_set_bits(dev->base + DAVINCI_MCASP_AHCLKRCTL_REG, AHCLKRE);
+		mcasp_set_bits(dev->base + DAVINCI_MCASP_PDIR_REG, AHCLKX);
+	} else {
+		mcasp_clr_bits(dev->base + DAVINCI_MCASP_AHCLKXCTL_REG, AHCLKXE);
+		mcasp_clr_bits(dev->base + DAVINCI_MCASP_AHCLKRCTL_REG, AHCLKRE);
+		mcasp_clr_bits(dev->base + DAVINCI_MCASP_PDIR_REG, AHCLKX);
+	}
+
+	return 0;
+}
+
+static int davinci_config_channel_size(struct davinci_audio_dev *dev,
+				       int word_length)
+{
+	u32 fmt;
+	u32 rotate = (32 - word_length) / 4;
+	u32 mask = (1ULL << word_length) - 1;
+
+	/*
+	 * if s BCLK-to-LRCLK ratio has been configured via the set_clkdiv()
+	 * callback, take it into account here. That allows us to for example
+	 * send 32 bits per channel to the codec, while only 16 of them carry
+	 * audio payload.
+	 * The clock ratio is given for a full period of data (both left and
+	 * right channels), so it has to be divided by 2.
+	 */
+	if (dev->bclk_lrclk_ratio)
+		word_length = dev->bclk_lrclk_ratio / 2;
+
+	/* mapping of the XSSZ bit-field as described in the datasheet */
+	fmt = (word_length >> 1) - 1;
+
 	mcasp_mod_bits(dev->base + DAVINCI_MCASP_RXFMT_REG,
 					RXSSZ(fmt), RXSSZ(0x0F));
 	mcasp_mod_bits(dev->base + DAVINCI_MCASP_TXFMT_REG,
@@ -709,8 +745,6 @@
 	if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
 		/* bit stream is MSB first  with no delay */
 		/* DSP_B mode */
-		mcasp_set_bits(dev->base + DAVINCI_MCASP_AHCLKXCTL_REG,
-				AHCLKXE);
 		mcasp_set_reg(dev->base + DAVINCI_MCASP_TXTDM_REG, mask);
 		mcasp_set_bits(dev->base + DAVINCI_MCASP_TXFMT_REG, TXORD);
 
@@ -720,14 +754,10 @@
 		else
 			printk(KERN_ERR "playback tdm slot %d not supported\n",
 				dev->tdm_slots);
-
-		mcasp_clr_bits(dev->base + DAVINCI_MCASP_TXFMCTL_REG, FSXDUR);
 	} else {
 		/* bit stream is MSB first with no delay */
 		/* DSP_B mode */
 		mcasp_set_bits(dev->base + DAVINCI_MCASP_RXFMT_REG, RXORD);
-		mcasp_set_bits(dev->base + DAVINCI_MCASP_AHCLKRCTL_REG,
-				AHCLKRE);
 		mcasp_set_reg(dev->base + DAVINCI_MCASP_RXTDM_REG, mask);
 
 		if ((dev->tdm_slots >= 2) && (dev->tdm_slots <= 32))
@@ -736,8 +766,6 @@
 		else
 			printk(KERN_ERR "capture tdm slot %d not supported\n",
 				dev->tdm_slots);
-
-		mcasp_clr_bits(dev->base + DAVINCI_MCASP_RXFMCTL_REG, FSRDUR);
 	}
 }
 
@@ -800,19 +828,27 @@
 	case SNDRV_PCM_FORMAT_U8:
 	case SNDRV_PCM_FORMAT_S8:
 		dma_params->data_type = 1;
-		word_length = DAVINCI_AUDIO_WORD_8;
+		word_length = 8;
 		break;
 
 	case SNDRV_PCM_FORMAT_U16_LE:
 	case SNDRV_PCM_FORMAT_S16_LE:
 		dma_params->data_type = 2;
-		word_length = DAVINCI_AUDIO_WORD_16;
+		word_length = 16;
 		break;
 
+	case SNDRV_PCM_FORMAT_U24_3LE:
+	case SNDRV_PCM_FORMAT_S24_3LE:
+		dma_params->data_type = 3;
+		word_length = 24;
+		break;
+
+	case SNDRV_PCM_FORMAT_U24_LE:
+	case SNDRV_PCM_FORMAT_S24_LE:
 	case SNDRV_PCM_FORMAT_U32_LE:
 	case SNDRV_PCM_FORMAT_S32_LE:
 		dma_params->data_type = 4;
-		word_length = DAVINCI_AUDIO_WORD_32;
+		word_length = 32;
 		break;
 
 	default:
@@ -880,13 +916,18 @@
 	.trigger	= davinci_mcasp_trigger,
 	.hw_params	= davinci_mcasp_hw_params,
 	.set_fmt	= davinci_mcasp_set_dai_fmt,
-
+	.set_clkdiv	= davinci_mcasp_set_clkdiv,
+	.set_sysclk	= davinci_mcasp_set_sysclk,
 };
 
 #define DAVINCI_MCASP_PCM_FMTS (SNDRV_PCM_FMTBIT_S8 | \
 				SNDRV_PCM_FMTBIT_U8 | \
 				SNDRV_PCM_FMTBIT_S16_LE | \
 				SNDRV_PCM_FMTBIT_U16_LE | \
+				SNDRV_PCM_FMTBIT_S24_LE | \
+				SNDRV_PCM_FMTBIT_U24_LE | \
+				SNDRV_PCM_FMTBIT_S24_3LE | \
+				SNDRV_PCM_FMTBIT_U24_3LE | \
 				SNDRV_PCM_FMTBIT_S32_LE | \
 				SNDRV_PCM_FMTBIT_U32_LE)
 
@@ -1089,7 +1130,6 @@
 	dev->tdm_slots = pdata->tdm_slots;
 	dev->num_serializer = pdata->num_serializer;
 	dev->serial_dir = pdata->serial_dir;
-	dev->codec_fmt = pdata->codec_fmt;
 	dev->version = pdata->version;
 	dev->txnumevt = pdata->txnumevt;
 	dev->rxnumevt = pdata->rxnumevt;
@@ -1098,6 +1138,7 @@
 	dma_data = &dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK];
 	dma_data->asp_chan_q = pdata->asp_chan_q;
 	dma_data->ram_chan_q = pdata->ram_chan_q;
+	dma_data->sram_pool = pdata->sram_pool;
 	dma_data->sram_size = pdata->sram_size_playback;
 	dma_data->dma_addr = (dma_addr_t) (pdata->tx_dma_offset +
 							mem->start);
@@ -1115,6 +1156,7 @@
 	dma_data = &dev->dma_params[SNDRV_PCM_STREAM_CAPTURE];
 	dma_data->asp_chan_q = pdata->asp_chan_q;
 	dma_data->ram_chan_q = pdata->ram_chan_q;
+	dma_data->sram_pool = pdata->sram_pool;
 	dma_data->sram_size = pdata->sram_size_capture;
 	dma_data->dma_addr = (dma_addr_t)(pdata->rx_dma_offset +
 							mem->start);
diff --git a/sound/soc/davinci/davinci-mcasp.h b/sound/soc/davinci/davinci-mcasp.h
index 0de9ed6..0edd3b5 100644
--- a/sound/soc/davinci/davinci-mcasp.h
+++ b/sound/soc/davinci/davinci-mcasp.h
@@ -23,26 +23,14 @@
 
 #include "davinci-pcm.h"
 
-#define DAVINCI_MCASP_RATES	SNDRV_PCM_RATE_8000_96000
+#define DAVINCI_MCASP_RATES	SNDRV_PCM_RATE_8000_192000
 #define DAVINCI_MCASP_I2S_DAI	0
 #define DAVINCI_MCASP_DIT_DAI	1
 
-enum {
-	DAVINCI_AUDIO_WORD_8 = 0,
-	DAVINCI_AUDIO_WORD_12,
-	DAVINCI_AUDIO_WORD_16,
-	DAVINCI_AUDIO_WORD_20,
-	DAVINCI_AUDIO_WORD_24,
-	DAVINCI_AUDIO_WORD_32,
-	DAVINCI_AUDIO_WORD_28,  /* This is only valid for McASP */
-};
-
 struct davinci_audio_dev {
 	struct davinci_pcm_dma_params dma_params[2];
 	void __iomem *base;
-	int sample_rate;
 	struct device *dev;
-	unsigned int codec_fmt;
 
 	/* McASP specific data */
 	int	tdm_slots;
@@ -50,6 +38,7 @@
 	u8	num_serializer;
 	u8	*serial_dir;
 	u8	version;
+	u8	bclk_lrclk_ratio;
 
 	/* McASP FIFO related */
 	u8	txnumevt;
diff --git a/sound/soc/davinci/davinci-pcm.c b/sound/soc/davinci/davinci-pcm.c
index 93ea3bf..afab81f 100644
--- a/sound/soc/davinci/davinci-pcm.c
+++ b/sound/soc/davinci/davinci-pcm.c
@@ -16,6 +16,7 @@
 #include <linux/slab.h>
 #include <linux/dma-mapping.h>
 #include <linux/kernel.h>
+#include <linux/genalloc.h>
 
 #include <sound/core.h>
 #include <sound/pcm.h>
@@ -23,7 +24,6 @@
 #include <sound/soc.h>
 
 #include <asm/dma.h>
-#include <mach/sram.h>
 
 #include "davinci-pcm.h"
 
@@ -67,13 +67,9 @@
 		 SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME|
 		 SNDRV_PCM_INFO_BATCH),
 	.formats = DAVINCI_PCM_FMTBITS,
-	.rates = (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
-		  SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 |
-		  SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |
-		  SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 |
-		  SNDRV_PCM_RATE_KNOT),
+	.rates = SNDRV_PCM_RATE_8000_192000 | SNDRV_PCM_RATE_KNOT,
 	.rate_min = 8000,
-	.rate_max = 96000,
+	.rate_max = 192000,
 	.channels_min = 2,
 	.channels_max = 384,
 	.buffer_bytes_max = 128 * 1024,
@@ -90,13 +86,9 @@
 		 SNDRV_PCM_INFO_PAUSE |
 		 SNDRV_PCM_INFO_BATCH),
 	.formats = DAVINCI_PCM_FMTBITS,
-	.rates = (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
-		  SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 |
-		  SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |
-		  SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 |
-		  SNDRV_PCM_RATE_KNOT),
+	.rates = SNDRV_PCM_RATE_8000_192000 | SNDRV_PCM_RATE_KNOT,
 	.rate_min = 8000,
-	.rate_max = 96000,
+	.rate_max = 192000,
 	.channels_min = 2,
 	.channels_max = 384,
 	.buffer_bytes_max = 128 * 1024,
@@ -259,7 +251,9 @@
 	}
 }
 
-static int allocate_sram(struct snd_pcm_substream *substream, unsigned size,
+#ifdef CONFIG_GENERIC_ALLOCATOR
+static int allocate_sram(struct snd_pcm_substream *substream,
+		struct gen_pool *sram_pool, unsigned size,
 		struct snd_pcm_hardware *ppcm)
 {
 	struct snd_dma_buffer *buf = &substream->dma_buffer;
@@ -271,9 +265,10 @@
 		return 0;
 
 	ppcm->period_bytes_max = size;
-	iram_virt = sram_alloc(size, &iram_phys);
+	iram_virt = (void *)gen_pool_alloc(sram_pool, size);
 	if (!iram_virt)
 		goto exit1;
+	iram_phys = gen_pool_virt_to_phys(sram_pool, (unsigned)iram_virt);
 	iram_dma = kzalloc(sizeof(*iram_dma), GFP_KERNEL);
 	if (!iram_dma)
 		goto exit2;
@@ -285,11 +280,33 @@
 	return 0;
 exit2:
 	if (iram_virt)
-		sram_free(iram_virt, size);
+		gen_pool_free(sram_pool, (unsigned)iram_virt, size);
 exit1:
 	return -ENOMEM;
 }
 
+static void davinci_free_sram(struct snd_pcm_substream *substream,
+			      struct snd_dma_buffer *iram_dma)
+{
+	struct davinci_runtime_data *prtd = substream->runtime->private_data;
+	struct gen_pool *sram_pool = prtd->params->sram_pool;
+
+	gen_pool_free(sram_pool, (unsigned) iram_dma->area, iram_dma->bytes);
+}
+#else
+static int allocate_sram(struct snd_pcm_substream *substream,
+		struct gen_pool *sram_pool, unsigned size,
+		struct snd_pcm_hardware *ppcm)
+{
+	return 0;
+}
+
+static void davinci_free_sram(struct snd_pcm_substream *substream,
+			      struct snd_dma_buffer *iram_dma)
+{
+}
+#endif
+
 /*
  * Only used with ping/pong.
  * This is called after runtime->dma_addr, period_bytes and data_type are valid
@@ -676,7 +693,7 @@
 
 	ppcm = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
 			&pcm_hardware_playback : &pcm_hardware_capture;
-	allocate_sram(substream, params->sram_size, ppcm);
+	allocate_sram(substream, params->sram_pool, params->sram_size, ppcm);
 	snd_soc_set_runtime_hwparams(substream, ppcm);
 	/* ensure that buffer size is a multiple of period size */
 	ret = snd_pcm_hw_constraint_integer(runtime,
@@ -819,7 +836,7 @@
 		buf->area = NULL;
 		iram_dma = buf->private_data;
 		if (iram_dma) {
-			sram_free(iram_dma->area, iram_dma->bytes);
+			davinci_free_sram(substream, iram_dma);
 			kfree(iram_dma);
 		}
 	}
diff --git a/sound/soc/davinci/davinci-pcm.h b/sound/soc/davinci/davinci-pcm.h
index fc4d01c..b6ef703 100644
--- a/sound/soc/davinci/davinci-pcm.h
+++ b/sound/soc/davinci/davinci-pcm.h
@@ -12,6 +12,7 @@
 #ifndef _DAVINCI_PCM_H
 #define _DAVINCI_PCM_H
 
+#include <linux/genalloc.h>
 #include <linux/platform_data/davinci_asp.h>
 #include <mach/edma.h>
 
@@ -20,6 +21,7 @@
 	unsigned short acnt;
 	dma_addr_t dma_addr;		/* device physical address for DMA */
 	unsigned sram_size;
+	struct gen_pool *sram_pool;	/* SRAM gen_pool for ping pong */
 	enum dma_event_q asp_chan_q;	/* event queue number for ASP channel */
 	enum dma_event_q ram_chan_q;	/* event queue number for RAM channel */
 	unsigned char data_type;	/* xfer data type */
diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig
index 4563b28..3b98159 100644
--- a/sound/soc/fsl/Kconfig
+++ b/sound/soc/fsl/Kconfig
@@ -46,6 +46,20 @@
 	  This will also include the Wolfson Microelectronics WM8776 codec
 	  driver.
 
+config SND_SOC_P1022_RDK
+	tristate "ALSA SoC support for the Freescale / iVeia P1022 RDK board"
+	# I2C is necessary for the WM8960 driver
+	depends on P1022_RDK && I2C
+	select SND_SOC_FSL_SSI
+	select SND_SOC_FSL_UTILS
+	select SND_SOC_POWERPC_DMA
+	select SND_SOC_WM8960
+	default y if P1022_RDK
+	help
+	  Say Y if you want to enable audio on the Freescale / iVeia
+	  P1022 RDK board.  This will also include the Wolfson
+	  Microelectronics WM8960 codec driver.
+
 config SND_SOC_MPC5200_I2S
 	tristate "Freescale MPC5200 PSC in I2S mode driver"
 	depends on PPC_MPC52xx && PPC_BESTCOMM
@@ -98,12 +112,12 @@
 	tristate
 
 config SND_SOC_IMX_PCM_FIQ
-	tristate
+	bool
 	select FIQ
 	select SND_SOC_IMX_PCM
 
 config SND_SOC_IMX_PCM_DMA
-	tristate
+	bool
 	select SND_SOC_DMAENGINE_PCM
 	select SND_SOC_IMX_PCM
 
@@ -112,7 +126,7 @@
 
 config SND_MXC_SOC_WM1133_EV1
 	tristate "Audio on the i.MX31ADS with WM1133-EV1 fitted"
-	depends on MACH_MX31ADS_WM1133_EV1 && EXPERIMENTAL
+	depends on MACH_MX31ADS_WM1133_EV1
 	select SND_SOC_WM8350
 	select SND_SOC_IMX_PCM_FIQ
 	select SND_SOC_IMX_AUDMUX
diff --git a/sound/soc/fsl/Makefile b/sound/soc/fsl/Makefile
index 5f3cf3f..afd3479 100644
--- a/sound/soc/fsl/Makefile
+++ b/sound/soc/fsl/Makefile
@@ -6,6 +6,10 @@
 snd-soc-p1022-ds-objs := p1022_ds.o
 obj-$(CONFIG_SND_SOC_P1022_DS) += snd-soc-p1022-ds.o
 
+# P1022 RDK Machine Support
+snd-soc-p1022-rdk-objs := p1022_rdk.o
+obj-$(CONFIG_SND_SOC_P1022_RDK) += snd-soc-p1022-rdk.o
+
 # Freescale PowerPC SSI/DMA Platform Support
 snd-soc-fsl-ssi-objs := fsl_ssi.o
 snd-soc-fsl-utils-objs := fsl_utils.o
@@ -26,14 +30,18 @@
 # i.MX Platform Support
 snd-soc-imx-ssi-objs := imx-ssi.o
 snd-soc-imx-audmux-objs := imx-audmux.o
+snd-soc-imx-pcm-objs := imx-pcm.o
+ifneq ($(CONFIG_SND_SOC_IMX_PCM_FIQ),)
+	snd-soc-imx-pcm-objs += imx-pcm-fiq.o
+endif
+ifneq ($(CONFIG_SND_SOC_IMX_PCM_DMA),)
+	snd-soc-imx-pcm-objs += imx-pcm-dma.o
+endif
 
 obj-$(CONFIG_SND_SOC_IMX_SSI) += snd-soc-imx-ssi.o
 obj-$(CONFIG_SND_SOC_IMX_AUDMUX) += snd-soc-imx-audmux.o
 
 obj-$(CONFIG_SND_SOC_IMX_PCM) += snd-soc-imx-pcm.o
-snd-soc-imx-pcm-y := imx-pcm.o
-snd-soc-imx-pcm-$(CONFIG_SND_SOC_IMX_PCM_FIQ) += imx-pcm-fiq.o
-snd-soc-imx-pcm-$(CONFIG_SND_SOC_IMX_PCM_DMA) += imx-pcm-dma.o
 
 # i.MX Machine Support
 snd-soc-eukrea-tlv320-objs := eukrea-tlv320.o
diff --git a/sound/soc/fsl/eukrea-tlv320.c b/sound/soc/fsl/eukrea-tlv320.c
index 267d5b4..75ffdf0 100644
--- a/sound/soc/fsl/eukrea-tlv320.c
+++ b/sound/soc/fsl/eukrea-tlv320.c
@@ -93,7 +93,7 @@
 	.num_links	= 1,
 };
 
-static int __devinit eukrea_tlv320_probe(struct platform_device *pdev)
+static int eukrea_tlv320_probe(struct platform_device *pdev)
 {
 	int ret;
 	int int_port = 0, ext_port;
@@ -142,7 +142,7 @@
 	return ret;
 }
 
-static int __devexit eukrea_tlv320_remove(struct platform_device *pdev)
+static int eukrea_tlv320_remove(struct platform_device *pdev)
 {
 	snd_soc_unregister_card(&eukrea_tlv320);
 
@@ -155,7 +155,7 @@
 		.owner = THIS_MODULE,
 	},
 	.probe = eukrea_tlv320_probe,
-	.remove = __devexit_p(eukrea_tlv320_remove),};
+	.remove = eukrea_tlv320_remove,};
 
 module_platform_driver(eukrea_tlv320_driver);
 
diff --git a/sound/soc/fsl/fsl_dma.c b/sound/soc/fsl/fsl_dma.c
index 6feb265..9cc5c1f 100644
--- a/sound/soc/fsl/fsl_dma.c
+++ b/sound/soc/fsl/fsl_dma.c
@@ -894,7 +894,7 @@
 	.pointer	= fsl_dma_pointer,
 };
 
-static int __devinit fsl_soc_dma_probe(struct platform_device *pdev)
+static int fsl_soc_dma_probe(struct platform_device *pdev)
  {
 	struct dma_object *dma;
 	struct device_node *np = pdev->dev.of_node;
@@ -958,7 +958,7 @@
 	return 0;
 }
 
-static int __devexit fsl_soc_dma_remove(struct platform_device *pdev)
+static int fsl_soc_dma_remove(struct platform_device *pdev)
 {
 	struct dma_object *dma = dev_get_drvdata(&pdev->dev);
 
@@ -983,7 +983,7 @@
 		.of_match_table = fsl_soc_dma_ids,
 	},
 	.probe = fsl_soc_dma_probe,
-	.remove = __devexit_p(fsl_soc_dma_remove),
+	.remove = fsl_soc_dma_remove,
 };
 
 module_platform_driver(fsl_soc_dma_driver);
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index 4ed2afd..7decbd9 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -639,7 +639,7 @@
 	}
 }
 
-static int __devinit fsl_ssi_probe(struct platform_device *pdev)
+static int fsl_ssi_probe(struct platform_device *pdev)
 {
 	struct fsl_ssi_private *ssi_private;
 	int ret = 0;
diff --git a/sound/soc/fsl/imx-audmux.c b/sound/soc/fsl/imx-audmux.c
index 524ce62..251f4d9 100644
--- a/sound/soc/fsl/imx-audmux.c
+++ b/sound/soc/fsl/imx-audmux.c
@@ -162,7 +162,7 @@
 	}
 }
 
-static void __devexit audmux_debugfs_remove(void)
+static void audmux_debugfs_remove(void)
 {
 	debugfs_remove_recursive(audmux_debugfs_root);
 }
@@ -244,7 +244,7 @@
 }
 EXPORT_SYMBOL_GPL(imx_audmux_v2_configure_port);
 
-static int __devinit imx_audmux_probe(struct platform_device *pdev)
+static int imx_audmux_probe(struct platform_device *pdev)
 {
 	struct resource *res;
 	struct pinctrl *pinctrl;
@@ -278,7 +278,7 @@
 	return 0;
 }
 
-static int __devexit imx_audmux_remove(struct platform_device *pdev)
+static int imx_audmux_remove(struct platform_device *pdev)
 {
 	if (audmux_type == IMX31_AUDMUX)
 		audmux_debugfs_remove();
@@ -289,7 +289,7 @@
 
 static struct platform_driver imx_audmux_driver = {
 	.probe		= imx_audmux_probe,
-	.remove		= __devexit_p(imx_audmux_remove),
+	.remove		= imx_audmux_remove,
 	.id_table	= imx_audmux_ids,
 	.driver	= {
 		.name	= DRIVER_NAME,
diff --git a/sound/soc/fsl/imx-mc13783.c b/sound/soc/fsl/imx-mc13783.c
index 549b31f..4ae30f2 100644
--- a/sound/soc/fsl/imx-mc13783.c
+++ b/sound/soc/fsl/imx-mc13783.c
@@ -98,7 +98,7 @@
 	.num_dapm_routes = ARRAY_SIZE(imx_mc13783_routes),
 };
 
-static int __devinit imx_mc13783_probe(struct platform_device *pdev)
+static int imx_mc13783_probe(struct platform_device *pdev)
 {
 	int ret;
 
@@ -148,7 +148,7 @@
 	return ret;
 }
 
-static int __devexit imx_mc13783_remove(struct platform_device *pdev)
+static int imx_mc13783_remove(struct platform_device *pdev)
 {
 	snd_soc_unregister_card(&imx_mc13783);
 
@@ -161,7 +161,7 @@
 		.owner = THIS_MODULE,
 	},
 	.probe = imx_mc13783_probe,
-	.remove = __devexit_p(imx_mc13783_remove)
+	.remove = imx_mc13783_remove
 };
 
 module_platform_driver(imx_mc13783_audio_driver);
diff --git a/sound/soc/fsl/imx-pcm-dma.c b/sound/soc/fsl/imx-pcm-dma.c
index d85929b..bf363d8 100644
--- a/sound/soc/fsl/imx-pcm-dma.c
+++ b/sound/soc/fsl/imx-pcm-dma.c
@@ -154,12 +154,12 @@
 	.pcm_free	= imx_pcm_free,
 };
 
-static int __devinit imx_soc_platform_probe(struct platform_device *pdev)
+static int imx_soc_platform_probe(struct platform_device *pdev)
 {
 	return snd_soc_register_platform(&pdev->dev, &imx_soc_platform_mx2);
 }
 
-static int __devexit imx_soc_platform_remove(struct platform_device *pdev)
+static int imx_soc_platform_remove(struct platform_device *pdev)
 {
 	snd_soc_unregister_platform(&pdev->dev);
 	return 0;
@@ -171,7 +171,7 @@
 			.owner = THIS_MODULE,
 	},
 	.probe = imx_soc_platform_probe,
-	.remove = __devexit_p(imx_soc_platform_remove),
+	.remove = imx_soc_platform_remove,
 };
 
 module_platform_driver(imx_pcm_driver);
diff --git a/sound/soc/fsl/imx-pcm-fiq.c b/sound/soc/fsl/imx-pcm-fiq.c
index 9ffc9e6..5ec362a 100644
--- a/sound/soc/fsl/imx-pcm-fiq.c
+++ b/sound/soc/fsl/imx-pcm-fiq.c
@@ -281,7 +281,7 @@
 	.pcm_free	= imx_pcm_fiq_free,
 };
 
-static int __devinit imx_soc_platform_probe(struct platform_device *pdev)
+static int imx_soc_platform_probe(struct platform_device *pdev)
 {
 	struct imx_ssi *ssi = platform_get_drvdata(pdev);
 	int ret;
@@ -315,7 +315,7 @@
 	return ret;
 }
 
-static int __devexit imx_soc_platform_remove(struct platform_device *pdev)
+static int imx_soc_platform_remove(struct platform_device *pdev)
 {
 	snd_soc_unregister_platform(&pdev->dev);
 	return 0;
@@ -328,7 +328,7 @@
 	},
 
 	.probe = imx_soc_platform_probe,
-	.remove = __devexit_p(imx_soc_platform_remove),
+	.remove = imx_soc_platform_remove,
 };
 
 module_platform_driver(imx_pcm_driver);
diff --git a/sound/soc/fsl/imx-pcm.c b/sound/soc/fsl/imx-pcm.c
index 93dc360b..d5cd9ef 100644
--- a/sound/soc/fsl/imx-pcm.c
+++ b/sound/soc/fsl/imx-pcm.c
@@ -103,3 +103,7 @@
 	}
 }
 EXPORT_SYMBOL_GPL(imx_pcm_free);
+
+MODULE_DESCRIPTION("Freescale i.MX PCM driver");
+MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de>");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/fsl/imx-sgtl5000.c b/sound/soc/fsl/imx-sgtl5000.c
index 199408e..424347e 100644
--- a/sound/soc/fsl/imx-sgtl5000.c
+++ b/sound/soc/fsl/imx-sgtl5000.c
@@ -56,7 +56,7 @@
 	SND_SOC_DAPM_SPK("Ext Spk", NULL),
 };
 
-static int __devinit imx_sgtl5000_probe(struct platform_device *pdev)
+static int imx_sgtl5000_probe(struct platform_device *pdev)
 {
 	struct device_node *np = pdev->dev.of_node;
 	struct device_node *ssi_np, *codec_np;
@@ -162,6 +162,7 @@
 	if (ret)
 		goto clk_fail;
 	data->card.num_links = 1;
+	data->card.owner = THIS_MODULE;
 	data->card.dai_link = &data->dai;
 	data->card.dapm_widgets = imx_sgtl5000_dapm_widgets;
 	data->card.num_dapm_widgets = ARRAY_SIZE(imx_sgtl5000_dapm_widgets);
@@ -184,7 +185,7 @@
 	return ret;
 }
 
-static int __devexit imx_sgtl5000_remove(struct platform_device *pdev)
+static int imx_sgtl5000_remove(struct platform_device *pdev)
 {
 	struct imx_sgtl5000_data *data = platform_get_drvdata(pdev);
 
@@ -210,7 +211,7 @@
 		.of_match_table = imx_sgtl5000_dt_ids,
 	},
 	.probe = imx_sgtl5000_probe,
-	.remove = __devexit_p(imx_sgtl5000_remove),
+	.remove = imx_sgtl5000_remove,
 };
 module_platform_driver(imx_sgtl5000_driver);
 
diff --git a/sound/soc/fsl/imx-ssi.c b/sound/soc/fsl/imx-ssi.c
index dd56644..3b48042 100644
--- a/sound/soc/fsl/imx-ssi.c
+++ b/sound/soc/fsl/imx-ssi.c
@@ -638,7 +638,7 @@
 	return ret;
 }
 
-static int __devexit imx_ssi_remove(struct platform_device *pdev)
+static int imx_ssi_remove(struct platform_device *pdev)
 {
 	struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	struct imx_ssi *ssi = platform_get_drvdata(pdev);
@@ -659,7 +659,7 @@
 
 static struct platform_driver imx_ssi_driver = {
 	.probe = imx_ssi_probe,
-	.remove = __devexit_p(imx_ssi_remove),
+	.remove = imx_ssi_remove,
 
 	.driver = {
 		.name = "imx-ssi",
diff --git a/sound/soc/fsl/mpc5200_psc_ac97.c b/sound/soc/fsl/mpc5200_psc_ac97.c
index a313c0a..a4aec04 100644
--- a/sound/soc/fsl/mpc5200_psc_ac97.c
+++ b/sound/soc/fsl/mpc5200_psc_ac97.c
@@ -277,7 +277,7 @@
  * - Probe/remove operations
  * - OF device match table
  */
-static int __devinit psc_ac97_of_probe(struct platform_device *op)
+static int psc_ac97_of_probe(struct platform_device *op)
 {
 	int rc;
 	struct snd_ac97 ac97;
@@ -310,7 +310,7 @@
 	return 0;
 }
 
-static int __devexit psc_ac97_of_remove(struct platform_device *op)
+static int psc_ac97_of_remove(struct platform_device *op)
 {
 	mpc5200_audio_dma_destroy(op);
 	snd_soc_unregister_dais(&op->dev, ARRAY_SIZE(psc_ac97_dai));
@@ -318,7 +318,7 @@
 }
 
 /* Match table for of_platform binding */
-static struct of_device_id psc_ac97_match[] __devinitdata = {
+static struct of_device_id psc_ac97_match[] = {
 	{ .compatible = "fsl,mpc5200-psc-ac97", },
 	{ .compatible = "fsl,mpc5200b-psc-ac97", },
 	{}
@@ -327,7 +327,7 @@
 
 static struct platform_driver psc_ac97_driver = {
 	.probe = psc_ac97_of_probe,
-	.remove = __devexit_p(psc_ac97_of_remove),
+	.remove = psc_ac97_of_remove,
 	.driver = {
 		.name = "mpc5200-psc-ac97",
 		.owner = THIS_MODULE,
diff --git a/sound/soc/fsl/mpc5200_psc_i2s.c b/sound/soc/fsl/mpc5200_psc_i2s.c
index ba1f0a6..b95b966 100644
--- a/sound/soc/fsl/mpc5200_psc_i2s.c
+++ b/sound/soc/fsl/mpc5200_psc_i2s.c
@@ -153,7 +153,7 @@
  * - Probe/remove operations
  * - OF device match table
  */
-static int __devinit psc_i2s_of_probe(struct platform_device *op)
+static int psc_i2s_of_probe(struct platform_device *op)
 {
 	int rc;
 	struct psc_dma *psc_dma;
@@ -205,7 +205,7 @@
 
 }
 
-static int __devexit psc_i2s_of_remove(struct platform_device *op)
+static int psc_i2s_of_remove(struct platform_device *op)
 {
 	mpc5200_audio_dma_destroy(op);
 	snd_soc_unregister_dais(&op->dev, ARRAY_SIZE(psc_i2s_dai));
@@ -213,7 +213,7 @@
 }
 
 /* Match table for of_platform binding */
-static struct of_device_id psc_i2s_match[] __devinitdata = {
+static struct of_device_id psc_i2s_match[] = {
 	{ .compatible = "fsl,mpc5200-psc-i2s", },
 	{ .compatible = "fsl,mpc5200b-psc-i2s", },
 	{}
@@ -222,7 +222,7 @@
 
 static struct platform_driver psc_i2s_driver = {
 	.probe = psc_i2s_of_probe,
-	.remove = __devexit_p(psc_i2s_of_remove),
+	.remove = psc_i2s_of_remove,
 	.driver = {
 		.name = "mpc5200-psc-i2s",
 		.owner = THIS_MODULE,
diff --git a/sound/soc/fsl/mpc8610_hpcd.c b/sound/soc/fsl/mpc8610_hpcd.c
index 9ff9318..228c52e 100644
--- a/sound/soc/fsl/mpc8610_hpcd.c
+++ b/sound/soc/fsl/mpc8610_hpcd.c
@@ -368,7 +368,7 @@
  *
  * This function is called when the platform device is removed.
  */
-static int __devexit mpc8610_hpcd_remove(struct platform_device *pdev)
+static int mpc8610_hpcd_remove(struct platform_device *pdev)
 {
 	struct snd_soc_card *card = platform_get_drvdata(pdev);
 	struct mpc8610_hpcd_data *machine_data =
@@ -382,7 +382,7 @@
 
 static struct platform_driver mpc8610_hpcd_driver = {
 	.probe = mpc8610_hpcd_probe,
-	.remove = __devexit_p(mpc8610_hpcd_remove),
+	.remove = mpc8610_hpcd_remove,
 	.driver = {
 		/* The name must match 'compatible' property in the device tree,
 		 * in lowercase letters.
diff --git a/sound/soc/fsl/mx27vis-aic32x4.c b/sound/soc/fsl/mx27vis-aic32x4.c
index 2b76877..3d10741 100644
--- a/sound/soc/fsl/mx27vis-aic32x4.c
+++ b/sound/soc/fsl/mx27vis-aic32x4.c
@@ -180,7 +180,7 @@
 	.num_dapm_routes = ARRAY_SIZE(aic32x4_dapm_routes),
 };
 
-static int __devinit mx27vis_aic32x4_probe(struct platform_device *pdev)
+static int mx27vis_aic32x4_probe(struct platform_device *pdev)
 {
 	struct snd_mx27vis_platform_data *pdata = pdev->dev.platform_data;
 	int ret;
@@ -219,7 +219,7 @@
 	return ret;
 }
 
-static int __devexit mx27vis_aic32x4_remove(struct platform_device *pdev)
+static int mx27vis_aic32x4_remove(struct platform_device *pdev)
 {
 	snd_soc_unregister_card(&mx27vis_aic32x4);
 
@@ -232,7 +232,7 @@
 		.owner = THIS_MODULE,
 	},
 	.probe = mx27vis_aic32x4_probe,
-	.remove = __devexit_p(mx27vis_aic32x4_remove),
+	.remove = mx27vis_aic32x4_remove,
 };
 
 module_platform_driver(mx27vis_aic32x4_audio_driver);
diff --git a/sound/soc/fsl/p1022_ds.c b/sound/soc/fsl/p1022_ds.c
index 144d496..ba59c23 100644
--- a/sound/soc/fsl/p1022_ds.c
+++ b/sound/soc/fsl/p1022_ds.c
@@ -376,7 +376,7 @@
  *
  * This function is called when the platform device is removed.
  */
-static int __devexit p1022_ds_remove(struct platform_device *pdev)
+static int p1022_ds_remove(struct platform_device *pdev)
 {
 	struct snd_soc_card *card = platform_get_drvdata(pdev);
 	struct machine_data *mdata =
@@ -390,7 +390,7 @@
 
 static struct platform_driver p1022_ds_driver = {
 	.probe = p1022_ds_probe,
-	.remove = __devexit_p(p1022_ds_remove),
+	.remove = p1022_ds_remove,
 	.driver = {
 		/*
 		 * The name must match 'compatible' property in the device tree,
diff --git a/sound/soc/fsl/p1022_rdk.c b/sound/soc/fsl/p1022_rdk.c
new file mode 100644
index 0000000..f215519
--- /dev/null
+++ b/sound/soc/fsl/p1022_rdk.c
@@ -0,0 +1,392 @@
+/**
+ * Freescale P1022RDK ALSA SoC Machine driver
+ *
+ * Author: Timur Tabi <timur@freescale.com>
+ *
+ * Copyright 2012 Freescale Semiconductor, 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.
+ *
+ * Note: in order for audio to work correctly, the output controls need
+ * to be enabled, because they control the clock.  So for playback, for
+ * example:
+ *
+ *      amixer sset 'Left Output Mixer PCM' on
+ *      amixer sset 'Right Output Mixer PCM' on
+ */
+
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/of_device.h>
+#include <linux/slab.h>
+#include <sound/soc.h>
+#include <asm/fsl_guts.h>
+
+#include "fsl_dma.h"
+#include "fsl_ssi.h"
+#include "fsl_utils.h"
+
+/* P1022-specific PMUXCR and DMUXCR bit definitions */
+
+#define CCSR_GUTS_PMUXCR_UART0_I2C1_MASK	0x0001c000
+#define CCSR_GUTS_PMUXCR_UART0_I2C1_UART0_SSI	0x00010000
+#define CCSR_GUTS_PMUXCR_UART0_I2C1_SSI		0x00018000
+
+#define CCSR_GUTS_PMUXCR_SSI_DMA_TDM_MASK	0x00000c00
+#define CCSR_GUTS_PMUXCR_SSI_DMA_TDM_SSI	0x00000000
+
+#define CCSR_GUTS_DMUXCR_PAD	1	/* DMA controller/channel set to pad */
+#define CCSR_GUTS_DMUXCR_SSI	2	/* DMA controller/channel set to SSI */
+
+/*
+ * Set the DMACR register in the GUTS
+ *
+ * The DMACR register determines the source of initiated transfers for each
+ * channel on each DMA controller.  Rather than have a bunch of repetitive
+ * macros for the bit patterns, we just have a function that calculates
+ * them.
+ *
+ * guts: Pointer to GUTS structure
+ * co: The DMA controller (0 or 1)
+ * ch: The channel on the DMA controller (0, 1, 2, or 3)
+ * device: The device to set as the target (CCSR_GUTS_DMUXCR_xxx)
+ */
+static inline void guts_set_dmuxcr(struct ccsr_guts __iomem *guts,
+	unsigned int co, unsigned int ch, unsigned int device)
+{
+	unsigned int shift = 16 + (8 * (1 - co) + 2 * (3 - ch));
+
+	clrsetbits_be32(&guts->dmuxcr, 3 << shift, device << shift);
+}
+
+/* There's only one global utilities register */
+static phys_addr_t guts_phys;
+
+/**
+ * machine_data: machine-specific ASoC device data
+ *
+ * This structure contains data for a single sound platform device on an
+ * P1022 RDK.  Some of the data is taken from the device tree.
+ */
+struct machine_data {
+	struct snd_soc_dai_link dai[2];
+	struct snd_soc_card card;
+	unsigned int dai_format;
+	unsigned int codec_clk_direction;
+	unsigned int cpu_clk_direction;
+	unsigned int clk_frequency;
+	unsigned int dma_id[2];		/* 0 = DMA1, 1 = DMA2, etc */
+	unsigned int dma_channel_id[2]; /* 0 = ch 0, 1 = ch 1, etc*/
+	char platform_name[2][DAI_NAME_SIZE]; /* One for each DMA channel */
+};
+
+/**
+ * p1022_rdk_machine_probe: initialize the board
+ *
+ * This function is used to initialize the board-specific hardware.
+ *
+ * Here we program the DMACR and PMUXCR registers.
+ */
+static int p1022_rdk_machine_probe(struct snd_soc_card *card)
+{
+	struct machine_data *mdata =
+		container_of(card, struct machine_data, card);
+	struct ccsr_guts __iomem *guts;
+
+	guts = ioremap(guts_phys, sizeof(struct ccsr_guts));
+	if (!guts) {
+		dev_err(card->dev, "could not map global utilities\n");
+		return -ENOMEM;
+	}
+
+	/* Enable SSI Tx signal */
+	clrsetbits_be32(&guts->pmuxcr, CCSR_GUTS_PMUXCR_UART0_I2C1_MASK,
+			CCSR_GUTS_PMUXCR_UART0_I2C1_UART0_SSI);
+
+	/* Enable SSI Rx signal */
+	clrsetbits_be32(&guts->pmuxcr, CCSR_GUTS_PMUXCR_SSI_DMA_TDM_MASK,
+			CCSR_GUTS_PMUXCR_SSI_DMA_TDM_SSI);
+
+	/* Enable DMA Channel for SSI */
+	guts_set_dmuxcr(guts, mdata->dma_id[0], mdata->dma_channel_id[0],
+			CCSR_GUTS_DMUXCR_SSI);
+
+	guts_set_dmuxcr(guts, mdata->dma_id[1], mdata->dma_channel_id[1],
+			CCSR_GUTS_DMUXCR_SSI);
+
+	iounmap(guts);
+
+	return 0;
+}
+
+/**
+ * p1022_rdk_startup: program the board with various hardware parameters
+ *
+ * This function takes board-specific information, like clock frequencies
+ * and serial data formats, and passes that information to the codec and
+ * transport drivers.
+ */
+static int p1022_rdk_startup(struct snd_pcm_substream *substream)
+{
+	struct snd_soc_pcm_runtime *rtd = substream->private_data;
+	struct machine_data *mdata =
+		container_of(rtd->card, struct machine_data, card);
+	struct device *dev = rtd->card->dev;
+	int ret = 0;
+
+	/* Tell the codec driver what the serial protocol is. */
+	ret = snd_soc_dai_set_fmt(rtd->codec_dai, mdata->dai_format);
+	if (ret < 0) {
+		dev_err(dev, "could not set codec driver audio format (ret=%i)\n",
+			ret);
+		return ret;
+	}
+
+	ret = snd_soc_dai_set_pll(rtd->codec_dai, 0, 0, mdata->clk_frequency,
+		mdata->clk_frequency);
+	if (ret < 0) {
+		dev_err(dev, "could not set codec PLL frequency (ret=%i)\n",
+			ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+/**
+ * p1022_rdk_machine_remove: Remove the sound device
+ *
+ * This function is called to remove the sound device for one SSI.  We
+ * de-program the DMACR and PMUXCR register.
+ */
+static int p1022_rdk_machine_remove(struct snd_soc_card *card)
+{
+	struct machine_data *mdata =
+		container_of(card, struct machine_data, card);
+	struct ccsr_guts __iomem *guts;
+
+	guts = ioremap(guts_phys, sizeof(struct ccsr_guts));
+	if (!guts) {
+		dev_err(card->dev, "could not map global utilities\n");
+		return -ENOMEM;
+	}
+
+	/* Restore the signal routing */
+	clrbits32(&guts->pmuxcr, CCSR_GUTS_PMUXCR_UART0_I2C1_MASK);
+	clrbits32(&guts->pmuxcr, CCSR_GUTS_PMUXCR_SSI_DMA_TDM_MASK);
+	guts_set_dmuxcr(guts, mdata->dma_id[0], mdata->dma_channel_id[0], 0);
+	guts_set_dmuxcr(guts, mdata->dma_id[1], mdata->dma_channel_id[1], 0);
+
+	iounmap(guts);
+
+	return 0;
+}
+
+/**
+ * p1022_rdk_ops: ASoC machine driver operations
+ */
+static struct snd_soc_ops p1022_rdk_ops = {
+	.startup = p1022_rdk_startup,
+};
+
+/**
+ * p1022_rdk_probe: platform probe function for the machine driver
+ *
+ * Although this is a machine driver, the SSI node is the "master" node with
+ * respect to audio hardware connections.  Therefore, we create a new ASoC
+ * device for each new SSI node that has a codec attached.
+ */
+static int p1022_rdk_probe(struct platform_device *pdev)
+{
+	struct device *dev = pdev->dev.parent;
+	/* ssi_pdev is the platform device for the SSI node that probed us */
+	struct platform_device *ssi_pdev =
+		container_of(dev, struct platform_device, dev);
+	struct device_node *np = ssi_pdev->dev.of_node;
+	struct device_node *codec_np = NULL;
+	struct machine_data *mdata;
+	const u32 *iprop;
+	int ret;
+
+	/* Find the codec node for this SSI. */
+	codec_np = of_parse_phandle(np, "codec-handle", 0);
+	if (!codec_np) {
+		dev_err(dev, "could not find codec node\n");
+		return -EINVAL;
+	}
+
+	mdata = kzalloc(sizeof(struct machine_data), GFP_KERNEL);
+	if (!mdata) {
+		ret = -ENOMEM;
+		goto error_put;
+	}
+
+	mdata->dai[0].cpu_dai_name = dev_name(&ssi_pdev->dev);
+	mdata->dai[0].ops = &p1022_rdk_ops;
+
+	/* ASoC core can match codec with device node */
+	mdata->dai[0].codec_of_node = codec_np;
+
+	/*
+	 * We register two DAIs per SSI, one for playback and the other for
+	 * capture.  We support codecs that have separate DAIs for both playback
+	 * and capture.
+	 */
+	memcpy(&mdata->dai[1], &mdata->dai[0], sizeof(struct snd_soc_dai_link));
+
+	/* The DAI names from the codec (snd_soc_dai_driver.name) */
+	mdata->dai[0].codec_dai_name = "wm8960-hifi";
+	mdata->dai[1].codec_dai_name = mdata->dai[0].codec_dai_name;
+
+	/*
+	 * Configure the SSI for I2S slave mode.  Older device trees have
+	 * an fsl,mode property, but we ignore that since there's really
+	 * only one way to configure the SSI.
+	 */
+	mdata->dai_format = SND_SOC_DAIFMT_NB_NF |
+		SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM;
+	mdata->codec_clk_direction = SND_SOC_CLOCK_OUT;
+	mdata->cpu_clk_direction = SND_SOC_CLOCK_IN;
+
+	/*
+	 * In i2s-slave mode, the codec has its own clock source, so we
+	 * need to get the frequency from the device tree and pass it to
+	 * the codec driver.
+	 */
+	iprop = of_get_property(codec_np, "clock-frequency", NULL);
+	if (!iprop || !*iprop) {
+		dev_err(&pdev->dev, "codec bus-frequency property is missing or invalid\n");
+		ret = -EINVAL;
+		goto error;
+	}
+	mdata->clk_frequency = be32_to_cpup(iprop);
+
+	if (!mdata->clk_frequency) {
+		dev_err(&pdev->dev, "unknown clock frequency\n");
+		ret = -EINVAL;
+		goto error;
+	}
+
+	/* Find the playback DMA channel to use. */
+	mdata->dai[0].platform_name = mdata->platform_name[0];
+	ret = fsl_asoc_get_dma_channel(np, "fsl,playback-dma", &mdata->dai[0],
+				       &mdata->dma_channel_id[0],
+				       &mdata->dma_id[0]);
+	if (ret) {
+		dev_err(&pdev->dev, "missing/invalid playback DMA phandle (ret=%i)\n",
+			ret);
+		goto error;
+	}
+
+	/* Find the capture DMA channel to use. */
+	mdata->dai[1].platform_name = mdata->platform_name[1];
+	ret = fsl_asoc_get_dma_channel(np, "fsl,capture-dma", &mdata->dai[1],
+				       &mdata->dma_channel_id[1],
+				       &mdata->dma_id[1]);
+	if (ret) {
+		dev_err(&pdev->dev, "missing/invalid capture DMA phandle (ret=%i)\n",
+			ret);
+		goto error;
+	}
+
+	/* Initialize our DAI data structure.  */
+	mdata->dai[0].stream_name = "playback";
+	mdata->dai[1].stream_name = "capture";
+	mdata->dai[0].name = mdata->dai[0].stream_name;
+	mdata->dai[1].name = mdata->dai[1].stream_name;
+
+	mdata->card.probe = p1022_rdk_machine_probe;
+	mdata->card.remove = p1022_rdk_machine_remove;
+	mdata->card.name = pdev->name; /* The platform driver name */
+	mdata->card.owner = THIS_MODULE;
+	mdata->card.dev = &pdev->dev;
+	mdata->card.num_links = 2;
+	mdata->card.dai_link = mdata->dai;
+
+	/* Register with ASoC */
+	ret = snd_soc_register_card(&mdata->card);
+	if (ret) {
+		dev_err(&pdev->dev, "could not register card (ret=%i)\n", ret);
+		goto error;
+	}
+
+	return 0;
+
+error:
+	kfree(mdata);
+error_put:
+	of_node_put(codec_np);
+	return ret;
+}
+
+/**
+ * p1022_rdk_remove: remove the platform device
+ *
+ * This function is called when the platform device is removed.
+ */
+static int p1022_rdk_remove(struct platform_device *pdev)
+{
+	struct snd_soc_card *card = platform_get_drvdata(pdev);
+	struct machine_data *mdata =
+		container_of(card, struct machine_data, card);
+
+	snd_soc_unregister_card(card);
+	kfree(mdata);
+
+	return 0;
+}
+
+static struct platform_driver p1022_rdk_driver = {
+	.probe = p1022_rdk_probe,
+	.remove = p1022_rdk_remove,
+	.driver = {
+		/*
+		 * The name must match 'compatible' property in the device tree,
+		 * in lowercase letters.
+		 */
+		.name = "snd-soc-p1022rdk",
+		.owner = THIS_MODULE,
+	},
+};
+
+/**
+ * p1022_rdk_init: machine driver initialization.
+ *
+ * This function is called when this module is loaded.
+ */
+static int __init p1022_rdk_init(void)
+{
+	struct device_node *guts_np;
+	struct resource res;
+
+	/* Get the physical address of the global utilities registers */
+	guts_np = of_find_compatible_node(NULL, NULL, "fsl,p1022-guts");
+	if (of_address_to_resource(guts_np, 0, &res)) {
+		pr_err("snd-soc-p1022rdk: missing/invalid global utils node\n");
+		of_node_put(guts_np);
+		return -EINVAL;
+	}
+	guts_phys = res.start;
+	of_node_put(guts_np);
+
+	return platform_driver_register(&p1022_rdk_driver);
+}
+
+/**
+ * p1022_rdk_exit: machine driver exit
+ *
+ * This function is called when this driver is unloaded.
+ */
+static void __exit p1022_rdk_exit(void)
+{
+	platform_driver_unregister(&p1022_rdk_driver);
+}
+
+late_initcall(p1022_rdk_init);
+module_exit(p1022_rdk_exit);
+
+MODULE_AUTHOR("Timur Tabi <timur@freescale.com>");
+MODULE_DESCRIPTION("Freescale / iVeia P1022 RDK ALSA SoC machine driver");
+MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/fsl/pcm030-audio-fabric.c b/sound/soc/fsl/pcm030-audio-fabric.c
index 4b63ec8..8e52c14 100644
--- a/sound/soc/fsl/pcm030-audio-fabric.c
+++ b/sound/soc/fsl/pcm030-audio-fabric.c
@@ -29,14 +29,14 @@
 
 static struct snd_soc_dai_link pcm030_fabric_dai[] = {
 {
-	.name = "AC97",
+	.name = "AC97.0",
 	.stream_name = "AC97 Analog",
 	.codec_dai_name = "wm9712-hifi",
 	.cpu_dai_name = "mpc5200-psc-ac97.0",
 	.codec_name = "wm9712-codec",
 },
 {
-	.name = "AC97",
+	.name = "AC97.1",
 	.stream_name = "AC97 IEC958",
 	.codec_dai_name = "wm9712-aux",
 	.cpu_dai_name = "mpc5200-psc-ac97.1",
@@ -101,7 +101,7 @@
 	return ret;
 }
 
-static int __devexit pcm030_fabric_remove(struct platform_device *op)
+static int pcm030_fabric_remove(struct platform_device *op)
 {
 	struct pcm030_audio_data *pdata = platform_get_drvdata(op);
 	int ret;
@@ -120,7 +120,7 @@
 
 static struct platform_driver pcm030_fabric_driver = {
 	.probe		= pcm030_fabric_probe,
-	.remove		= __devexit_p(pcm030_fabric_remove),
+	.remove		= pcm030_fabric_remove,
 	.driver		= {
 		.name	= DRV_NAME,
 		.owner	= THIS_MODULE,
diff --git a/sound/soc/jz4740/jz4740-i2s.c b/sound/soc/jz4740/jz4740-i2s.c
index 4134967..6cef491 100644
--- a/sound/soc/jz4740/jz4740-i2s.c
+++ b/sound/soc/jz4740/jz4740-i2s.c
@@ -425,7 +425,7 @@
 	.resume = jz4740_i2s_resume,
 };
 
-static int __devinit jz4740_i2s_dev_probe(struct platform_device *pdev)
+static int jz4740_i2s_dev_probe(struct platform_device *pdev)
 {
 	struct jz4740_i2s *i2s;
 	int ret;
@@ -492,7 +492,7 @@
 	return ret;
 }
 
-static int __devexit jz4740_i2s_dev_remove(struct platform_device *pdev)
+static int jz4740_i2s_dev_remove(struct platform_device *pdev)
 {
 	struct jz4740_i2s *i2s = platform_get_drvdata(pdev);
 
@@ -512,7 +512,7 @@
 
 static struct platform_driver jz4740_i2s_driver = {
 	.probe = jz4740_i2s_dev_probe,
-	.remove = __devexit_p(jz4740_i2s_dev_remove),
+	.remove = jz4740_i2s_dev_remove,
 	.driver = {
 		.name = "jz4740-i2s",
 		.owner = THIS_MODULE,
diff --git a/sound/soc/jz4740/jz4740-pcm.c b/sound/soc/jz4740/jz4740-pcm.c
index 9b8cf25..7100592 100644
--- a/sound/soc/jz4740/jz4740-pcm.c
+++ b/sound/soc/jz4740/jz4740-pcm.c
@@ -335,12 +335,12 @@
 		.pcm_free	= jz4740_pcm_free,
 };
 
-static int __devinit jz4740_pcm_probe(struct platform_device *pdev)
+static int jz4740_pcm_probe(struct platform_device *pdev)
 {
 	return snd_soc_register_platform(&pdev->dev, &jz4740_soc_platform);
 }
 
-static int __devexit jz4740_pcm_remove(struct platform_device *pdev)
+static int jz4740_pcm_remove(struct platform_device *pdev)
 {
 	snd_soc_unregister_platform(&pdev->dev);
 	return 0;
@@ -348,7 +348,7 @@
 
 static struct platform_driver jz4740_pcm_driver = {
 	.probe = jz4740_pcm_probe,
-	.remove = __devexit_p(jz4740_pcm_remove),
+	.remove = jz4740_pcm_remove,
 	.driver = {
 		.name = "jz4740-pcm-audio",
 		.owner = THIS_MODULE,
diff --git a/sound/soc/jz4740/qi_lb60.c b/sound/soc/jz4740/qi_lb60.c
index e8aaff1..55fd6b5 100644
--- a/sound/soc/jz4740/qi_lb60.c
+++ b/sound/soc/jz4740/qi_lb60.c
@@ -96,7 +96,7 @@
 	{ QI_LB60_AMP_GPIO, GPIOF_OUT_INIT_LOW, "AMP" },
 };
 
-static int __devinit qi_lb60_probe(struct platform_device *pdev)
+static int qi_lb60_probe(struct platform_device *pdev)
 {
 	struct snd_soc_card *card = &qi_lb60;
 	int ret;
@@ -116,7 +116,7 @@
 	return ret;
 }
 
-static int __devexit qi_lb60_remove(struct platform_device *pdev)
+static int qi_lb60_remove(struct platform_device *pdev)
 {
 	struct snd_soc_card *card = platform_get_drvdata(pdev);
 
@@ -131,7 +131,7 @@
 		.owner	= THIS_MODULE,
 	},
 	.probe		= qi_lb60_probe,
-	.remove		= __devexit_p(qi_lb60_remove),
+	.remove		= qi_lb60_remove,
 };
 
 module_platform_driver(qi_lb60_driver);
diff --git a/sound/soc/kirkwood/kirkwood-dma.c b/sound/soc/kirkwood/kirkwood-dma.c
index 2ba0814..d3d4bdc 100644
--- a/sound/soc/kirkwood/kirkwood-dma.c
+++ b/sound/soc/kirkwood/kirkwood-dma.c
@@ -22,12 +22,16 @@
 #include "kirkwood.h"
 
 #define KIRKWOOD_RATES \
-	(SNDRV_PCM_RATE_44100 | \
-	 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000)
+	(SNDRV_PCM_RATE_8000_192000 |		\
+	 SNDRV_PCM_RATE_CONTINUOUS |		\
+	 SNDRV_PCM_RATE_KNOT)
+
 #define KIRKWOOD_FORMATS \
 	(SNDRV_PCM_FMTBIT_S16_LE | \
 	 SNDRV_PCM_FMTBIT_S24_LE | \
-	 SNDRV_PCM_FMTBIT_S32_LE)
+	 SNDRV_PCM_FMTBIT_S32_LE | \
+	 SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE | \
+	 SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_BE)
 
 struct kirkwood_dma_priv {
 	struct snd_pcm_substream *play_stream;
@@ -43,10 +47,10 @@
 		 SNDRV_PCM_INFO_PAUSE),
 	.formats		= KIRKWOOD_FORMATS,
 	.rates			= KIRKWOOD_RATES,
-	.rate_min		= 44100,
-	.rate_max		= 96000,
+	.rate_min		= 8000,
+	.rate_max		= 384000,
 	.channels_min		= 1,
-	.channels_max		= 2,
+	.channels_max		= 8,
 	.buffer_bytes_max	= KIRKWOOD_SND_MAX_PERIOD_BYTES * KIRKWOOD_SND_MAX_PERIODS,
 	.period_bytes_min	= KIRKWOOD_SND_MIN_PERIOD_BYTES,
 	.period_bytes_max	= KIRKWOOD_SND_MAX_PERIOD_BYTES,
@@ -368,12 +372,12 @@
 	.pcm_free	= kirkwood_dma_free_dma_buffers,
 };
 
-static int __devinit kirkwood_soc_platform_probe(struct platform_device *pdev)
+static int kirkwood_soc_platform_probe(struct platform_device *pdev)
 {
 	return snd_soc_register_platform(&pdev->dev, &kirkwood_soc_platform);
 }
 
-static int __devexit kirkwood_soc_platform_remove(struct platform_device *pdev)
+static int kirkwood_soc_platform_remove(struct platform_device *pdev)
 {
 	snd_soc_unregister_platform(&pdev->dev);
 	return 0;
@@ -386,7 +390,7 @@
 	},
 
 	.probe = kirkwood_soc_platform_probe,
-	.remove = __devexit_p(kirkwood_soc_platform_remove),
+	.remove = kirkwood_soc_platform_remove,
 };
 
 module_platform_driver(kirkwood_pcm_driver);
diff --git a/sound/soc/kirkwood/kirkwood-i2s.c b/sound/soc/kirkwood/kirkwood-i2s.c
index 1d5db48..282d8b1 100644
--- a/sound/soc/kirkwood/kirkwood-i2s.c
+++ b/sound/soc/kirkwood/kirkwood-i2s.c
@@ -99,6 +99,29 @@
 	} while (value == 0);
 }
 
+static void kirkwood_set_rate(struct snd_soc_dai *dai,
+	struct kirkwood_dma_data *priv, unsigned long rate)
+{
+	uint32_t clks_ctrl;
+
+	if (rate == 44100 || rate == 48000 || rate == 96000) {
+		/* use internal dco for supported rates */
+		dev_dbg(dai->dev, "%s: dco set rate = %lu\n",
+			__func__, rate);
+		kirkwood_set_dco(priv->io, rate);
+
+		clks_ctrl = KIRKWOOD_MCLK_SOURCE_DCO;
+	} else if (!IS_ERR(priv->extclk)) {
+		/* use optional external clk for other rates */
+		dev_dbg(dai->dev, "%s: extclk set rate = %lu -> %lu\n",
+			__func__, rate, 256 * rate);
+		clk_set_rate(priv->extclk, 256 * rate);
+
+		clks_ctrl = KIRKWOOD_MCLK_SOURCE_EXTCLK;
+	}
+	writel(clks_ctrl, priv->io + KIRKWOOD_CLOCKS_CTRL);
+}
+
 static int kirkwood_i2s_startup(struct snd_pcm_substream *substream,
 		struct snd_soc_dai *dai)
 {
@@ -113,26 +136,21 @@
 				 struct snd_soc_dai *dai)
 {
 	struct kirkwood_dma_data *priv = snd_soc_dai_get_drvdata(dai);
-	unsigned int i2s_reg, reg;
-	unsigned long i2s_value, value;
+	uint32_t ctl_play, ctl_rec;
+	unsigned int i2s_reg;
+	unsigned long i2s_value;
 
 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
 		i2s_reg = KIRKWOOD_I2S_PLAYCTL;
-		reg = KIRKWOOD_PLAYCTL;
 	} else {
 		i2s_reg = KIRKWOOD_I2S_RECCTL;
-		reg = KIRKWOOD_RECCTL;
 	}
 
-	/* set dco conf */
-	kirkwood_set_dco(priv->io, params_rate(params));
+	kirkwood_set_rate(dai, priv, params_rate(params));
 
 	i2s_value = readl(priv->io+i2s_reg);
 	i2s_value &= ~KIRKWOOD_I2S_CTL_SIZE_MASK;
 
-	value = readl(priv->io+reg);
-	value &= ~KIRKWOOD_PLAYCTL_SIZE_MASK;
-
 	/*
 	 * Size settings in play/rec i2s control regs and play/rec control
 	 * regs must be the same.
@@ -140,38 +158,57 @@
 	switch (params_format(params)) {
 	case SNDRV_PCM_FORMAT_S16_LE:
 		i2s_value |= KIRKWOOD_I2S_CTL_SIZE_16;
-		value |= KIRKWOOD_PLAYCTL_SIZE_16_C;
+		ctl_play = KIRKWOOD_PLAYCTL_SIZE_16_C |
+			   KIRKWOOD_PLAYCTL_I2S_EN;
+		ctl_rec = KIRKWOOD_RECCTL_SIZE_16_C |
+			  KIRKWOOD_RECCTL_I2S_EN;
 		break;
 	/*
 	 * doesn't work... S20_3LE != kirkwood 20bit format ?
 	 *
 	case SNDRV_PCM_FORMAT_S20_3LE:
 		i2s_value |= KIRKWOOD_I2S_CTL_SIZE_20;
-		value |= KIRKWOOD_PLAYCTL_SIZE_20;
+		ctl_play = KIRKWOOD_PLAYCTL_SIZE_20 |
+			   KIRKWOOD_PLAYCTL_I2S_EN;
+		ctl_rec = KIRKWOOD_RECCTL_SIZE_20 |
+			  KIRKWOOD_RECCTL_I2S_EN;
 		break;
 	*/
 	case SNDRV_PCM_FORMAT_S24_LE:
 		i2s_value |= KIRKWOOD_I2S_CTL_SIZE_24;
-		value |= KIRKWOOD_PLAYCTL_SIZE_24;
+		ctl_play = KIRKWOOD_PLAYCTL_SIZE_24 |
+			   KIRKWOOD_PLAYCTL_I2S_EN;
+		ctl_rec = KIRKWOOD_RECCTL_SIZE_24 |
+			  KIRKWOOD_RECCTL_I2S_EN;
 		break;
 	case SNDRV_PCM_FORMAT_S32_LE:
 		i2s_value |= KIRKWOOD_I2S_CTL_SIZE_32;
-		value |= KIRKWOOD_PLAYCTL_SIZE_32;
+		ctl_play = KIRKWOOD_PLAYCTL_SIZE_32 |
+			   KIRKWOOD_PLAYCTL_I2S_EN;
+		ctl_rec = KIRKWOOD_RECCTL_SIZE_32 |
+			  KIRKWOOD_RECCTL_I2S_EN;
 		break;
 	default:
 		return -EINVAL;
 	}
 
 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
-		value &= ~KIRKWOOD_PLAYCTL_MONO_MASK;
 		if (params_channels(params) == 1)
-			value |= KIRKWOOD_PLAYCTL_MONO_BOTH;
+			ctl_play |= KIRKWOOD_PLAYCTL_MONO_BOTH;
 		else
-			value |= KIRKWOOD_PLAYCTL_MONO_OFF;
+			ctl_play |= KIRKWOOD_PLAYCTL_MONO_OFF;
+
+		priv->ctl_play &= ~(KIRKWOOD_PLAYCTL_MONO_MASK |
+				    KIRKWOOD_PLAYCTL_I2S_EN |
+				    KIRKWOOD_PLAYCTL_SPDIF_EN |
+				    KIRKWOOD_PLAYCTL_SIZE_MASK);
+		priv->ctl_play |= ctl_play;
+	} else {
+		priv->ctl_rec &= ~KIRKWOOD_RECCTL_SIZE_MASK;
+		priv->ctl_rec |= ctl_rec;
 	}
 
 	writel(i2s_value, priv->io+i2s_reg);
-	writel(value, priv->io+reg);
 
 	return 0;
 }
@@ -205,20 +242,18 @@
 
 	switch (cmd) {
 	case SNDRV_PCM_TRIGGER_START:
+		/* configure */
+		ctl = priv->ctl_play;
+		value = ctl & ~(KIRKWOOD_PLAYCTL_I2S_EN |
+				KIRKWOOD_PLAYCTL_SPDIF_EN);
+		writel(value, priv->io + KIRKWOOD_PLAYCTL);
+
+		/* enable interrupts */
 		value = readl(priv->io + KIRKWOOD_INT_MASK);
 		value |= KIRKWOOD_INT_CAUSE_PLAY_BYTES;
 		writel(value, priv->io + KIRKWOOD_INT_MASK);
 
-		/* configure audio & enable i2s playback */
-		ctl &= ~KIRKWOOD_PLAYCTL_BURST_MASK;
-		ctl &= ~(KIRKWOOD_PLAYCTL_PAUSE | KIRKWOOD_PLAYCTL_I2S_MUTE
-				| KIRKWOOD_PLAYCTL_SPDIF_EN);
-
-		if (priv->burst == 32)
-			ctl |= KIRKWOOD_PLAYCTL_BURST_32;
-		else
-			ctl |= KIRKWOOD_PLAYCTL_BURST_128;
-		ctl |= KIRKWOOD_PLAYCTL_I2S_EN;
+		/* enable playback */
 		writel(ctl, priv->io + KIRKWOOD_PLAYCTL);
 		break;
 
@@ -259,30 +294,24 @@
 				int cmd, struct snd_soc_dai *dai)
 {
 	struct kirkwood_dma_data *priv = snd_soc_dai_get_drvdata(dai);
-	unsigned long value;
+	uint32_t ctl, value;
 
 	value = readl(priv->io + KIRKWOOD_RECCTL);
 
 	switch (cmd) {
 	case SNDRV_PCM_TRIGGER_START:
+		/* configure */
+		ctl = priv->ctl_rec;
+		value = ctl & ~KIRKWOOD_RECCTL_I2S_EN;
+		writel(value, priv->io + KIRKWOOD_RECCTL);
+
+		/* enable interrupts */
 		value = readl(priv->io + KIRKWOOD_INT_MASK);
 		value |= KIRKWOOD_INT_CAUSE_REC_BYTES;
 		writel(value, priv->io + KIRKWOOD_INT_MASK);
 
-		/* configure audio & enable i2s record */
-		value = readl(priv->io + KIRKWOOD_RECCTL);
-		value &= ~KIRKWOOD_RECCTL_BURST_MASK;
-		value &= ~KIRKWOOD_RECCTL_MONO;
-		value &= ~(KIRKWOOD_RECCTL_PAUSE | KIRKWOOD_RECCTL_MUTE
-			| KIRKWOOD_RECCTL_SPDIF_EN);
-
-		if (priv->burst == 32)
-			value |= KIRKWOOD_RECCTL_BURST_32;
-		else
-			value |= KIRKWOOD_RECCTL_BURST_128;
-		value |= KIRKWOOD_RECCTL_I2S_EN;
-
-		writel(value, priv->io + KIRKWOOD_RECCTL);
+		/* enable record */
+		writel(ctl, priv->io + KIRKWOOD_RECCTL);
 		break;
 
 	case SNDRV_PCM_TRIGGER_STOP:
@@ -389,112 +418,146 @@
 		.channels_min = 1,
 		.channels_max = 2,
 		.rates = KIRKWOOD_I2S_RATES,
-		.formats = KIRKWOOD_I2S_FORMATS,},
+		.formats = KIRKWOOD_I2S_FORMATS,
+	},
 	.capture = {
 		.channels_min = 1,
 		.channels_max = 2,
 		.rates = KIRKWOOD_I2S_RATES,
-		.formats = KIRKWOOD_I2S_FORMATS,},
+		.formats = KIRKWOOD_I2S_FORMATS,
+	},
 	.ops = &kirkwood_i2s_dai_ops,
 };
 
-static __devinit int kirkwood_i2s_dev_probe(struct platform_device *pdev)
+static struct snd_soc_dai_driver kirkwood_i2s_dai_extclk = {
+	.probe = kirkwood_i2s_probe,
+	.remove = kirkwood_i2s_remove,
+	.playback = {
+		.channels_min = 1,
+		.channels_max = 2,
+		.rates = SNDRV_PCM_RATE_8000_192000 |
+			 SNDRV_PCM_RATE_CONTINUOUS |
+			 SNDRV_PCM_RATE_KNOT,
+		.formats = KIRKWOOD_I2S_FORMATS,
+	},
+	.capture = {
+		.channels_min = 1,
+		.channels_max = 2,
+		.rates = SNDRV_PCM_RATE_8000_192000 |
+			 SNDRV_PCM_RATE_CONTINUOUS |
+			 SNDRV_PCM_RATE_KNOT,
+		.formats = KIRKWOOD_I2S_FORMATS,
+	},
+	.ops = &kirkwood_i2s_dai_ops,
+};
+
+static int kirkwood_i2s_dev_probe(struct platform_device *pdev)
 {
-	struct resource *mem;
-	struct kirkwood_asoc_platform_data *data =
-		pdev->dev.platform_data;
+	struct kirkwood_asoc_platform_data *data = pdev->dev.platform_data;
+	struct snd_soc_dai_driver *soc_dai = &kirkwood_i2s_dai;
 	struct kirkwood_dma_data *priv;
+	struct resource *mem;
 	int err;
 
-	priv = kzalloc(sizeof(struct kirkwood_dma_data), GFP_KERNEL);
+	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
 	if (!priv) {
 		dev_err(&pdev->dev, "allocation failed\n");
-		err = -ENOMEM;
-		goto error;
+		return -ENOMEM;
 	}
 	dev_set_drvdata(&pdev->dev, priv);
 
 	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (!mem) {
 		dev_err(&pdev->dev, "platform_get_resource failed\n");
-		err = -ENXIO;
-		goto err_alloc;
+		return -ENXIO;
 	}
 
-	priv->mem = request_mem_region(mem->start, SZ_16K, DRV_NAME);
-	if (!priv->mem) {
-		dev_err(&pdev->dev, "request_mem_region failed\n");
-		err = -EBUSY;
-		goto err_alloc;
-	}
-
-	priv->io = ioremap(priv->mem->start, SZ_16K);
+	priv->io = devm_request_and_ioremap(&pdev->dev, mem);
 	if (!priv->io) {
-		dev_err(&pdev->dev, "ioremap failed\n");
-		err = -ENOMEM;
-		goto err_iomem;
+		dev_err(&pdev->dev, "devm_request_and_ioremap failed\n");
+		return -ENOMEM;
 	}
 
 	priv->irq = platform_get_irq(pdev, 0);
 	if (priv->irq <= 0) {
 		dev_err(&pdev->dev, "platform_get_irq failed\n");
-		err = -ENXIO;
-		goto err_ioremap;
+		return -ENXIO;
 	}
 
 	if (!data) {
 		dev_err(&pdev->dev, "no platform data ?!\n");
-		err = -EINVAL;
-		goto err_ioremap;
+		return -EINVAL;
 	}
 
 	priv->burst = data->burst;
 
-	priv->clk = clk_get(&pdev->dev, NULL);
+	priv->clk = devm_clk_get(&pdev->dev, NULL);
 	if (IS_ERR(priv->clk)) {
 		dev_err(&pdev->dev, "no clock\n");
-		err = PTR_ERR(priv->clk);
-		goto err_ioremap;
+		return PTR_ERR(priv->clk);
 	}
-	clk_prepare_enable(priv->clk);
 
-	err = snd_soc_register_dai(&pdev->dev, &kirkwood_i2s_dai);
+	err = clk_prepare_enable(priv->clk);
+	if (err < 0)
+		return err;
+
+	priv->extclk = clk_get(&pdev->dev, "extclk");
+	if (!IS_ERR(priv->extclk)) {
+		if (priv->extclk == priv->clk) {
+			clk_put(priv->extclk);
+			priv->extclk = ERR_PTR(-EINVAL);
+		} else {
+			dev_info(&pdev->dev, "found external clock\n");
+			clk_prepare_enable(priv->extclk);
+			soc_dai = &kirkwood_i2s_dai_extclk;
+		}
+	}
+
+	/* Some sensible defaults - this reflects the powerup values */
+	priv->ctl_play = KIRKWOOD_PLAYCTL_SIZE_24;
+	priv->ctl_rec = KIRKWOOD_RECCTL_SIZE_24;
+
+	/* Select the burst size */
+	if (data->burst == 32) {
+		priv->ctl_play |= KIRKWOOD_PLAYCTL_BURST_32;
+		priv->ctl_rec |= KIRKWOOD_RECCTL_BURST_32;
+	} else {
+		priv->ctl_play |= KIRKWOOD_PLAYCTL_BURST_128;
+		priv->ctl_rec |= KIRKWOOD_RECCTL_BURST_128;
+	}
+
+	err = snd_soc_register_dai(&pdev->dev, soc_dai);
 	if (!err)
 		return 0;
 	dev_err(&pdev->dev, "snd_soc_register_dai failed\n");
 
+	if (!IS_ERR(priv->extclk)) {
+		clk_disable_unprepare(priv->extclk);
+		clk_put(priv->extclk);
+	}
 	clk_disable_unprepare(priv->clk);
-	clk_put(priv->clk);
 
-err_ioremap:
-	iounmap(priv->io);
-err_iomem:
-	release_mem_region(priv->mem->start, SZ_16K);
-err_alloc:
-	kfree(priv);
-error:
 	return err;
 }
 
-static __devexit int kirkwood_i2s_dev_remove(struct platform_device *pdev)
+static int kirkwood_i2s_dev_remove(struct platform_device *pdev)
 {
 	struct kirkwood_dma_data *priv = dev_get_drvdata(&pdev->dev);
 
 	snd_soc_unregister_dai(&pdev->dev);
 
+	if (!IS_ERR(priv->extclk)) {
+		clk_disable_unprepare(priv->extclk);
+		clk_put(priv->extclk);
+	}
 	clk_disable_unprepare(priv->clk);
-	clk_put(priv->clk);
-
-	iounmap(priv->io);
-	release_mem_region(priv->mem->start, SZ_16K);
-	kfree(priv);
 
 	return 0;
 }
 
 static struct platform_driver kirkwood_i2s_driver = {
 	.probe  = kirkwood_i2s_dev_probe,
-	.remove = __devexit_p(kirkwood_i2s_dev_remove),
+	.remove = kirkwood_i2s_dev_remove,
 	.driver = {
 		.name = DRV_NAME,
 		.owner = THIS_MODULE,
diff --git a/sound/soc/kirkwood/kirkwood-openrd.c b/sound/soc/kirkwood/kirkwood-openrd.c
index c28540a..b979c71 100644
--- a/sound/soc/kirkwood/kirkwood-openrd.c
+++ b/sound/soc/kirkwood/kirkwood-openrd.c
@@ -71,7 +71,7 @@
 	.num_links = ARRAY_SIZE(openrd_client_dai),
 };
 
-static int __devinit openrd_probe(struct platform_device *pdev)
+static int openrd_probe(struct platform_device *pdev)
 {
 	struct snd_soc_card *card = &openrd_client;
 	int ret;
@@ -85,7 +85,7 @@
 	return ret;
 }
 
-static int __devexit openrd_remove(struct platform_device *pdev)
+static int openrd_remove(struct platform_device *pdev)
 {
 	struct snd_soc_card *card = platform_get_drvdata(pdev);
 
@@ -99,7 +99,7 @@
 		.owner	= THIS_MODULE,
 	},
 	.probe		= openrd_probe,
-	.remove		= __devexit_p(openrd_remove),
+	.remove		= openrd_remove,
 };
 
 module_platform_driver(openrd_driver);
diff --git a/sound/soc/kirkwood/kirkwood-t5325.c b/sound/soc/kirkwood/kirkwood-t5325.c
index c67bbc5..1d0ed6f 100644
--- a/sound/soc/kirkwood/kirkwood-t5325.c
+++ b/sound/soc/kirkwood/kirkwood-t5325.c
@@ -92,7 +92,7 @@
 	.num_dapm_routes = ARRAY_SIZE(t5325_route),
 };
 
-static int __devinit t5325_probe(struct platform_device *pdev)
+static int t5325_probe(struct platform_device *pdev)
 {
 	struct snd_soc_card *card = &t5325;
 	int ret;
@@ -106,7 +106,7 @@
 	return ret;
 }
 
-static int __devexit t5325_remove(struct platform_device *pdev)
+static int t5325_remove(struct platform_device *pdev)
 {
 	struct snd_soc_card *card = platform_get_drvdata(pdev);
 
@@ -120,7 +120,7 @@
 		.owner	= THIS_MODULE,
 	},
 	.probe		= t5325_probe,
-	.remove		= __devexit_p(t5325_remove),
+	.remove		= t5325_remove,
 };
 
 module_platform_driver(t5325_driver);
diff --git a/sound/soc/kirkwood/kirkwood.h b/sound/soc/kirkwood/kirkwood.h
index f9084d8..4d92637 100644
--- a/sound/soc/kirkwood/kirkwood.h
+++ b/sound/soc/kirkwood/kirkwood.h
@@ -77,6 +77,11 @@
 #define KIRKWOOD_DCO_SPCR_STATUS		0x120c
 #define KIRKWOOD_DCO_SPCR_STATUS_DCO_LOCK	(1<<16)
 
+#define KIRKWOOD_CLOCKS_CTRL			0x1230
+#define KIRKWOOD_MCLK_SOURCE_MASK		(3<<0)
+#define KIRKWOOD_MCLK_SOURCE_DCO		(0<<0)
+#define KIRKWOOD_MCLK_SOURCE_EXTCLK		(3<<0)
+
 #define KIRKWOOD_ERR_CAUSE			0x1300
 #define KIRKWOOD_ERR_MASK			0x1304
 
@@ -119,11 +124,13 @@
 #define KIRKWOOD_SND_MAX_PERIOD_BYTES		0x4000
 
 struct kirkwood_dma_data {
-	struct resource *mem;
 	void __iomem *io;
+	struct clk *clk;
+	struct clk *extclk;
+	uint32_t ctl_play;
+	uint32_t ctl_rec;
 	int irq;
 	int burst;
-	struct clk *clk;
 };
 
 #endif
diff --git a/sound/soc/mid-x86/mfld_machine.c b/sound/soc/mid-x86/mfld_machine.c
index 2cc7782..4139116 100644
--- a/sound/soc/mid-x86/mfld_machine.c
+++ b/sound/soc/mid-x86/mfld_machine.c
@@ -358,7 +358,7 @@
 	return IRQ_HANDLED;
 }
 
-static int __devinit snd_mfld_mc_probe(struct platform_device *pdev)
+static int snd_mfld_mc_probe(struct platform_device *pdev)
 {
 	int ret_val = 0, irq;
 	struct mfld_mc_private *mc_drv_ctx;
@@ -417,7 +417,7 @@
 	return ret_val;
 }
 
-static int __devexit snd_mfld_mc_remove(struct platform_device *pdev)
+static int snd_mfld_mc_remove(struct platform_device *pdev)
 {
 	struct mfld_mc_private *mc_drv_ctx = platform_get_drvdata(pdev);
 
@@ -435,7 +435,7 @@
 		.name = "msic_audio",
 	},
 	.probe = snd_mfld_mc_probe,
-	.remove = __devexit_p(snd_mfld_mc_remove),
+	.remove = snd_mfld_mc_remove,
 };
 
 module_platform_driver(snd_mfld_mc_driver);
diff --git a/sound/soc/mxs/mxs-pcm.c b/sound/soc/mxs/mxs-pcm.c
index f82d766..564b5b6 100644
--- a/sound/soc/mxs/mxs-pcm.c
+++ b/sound/soc/mxs/mxs-pcm.c
@@ -220,13 +220,13 @@
 	.pcm_free	= mxs_pcm_free,
 };
 
-int __devinit mxs_pcm_platform_register(struct device *dev)
+int mxs_pcm_platform_register(struct device *dev)
 {
 	return snd_soc_register_platform(dev, &mxs_soc_platform);
 }
 EXPORT_SYMBOL_GPL(mxs_pcm_platform_register);
 
-void __devexit mxs_pcm_platform_unregister(struct device *dev)
+void mxs_pcm_platform_unregister(struct device *dev)
 {
 	snd_soc_unregister_platform(dev);
 }
diff --git a/sound/soc/mxs/mxs-saif.c b/sound/soc/mxs/mxs-saif.c
index c294fbb..365d9d2 100644
--- a/sound/soc/mxs/mxs-saif.c
+++ b/sound/soc/mxs/mxs-saif.c
@@ -229,6 +229,7 @@
 	saif->mclk_in_use = 0;
 	return 0;
 }
+EXPORT_SYMBOL_GPL(mxs_saif_put_mclk);
 
 /*
  * Get MCLK and set clock rate, then enable it
@@ -282,6 +283,7 @@
 
 	return 0;
 }
+EXPORT_SYMBOL_GPL(mxs_saif_get_mclk);
 
 /*
  * SAIF DAI format configuration.
@@ -655,7 +657,7 @@
 	return IRQ_HANDLED;
 }
 
-static int __devinit mxs_saif_probe(struct platform_device *pdev)
+static int mxs_saif_probe(struct platform_device *pdev)
 {
 	struct device_node *np = pdev->dev.of_node;
 	struct resource *iores, *dmares;
@@ -790,7 +792,7 @@
 	return ret;
 }
 
-static int __devexit mxs_saif_remove(struct platform_device *pdev)
+static int mxs_saif_remove(struct platform_device *pdev)
 {
 	mxs_pcm_platform_unregister(&pdev->dev);
 	snd_soc_unregister_dai(&pdev->dev);
@@ -806,7 +808,7 @@
 
 static struct platform_driver mxs_saif_driver = {
 	.probe = mxs_saif_probe,
-	.remove = __devexit_p(mxs_saif_remove),
+	.remove = mxs_saif_remove,
 
 	.driver = {
 		.name = "mxs-saif",
diff --git a/sound/soc/mxs/mxs-sgtl5000.c b/sound/soc/mxs/mxs-sgtl5000.c
index 215113b..b1d9b5e 100644
--- a/sound/soc/mxs/mxs-sgtl5000.c
+++ b/sound/soc/mxs/mxs-sgtl5000.c
@@ -112,7 +112,7 @@
 	.num_links	= ARRAY_SIZE(mxs_sgtl5000_dai),
 };
 
-static int __devinit mxs_sgtl5000_probe_dt(struct platform_device *pdev)
+static int mxs_sgtl5000_probe_dt(struct platform_device *pdev)
 {
 	struct device_node *np = pdev->dev.of_node;
 	struct device_node *saif_np[2], *codec_np;
@@ -145,7 +145,7 @@
 	return ret;
 }
 
-static int __devinit mxs_sgtl5000_probe(struct platform_device *pdev)
+static int mxs_sgtl5000_probe(struct platform_device *pdev)
 {
 	struct snd_soc_card *card = &mxs_sgtl5000;
 	int ret;
@@ -176,7 +176,7 @@
 	return 0;
 }
 
-static int __devexit mxs_sgtl5000_remove(struct platform_device *pdev)
+static int mxs_sgtl5000_remove(struct platform_device *pdev)
 {
 	struct snd_soc_card *card = platform_get_drvdata(pdev);
 
@@ -200,7 +200,7 @@
 		.of_match_table = mxs_sgtl5000_dt_ids,
 	},
 	.probe = mxs_sgtl5000_probe,
-	.remove = __devexit_p(mxs_sgtl5000_remove),
+	.remove = mxs_sgtl5000_remove,
 };
 
 module_platform_driver(mxs_sgtl5000_audio_driver);
diff --git a/sound/soc/nuc900/nuc900-ac97.c b/sound/soc/nuc900/nuc900-ac97.c
index 946020a..0418467 100644
--- a/sound/soc/nuc900/nuc900-ac97.c
+++ b/sound/soc/nuc900/nuc900-ac97.c
@@ -314,7 +314,7 @@
 	.ops = &nuc900_ac97_dai_ops,
 };
 
-static int __devinit nuc900_ac97_drvprobe(struct platform_device *pdev)
+static int nuc900_ac97_drvprobe(struct platform_device *pdev)
 {
 	struct nuc900_audio *nuc900_audio;
 	int ret;
@@ -382,7 +382,7 @@
 	return ret;
 }
 
-static int __devexit nuc900_ac97_drvremove(struct platform_device *pdev)
+static int nuc900_ac97_drvremove(struct platform_device *pdev)
 {
 	snd_soc_unregister_dai(&pdev->dev);
 
@@ -403,7 +403,7 @@
 		.owner	= THIS_MODULE,
 	},
 	.probe		= nuc900_ac97_drvprobe,
-	.remove		= __devexit_p(nuc900_ac97_drvremove),
+	.remove		= nuc900_ac97_drvremove,
 };
 
 module_platform_driver(nuc900_ac97_driver);
diff --git a/sound/soc/nuc900/nuc900-pcm.c b/sound/soc/nuc900/nuc900-pcm.c
index 37585b4..c894ff0 100644
--- a/sound/soc/nuc900/nuc900-pcm.c
+++ b/sound/soc/nuc900/nuc900-pcm.c
@@ -337,12 +337,12 @@
 	.pcm_free	= nuc900_dma_free_dma_buffers,
 };
 
-static int __devinit nuc900_soc_platform_probe(struct platform_device *pdev)
+static int nuc900_soc_platform_probe(struct platform_device *pdev)
 {
 	return snd_soc_register_platform(&pdev->dev, &nuc900_soc_platform);
 }
 
-static int __devexit nuc900_soc_platform_remove(struct platform_device *pdev)
+static int nuc900_soc_platform_remove(struct platform_device *pdev)
 {
 	snd_soc_unregister_platform(&pdev->dev);
 	return 0;
@@ -355,7 +355,7 @@
 	},
 
 	.probe = nuc900_soc_platform_probe,
-	.remove = __devexit_p(nuc900_soc_platform_remove),
+	.remove = nuc900_soc_platform_remove,
 };
 
 module_platform_driver(nuc900_pcm_driver);
diff --git a/sound/soc/omap/ams-delta.c b/sound/soc/omap/ams-delta.c
index d8e96b2..2600447 100644
--- a/sound/soc/omap/ams-delta.c
+++ b/sound/soc/omap/ams-delta.c
@@ -575,7 +575,7 @@
 };
 
 /* Module init/exit */
-static __devinit int ams_delta_probe(struct platform_device *pdev)
+static int ams_delta_probe(struct platform_device *pdev)
 {
 	struct snd_soc_card *card = &ams_delta_audio_card;
 	int ret;
@@ -591,7 +591,7 @@
 	return 0;
 }
 
-static int __devexit ams_delta_remove(struct platform_device *pdev)
+static int ams_delta_remove(struct platform_device *pdev)
 {
 	struct snd_soc_card *card = platform_get_drvdata(pdev);
 
@@ -616,7 +616,7 @@
 		.owner = THIS_MODULE,
 	},
 	.probe = ams_delta_probe,
-	.remove = __devexit_p(ams_delta_remove),
+	.remove = ams_delta_remove,
 };
 
 module_platform_driver(ams_delta_driver);
diff --git a/sound/soc/omap/mcbsp.c b/sound/soc/omap/mcbsp.c
index afb8d4f..285c836 100644
--- a/sound/soc/omap/mcbsp.c
+++ b/sound/soc/omap/mcbsp.c
@@ -28,8 +28,6 @@
 
 #include <linux/platform_data/asoc-ti-mcbsp.h>
 
-#include <plat/cpu.h>
-
 #include "mcbsp.h"
 
 static void omap_mcbsp_write(struct omap_mcbsp *mcbsp, u16 reg, u32 val)
@@ -612,7 +610,7 @@
 	 * system will refuse to enter idle if the CLKS pin source is not reset
 	 * back to internal source.
 	 */
-	if (!cpu_class_is_omap1())
+	if (!mcbsp_omap1())
 		omap2_mcbsp_set_clks_src(mcbsp, MCBSP_CLKS_PRCM_SRC);
 
 	spin_lock(&mcbsp->lock);
@@ -932,8 +930,7 @@
 	.attrs = (struct attribute **)sidetone_attrs,
 };
 
-static int __devinit omap_st_add(struct omap_mcbsp *mcbsp,
-				 struct resource *res)
+static int omap_st_add(struct omap_mcbsp *mcbsp, struct resource *res)
 {
 	struct omap_mcbsp_st_data *st_data;
 	int err;
@@ -959,7 +956,7 @@
  * McBSP1 and McBSP3 are directly mapped on 1610 and 1510.
  * 730 has only 2 McBSP, and both of them are MPU peripherals.
  */
-int __devinit omap_mcbsp_init(struct platform_device *pdev)
+int omap_mcbsp_init(struct platform_device *pdev)
 {
 	struct omap_mcbsp *mcbsp = platform_get_drvdata(pdev);
 	struct resource *res;
@@ -1087,7 +1084,7 @@
 	return ret;
 }
 
-void __devexit omap_mcbsp_sysfs_remove(struct omap_mcbsp *mcbsp)
+void omap_mcbsp_sysfs_remove(struct omap_mcbsp *mcbsp)
 {
 	if (mcbsp->pdata->buffer_size)
 		sysfs_remove_group(&mcbsp->dev->kobj, &additional_attr_group);
diff --git a/sound/soc/omap/mcbsp.h b/sound/soc/omap/mcbsp.h
index 49a6725..f93e0b0 100644
--- a/sound/soc/omap/mcbsp.h
+++ b/sound/soc/omap/mcbsp.h
@@ -26,6 +26,12 @@
 
 #include "omap-pcm.h"
 
+#ifdef CONFIG_ARCH_OMAP1
+#define mcbsp_omap1()	1
+#else
+#define mcbsp_omap1()	0
+#endif
+
 /* McBSP register numbers. Register address offset = num * reg_step */
 enum {
 	/* Common registers */
@@ -341,7 +347,7 @@
 int omap_st_disable(struct omap_mcbsp *mcbsp);
 int omap_st_is_enabled(struct omap_mcbsp *mcbsp);
 
-int __devinit omap_mcbsp_init(struct platform_device *pdev);
-void __devexit omap_mcbsp_sysfs_remove(struct omap_mcbsp *mcbsp);
+int omap_mcbsp_init(struct platform_device *pdev);
+void omap_mcbsp_sysfs_remove(struct omap_mcbsp *mcbsp);
 
 #endif /* __ASOC_MCBSP_H */
diff --git a/sound/soc/omap/omap-abe-twl6040.c b/sound/soc/omap/omap-abe-twl6040.c
index a57a4e6..e7d93fa 100644
--- a/sound/soc/omap/omap-abe-twl6040.c
+++ b/sound/soc/omap/omap-abe-twl6040.c
@@ -273,7 +273,7 @@
 	.num_dapm_routes = ARRAY_SIZE(audio_map),
 };
 
-static __devinit int omap_abe_probe(struct platform_device *pdev)
+static int omap_abe_probe(struct platform_device *pdev)
 {
 	struct omap_abe_twl6040_data *pdata = dev_get_platdata(&pdev->dev);
 	struct device_node *node = pdev->dev.of_node;
@@ -331,8 +331,8 @@
 			num_links = 1;
 		}
 
-		of_property_read_u32(node, "ti,jack-detection",
-				     &priv->jack_detection);
+		priv->jack_detection = of_property_read_bool(node,
+							   "ti,jack-detection");
 		of_property_read_u32(node, "ti,mclk-freq",
 				     &priv->mclk_freq);
 		if (!priv->mclk_freq) {
@@ -390,7 +390,7 @@
 	return ret;
 }
 
-static int __devexit omap_abe_remove(struct platform_device *pdev)
+static int omap_abe_remove(struct platform_device *pdev)
 {
 	struct snd_soc_card *card = platform_get_drvdata(pdev);
 	struct abe_twl6040 *priv = snd_soc_card_get_drvdata(card);
@@ -417,7 +417,7 @@
 		.of_match_table = omap_abe_of_match,
 	},
 	.probe = omap_abe_probe,
-	.remove = __devexit_p(omap_abe_remove),
+	.remove = omap_abe_remove,
 };
 
 module_platform_driver(omap_abe_driver);
diff --git a/sound/soc/omap/omap-dmic.c b/sound/soc/omap/omap-dmic.c
index 5a6aeaf..ba49ccd 100644
--- a/sound/soc/omap/omap-dmic.c
+++ b/sound/soc/omap/omap-dmic.c
@@ -448,7 +448,7 @@
 	.ops = &omap_dmic_dai_ops,
 };
 
-static __devinit int asoc_dmic_probe(struct platform_device *pdev)
+static int asoc_dmic_probe(struct platform_device *pdev)
 {
 	struct omap_dmic *dmic;
 	struct resource *res;
@@ -518,7 +518,7 @@
 	return ret;
 }
 
-static int __devexit asoc_dmic_remove(struct platform_device *pdev)
+static int asoc_dmic_remove(struct platform_device *pdev)
 {
 	struct omap_dmic *dmic = platform_get_drvdata(pdev);
 
@@ -541,7 +541,7 @@
 		.of_match_table = omap_dmic_of_match,
 	},
 	.probe = asoc_dmic_probe,
-	.remove = __devexit_p(asoc_dmic_remove),
+	.remove = asoc_dmic_remove,
 };
 
 module_platform_driver(asoc_dmic_driver);
diff --git a/sound/soc/omap/omap-hdmi-card.c b/sound/soc/omap/omap-hdmi-card.c
index eaa2ea0..d4eaa92 100644
--- a/sound/soc/omap/omap-hdmi-card.c
+++ b/sound/soc/omap/omap-hdmi-card.c
@@ -45,7 +45,7 @@
 	.num_links = 1,
 };
 
-static __devinit int omap_hdmi_probe(struct platform_device *pdev)
+static int omap_hdmi_probe(struct platform_device *pdev)
 {
 	struct snd_soc_card *card = &snd_soc_omap_hdmi;
 	int ret;
@@ -61,7 +61,7 @@
 	return 0;
 }
 
-static int __devexit omap_hdmi_remove(struct platform_device *pdev)
+static int omap_hdmi_remove(struct platform_device *pdev)
 {
 	struct snd_soc_card *card = platform_get_drvdata(pdev);
 
@@ -76,7 +76,7 @@
 		.owner = THIS_MODULE,
 	},
 	.probe = omap_hdmi_probe,
-	.remove = __devexit_p(omap_hdmi_remove),
+	.remove = omap_hdmi_remove,
 };
 
 module_platform_driver(omap_hdmi_driver);
diff --git a/sound/soc/omap/omap-hdmi.c b/sound/soc/omap/omap-hdmi.c
index f59c69f..7ea2481 100644
--- a/sound/soc/omap/omap-hdmi.c
+++ b/sound/soc/omap/omap-hdmi.c
@@ -262,7 +262,7 @@
 	.ops = &omap_hdmi_dai_ops,
 };
 
-static __devinit int omap_hdmi_probe(struct platform_device *pdev)
+static int omap_hdmi_probe(struct platform_device *pdev)
 {
 	int ret;
 	struct resource *hdmi_rsrc;
@@ -324,7 +324,7 @@
 	return ret;
 }
 
-static int __devexit omap_hdmi_remove(struct platform_device *pdev)
+static int omap_hdmi_remove(struct platform_device *pdev)
 {
 	struct hdmi_priv *hdmi_data = dev_get_drvdata(&pdev->dev);
 
@@ -345,7 +345,7 @@
 		.owner = THIS_MODULE,
 	},
 	.probe = omap_hdmi_probe,
-	.remove = __devexit_p(omap_hdmi_remove),
+	.remove = omap_hdmi_remove,
 };
 
 module_platform_driver(hdmi_dai_driver);
diff --git a/sound/soc/omap/omap-mcbsp.c b/sound/soc/omap/omap-mcbsp.c
index a6ee157..8d2defd 100644
--- a/sound/soc/omap/omap-mcbsp.c
+++ b/sound/soc/omap/omap-mcbsp.c
@@ -34,7 +34,6 @@
 #include <sound/initval.h>
 #include <sound/soc.h>
 
-#include <plat/cpu.h>
 #include <linux/platform_data/asoc-ti-mcbsp.h>
 #include "mcbsp.h"
 #include "omap-mcbsp.h"
@@ -512,7 +511,7 @@
 		regs->srgr2	|= CLKSM;
 		break;
 	case OMAP_MCBSP_SYSCLK_CLKS_FCLK:
-		if (cpu_class_is_omap1()) {
+		if (mcbsp_omap1()) {
 			err = -EINVAL;
 			break;
 		}
@@ -520,7 +519,7 @@
 					       MCBSP_CLKS_PRCM_SRC);
 		break;
 	case OMAP_MCBSP_SYSCLK_CLKS_EXT:
-		if (cpu_class_is_omap1()) {
+		if (mcbsp_omap1()) {
 			err = 0;
 			break;
 		}
@@ -758,7 +757,7 @@
 };
 MODULE_DEVICE_TABLE(of, omap_mcbsp_of_match);
 
-static __devinit int asoc_mcbsp_probe(struct platform_device *pdev)
+static int asoc_mcbsp_probe(struct platform_device *pdev)
 {
 	struct omap_mcbsp_platform_data *pdata = dev_get_platdata(&pdev->dev);
 	struct omap_mcbsp *mcbsp;
@@ -799,7 +798,7 @@
 	return ret;
 }
 
-static int __devexit asoc_mcbsp_remove(struct platform_device *pdev)
+static int asoc_mcbsp_remove(struct platform_device *pdev)
 {
 	struct omap_mcbsp *mcbsp = platform_get_drvdata(pdev);
 
@@ -825,7 +824,7 @@
 	},
 
 	.probe = asoc_mcbsp_probe,
-	.remove = __devexit_p(asoc_mcbsp_remove),
+	.remove = asoc_mcbsp_remove,
 };
 
 module_platform_driver(asoc_mcbsp_driver);
diff --git a/sound/soc/omap/omap-mcpdm.c b/sound/soc/omap/omap-mcpdm.c
index 56965bb..2fe8be2 100644
--- a/sound/soc/omap/omap-mcpdm.c
+++ b/sound/soc/omap/omap-mcpdm.c
@@ -429,7 +429,7 @@
 }
 EXPORT_SYMBOL_GPL(omap_mcpdm_configure_dn_offsets);
 
-static __devinit int asoc_mcpdm_probe(struct platform_device *pdev)
+static int asoc_mcpdm_probe(struct platform_device *pdev)
 {
 	struct omap_mcpdm *mcpdm;
 	struct resource *res;
@@ -487,7 +487,7 @@
 	return snd_soc_register_dai(&pdev->dev, &omap_mcpdm_dai);
 }
 
-static int __devexit asoc_mcpdm_remove(struct platform_device *pdev)
+static int asoc_mcpdm_remove(struct platform_device *pdev)
 {
 	snd_soc_unregister_dai(&pdev->dev);
 	return 0;
@@ -507,7 +507,7 @@
 	},
 
 	.probe	= asoc_mcpdm_probe,
-	.remove	= __devexit_p(asoc_mcpdm_remove),
+	.remove	= asoc_mcpdm_remove,
 };
 
 module_platform_driver(asoc_mcpdm_driver);
diff --git a/sound/soc/omap/omap-pcm.c b/sound/soc/omap/omap-pcm.c
index 52977aa..47bdbd4 100644
--- a/sound/soc/omap/omap-pcm.c
+++ b/sound/soc/omap/omap-pcm.c
@@ -302,13 +302,13 @@
 	.pcm_free	= omap_pcm_free_dma_buffers,
 };
 
-static __devinit int omap_pcm_probe(struct platform_device *pdev)
+static int omap_pcm_probe(struct platform_device *pdev)
 {
 	return snd_soc_register_platform(&pdev->dev,
 			&omap_soc_platform);
 }
 
-static int __devexit omap_pcm_remove(struct platform_device *pdev)
+static int omap_pcm_remove(struct platform_device *pdev)
 {
 	snd_soc_unregister_platform(&pdev->dev);
 	return 0;
@@ -321,7 +321,7 @@
 	},
 
 	.probe = omap_pcm_probe,
-	.remove = __devexit_p(omap_pcm_remove),
+	.remove = omap_pcm_remove,
 };
 
 module_platform_driver(omap_pcm_driver);
diff --git a/sound/soc/omap/omap-twl4030.c b/sound/soc/omap/omap-twl4030.c
index 3b97b879..4541d28 100644
--- a/sound/soc/omap/omap-twl4030.c
+++ b/sound/soc/omap/omap-twl4030.c
@@ -107,7 +107,7 @@
 	.num_links = ARRAY_SIZE(omap_twl4030_dai_links),
 };
 
-static __devinit int omap_twl4030_probe(struct platform_device *pdev)
+static int omap_twl4030_probe(struct platform_device *pdev)
 {
 	struct omap_tw4030_pdata *pdata = dev_get_platdata(&pdev->dev);
 	struct device_node *node = pdev->dev.of_node;
@@ -154,7 +154,7 @@
 	return 0;
 }
 
-static int __devexit omap_twl4030_remove(struct platform_device *pdev)
+static int omap_twl4030_remove(struct platform_device *pdev)
 {
 	struct snd_soc_card *card = platform_get_drvdata(pdev);
 
@@ -177,7 +177,7 @@
 		.of_match_table = omap_twl4030_of_match,
 	},
 	.probe = omap_twl4030_probe,
-	.remove = __devexit_p(omap_twl4030_remove),
+	.remove = omap_twl4030_remove,
 };
 
 module_platform_driver(omap_twl4030_driver);
diff --git a/sound/soc/omap/zoom2.c b/sound/soc/omap/zoom2.c
index 1ff6bb9..771bff2 100644
--- a/sound/soc/omap/zoom2.c
+++ b/sound/soc/omap/zoom2.c
@@ -37,8 +37,6 @@
 #include "omap-mcbsp.h"
 #include "omap-pcm.h"
 
-#define ZOOM2_HEADSET_MUX_GPIO		(OMAP_MAX_GPIO_LINES + 15)
-
 static int zoom2_hw_params(struct snd_pcm_substream *substream,
 				struct snd_pcm_hw_params *params)
 {
@@ -187,9 +185,6 @@
 	if (ret)
 		goto err1;
 
-	BUG_ON(gpio_request(ZOOM2_HEADSET_MUX_GPIO, "hs_mux") < 0);
-	gpio_direction_output(ZOOM2_HEADSET_MUX_GPIO, 0);
-
 	return 0;
 
 err1:
@@ -202,8 +197,6 @@
 
 static void __exit zoom2_soc_exit(void)
 {
-	gpio_free(ZOOM2_HEADSET_MUX_GPIO);
-
 	platform_device_unregister(zoom2_snd_device);
 }
 module_exit(zoom2_soc_exit);
diff --git a/sound/soc/pxa/brownstone.c b/sound/soc/pxa/brownstone.c
index 5e666e0..4ad7609 100644
--- a/sound/soc/pxa/brownstone.c
+++ b/sound/soc/pxa/brownstone.c
@@ -140,7 +140,7 @@
 	.num_dapm_routes = ARRAY_SIZE(brownstone_audio_map),
 };
 
-static int __devinit brownstone_probe(struct platform_device *pdev)
+static int brownstone_probe(struct platform_device *pdev)
 {
 	int ret;
 
@@ -152,7 +152,7 @@
 	return ret;
 }
 
-static int __devexit brownstone_remove(struct platform_device *pdev)
+static int brownstone_remove(struct platform_device *pdev)
 {
 	snd_soc_unregister_card(&brownstone);
 	return 0;
@@ -164,7 +164,7 @@
 		.owner	= THIS_MODULE,
 	},
 	.probe		= brownstone_probe,
-	.remove		= __devexit_p(brownstone_remove),
+	.remove		= brownstone_remove,
 };
 
 module_platform_driver(mmp_driver);
diff --git a/sound/soc/pxa/corgi.c b/sound/soc/pxa/corgi.c
index 863367a..f4cce1e 100644
--- a/sound/soc/pxa/corgi.c
+++ b/sound/soc/pxa/corgi.c
@@ -303,7 +303,7 @@
 	.num_dapm_routes = ARRAY_SIZE(corgi_audio_map),
 };
 
-static int __devinit corgi_probe(struct platform_device *pdev)
+static int corgi_probe(struct platform_device *pdev)
 {
 	struct snd_soc_card *card = &corgi;
 	int ret;
@@ -317,7 +317,7 @@
 	return ret;
 }
 
-static int __devexit corgi_remove(struct platform_device *pdev)
+static int corgi_remove(struct platform_device *pdev)
 {
 	struct snd_soc_card *card = platform_get_drvdata(pdev);
 
@@ -331,7 +331,7 @@
 		.owner	= THIS_MODULE,
 	},
 	.probe		= corgi_probe,
-	.remove		= __devexit_p(corgi_remove),
+	.remove		= corgi_remove,
 };
 
 module_platform_driver(corgi_driver);
diff --git a/sound/soc/pxa/e740_wm9705.c b/sound/soc/pxa/e740_wm9705.c
index 7b1bc23..70d799b 100644
--- a/sound/soc/pxa/e740_wm9705.c
+++ b/sound/soc/pxa/e740_wm9705.c
@@ -144,7 +144,7 @@
 	{ GPIO_E740_WM9705_nAVDD2, GPIOF_OUT_INIT_HIGH, "Audio power" },
 };
 
-static int __devinit e740_probe(struct platform_device *pdev)
+static int e740_probe(struct platform_device *pdev)
 {
 	struct snd_soc_card *card = &e740;
 	int ret;
@@ -165,7 +165,7 @@
 	return ret;
 }
 
-static int __devexit e740_remove(struct platform_device *pdev)
+static int e740_remove(struct platform_device *pdev)
 {
 	struct snd_soc_card *card = platform_get_drvdata(pdev);
 
@@ -180,7 +180,7 @@
 		.owner	= THIS_MODULE,
 	},
 	.probe		= e740_probe,
-	.remove		= __devexit_p(e740_remove),
+	.remove		= e740_remove,
 };
 
 module_platform_driver(e740_driver);
diff --git a/sound/soc/pxa/e750_wm9705.c b/sound/soc/pxa/e750_wm9705.c
index 47b89d7..f94d2ab 100644
--- a/sound/soc/pxa/e750_wm9705.c
+++ b/sound/soc/pxa/e750_wm9705.c
@@ -126,7 +126,7 @@
 	{ GPIO_E750_SPK_AMP_OFF, GPIOF_OUT_INIT_HIGH, "Speaker amp" },
 };
 
-static int __devinit e750_probe(struct platform_device *pdev)
+static int e750_probe(struct platform_device *pdev)
 {
 	struct snd_soc_card *card = &e750;
 	int ret;
@@ -147,7 +147,7 @@
 	return ret;
 }
 
-static int __devexit e750_remove(struct platform_device *pdev)
+static int e750_remove(struct platform_device *pdev)
 {
 	struct snd_soc_card *card = platform_get_drvdata(pdev);
 
@@ -162,7 +162,7 @@
 		.owner	= THIS_MODULE,
 	},
 	.probe		= e750_probe,
-	.remove		= __devexit_p(e750_remove),
+	.remove		= e750_remove,
 };
 
 module_platform_driver(e750_driver);
diff --git a/sound/soc/pxa/e800_wm9712.c b/sound/soc/pxa/e800_wm9712.c
index ea9707e..8768a64 100644
--- a/sound/soc/pxa/e800_wm9712.c
+++ b/sound/soc/pxa/e800_wm9712.c
@@ -116,7 +116,7 @@
 	{ GPIO_E800_HP_AMP_OFF, GPIOF_OUT_INIT_HIGH, "Speaker amp" },
 };
 
-static int __devinit e800_probe(struct platform_device *pdev)
+static int e800_probe(struct platform_device *pdev)
 {
 	struct snd_soc_card *card = &e800;
 	int ret;
@@ -137,7 +137,7 @@
 	return ret;
 }
 
-static int __devexit e800_remove(struct platform_device *pdev)
+static int e800_remove(struct platform_device *pdev)
 {
 	struct snd_soc_card *card = platform_get_drvdata(pdev);
 
@@ -152,7 +152,7 @@
 		.owner	= THIS_MODULE,
 	},
 	.probe		= e800_probe,
-	.remove		= __devexit_p(e800_remove),
+	.remove		= e800_remove,
 };
 
 module_platform_driver(e800_driver);
diff --git a/sound/soc/pxa/hx4700.c b/sound/soc/pxa/hx4700.c
index 2a342c9..dcc9b04 100644
--- a/sound/soc/pxa/hx4700.c
+++ b/sound/soc/pxa/hx4700.c
@@ -183,7 +183,7 @@
 	{ GPIO92_HX4700_HP_DRIVER, GPIOF_OUT_INIT_LOW, "EP_POWER" },
 };
 
-static int __devinit hx4700_audio_probe(struct platform_device *pdev)
+static int hx4700_audio_probe(struct platform_device *pdev)
 {
 	int ret;
 
@@ -204,7 +204,7 @@
 	return ret;
 }
 
-static int __devexit hx4700_audio_remove(struct platform_device *pdev)
+static int hx4700_audio_remove(struct platform_device *pdev)
 {
 	snd_soc_jack_free_gpios(&hs_jack, 1, &hs_jack_gpio);
 	snd_soc_unregister_card(&snd_soc_card_hx4700);
@@ -223,7 +223,7 @@
 		.pm = &snd_soc_pm_ops,
 	},
 	.probe	= hx4700_audio_probe,
-	.remove	= __devexit_p(hx4700_audio_remove),
+	.remove	= hx4700_audio_remove,
 };
 
 module_platform_driver(hx4700_audio_driver);
diff --git a/sound/soc/pxa/imote2.c b/sound/soc/pxa/imote2.c
index b93dafd..eef1f7b 100644
--- a/sound/soc/pxa/imote2.c
+++ b/sound/soc/pxa/imote2.c
@@ -65,7 +65,7 @@
 	.num_links = 1,
 };
 
-static int __devinit imote2_probe(struct platform_device *pdev)
+static int imote2_probe(struct platform_device *pdev)
 {
 	struct snd_soc_card *card = &imote2;
 	int ret;
@@ -79,7 +79,7 @@
 	return ret;
 }
 
-static int __devexit imote2_remove(struct platform_device *pdev)
+static int imote2_remove(struct platform_device *pdev)
 {
 	struct snd_soc_card *card = platform_get_drvdata(pdev);
 
@@ -93,7 +93,7 @@
 		.owner	= THIS_MODULE,
 	},
 	.probe		= imote2_probe,
-	.remove		= __devexit_p(imote2_remove),
+	.remove		= imote2_remove,
 };
 
 module_platform_driver(imote2_driver);
diff --git a/sound/soc/pxa/mioa701_wm9713.c b/sound/soc/pxa/mioa701_wm9713.c
index 8687c1c..97b711e 100644
--- a/sound/soc/pxa/mioa701_wm9713.c
+++ b/sound/soc/pxa/mioa701_wm9713.c
@@ -186,7 +186,7 @@
 	.num_links = ARRAY_SIZE(mioa701_dai),
 };
 
-static int __devinit mioa701_wm9713_probe(struct platform_device *pdev)
+static int mioa701_wm9713_probe(struct platform_device *pdev)
 {
 	int rc;
 
@@ -202,7 +202,7 @@
 	return rc;
 }
 
-static int __devexit mioa701_wm9713_remove(struct platform_device *pdev)
+static int mioa701_wm9713_remove(struct platform_device *pdev)
 {
 	struct snd_soc_card *card = platform_get_drvdata(pdev);
 
@@ -212,7 +212,7 @@
 
 static struct platform_driver mioa701_wm9713_driver = {
 	.probe		= mioa701_wm9713_probe,
-	.remove		= __devexit_p(mioa701_wm9713_remove),
+	.remove		= mioa701_wm9713_remove,
 	.driver		= {
 		.name		= "mioa701-wm9713",
 		.owner		= THIS_MODULE,
diff --git a/sound/soc/pxa/mmp-pcm.c b/sound/soc/pxa/mmp-pcm.c
index e834faf..190eb0b 100644
--- a/sound/soc/pxa/mmp-pcm.c
+++ b/sound/soc/pxa/mmp-pcm.c
@@ -257,7 +257,7 @@
 	.pcm_free	= mmp_pcm_free_dma_buffers,
 };
 
-static __devinit int mmp_pcm_probe(struct platform_device *pdev)
+static int mmp_pcm_probe(struct platform_device *pdev)
 {
 	struct mmp_audio_platdata *pdata = pdev->dev.platform_data;
 
@@ -274,7 +274,7 @@
 	return snd_soc_register_platform(&pdev->dev, &mmp_soc_platform);
 }
 
-static int __devexit mmp_pcm_remove(struct platform_device *pdev)
+static int mmp_pcm_remove(struct platform_device *pdev)
 {
 	snd_soc_unregister_platform(&pdev->dev);
 	return 0;
@@ -287,7 +287,7 @@
 	},
 
 	.probe = mmp_pcm_probe,
-	.remove = __devexit_p(mmp_pcm_remove),
+	.remove = mmp_pcm_remove,
 };
 
 module_platform_driver(mmp_pcm_driver);
diff --git a/sound/soc/pxa/mmp-sspa.c b/sound/soc/pxa/mmp-sspa.c
index 4d6cb8a..41c3a09 100644
--- a/sound/soc/pxa/mmp-sspa.c
+++ b/sound/soc/pxa/mmp-sspa.c
@@ -405,7 +405,7 @@
 	.ops = &mmp_sspa_dai_ops,
 };
 
-static __devinit int asoc_mmp_sspa_probe(struct platform_device *pdev)
+static int asoc_mmp_sspa_probe(struct platform_device *pdev)
 {
 	struct sspa_priv *priv;
 	struct resource *res;
@@ -453,7 +453,7 @@
 	return snd_soc_register_dai(&pdev->dev, &mmp_sspa_dai);
 }
 
-static int __devexit asoc_mmp_sspa_remove(struct platform_device *pdev)
+static int asoc_mmp_sspa_remove(struct platform_device *pdev)
 {
 	struct sspa_priv *priv = platform_get_drvdata(pdev);
 
@@ -470,7 +470,7 @@
 		.owner = THIS_MODULE,
 	},
 	.probe = asoc_mmp_sspa_probe,
-	.remove = __devexit_p(asoc_mmp_sspa_remove),
+	.remove = asoc_mmp_sspa_remove,
 };
 
 module_platform_driver(asoc_mmp_sspa_driver);
diff --git a/sound/soc/pxa/palm27x.c b/sound/soc/pxa/palm27x.c
index aa3da91..2074e2d 100644
--- a/sound/soc/pxa/palm27x.c
+++ b/sound/soc/pxa/palm27x.c
@@ -187,7 +187,7 @@
 	return ret;
 }
 
-static int __devexit palm27x_asoc_remove(struct platform_device *pdev)
+static int palm27x_asoc_remove(struct platform_device *pdev)
 {
 	platform_device_unregister(palm27x_snd_device);
 	return 0;
@@ -195,7 +195,7 @@
 
 static struct platform_driver palm27x_wm9712_driver = {
 	.probe		= palm27x_asoc_probe,
-	.remove		= __devexit_p(palm27x_asoc_remove),
+	.remove		= palm27x_asoc_remove,
 	.driver		= {
 		.name		= "palm27x-asoc",
 		.owner		= THIS_MODULE,
diff --git a/sound/soc/pxa/poodle.c b/sound/soc/pxa/poodle.c
index d2cc8173..fafe463 100644
--- a/sound/soc/pxa/poodle.c
+++ b/sound/soc/pxa/poodle.c
@@ -269,7 +269,7 @@
 	.num_dapm_routes = ARRAY_SIZE(poodle_audio_map),
 };
 
-static int __devinit poodle_probe(struct platform_device *pdev)
+static int poodle_probe(struct platform_device *pdev)
 {
 	struct snd_soc_card *card = &poodle;
 	int ret;
@@ -291,7 +291,7 @@
 	return ret;
 }
 
-static int __devexit poodle_remove(struct platform_device *pdev)
+static int poodle_remove(struct platform_device *pdev)
 {
 	struct snd_soc_card *card = platform_get_drvdata(pdev);
 
@@ -305,7 +305,7 @@
 		.owner	= THIS_MODULE,
 	},
 	.probe		= poodle_probe,
-	.remove		= __devexit_p(poodle_remove),
+	.remove		= poodle_remove,
 };
 
 module_platform_driver(poodle_driver);
diff --git a/sound/soc/pxa/pxa-ssp.c b/sound/soc/pxa/pxa-ssp.c
index 4da5fc5..d3eb0c2 100644
--- a/sound/soc/pxa/pxa-ssp.c
+++ b/sound/soc/pxa/pxa-ssp.c
@@ -794,12 +794,12 @@
 		.ops = &pxa_ssp_dai_ops,
 };
 
-static __devinit int asoc_ssp_probe(struct platform_device *pdev)
+static int asoc_ssp_probe(struct platform_device *pdev)
 {
 	return snd_soc_register_dai(&pdev->dev, &pxa_ssp_dai);
 }
 
-static int __devexit asoc_ssp_remove(struct platform_device *pdev)
+static int asoc_ssp_remove(struct platform_device *pdev)
 {
 	snd_soc_unregister_dai(&pdev->dev);
 	return 0;
@@ -812,7 +812,7 @@
 	},
 
 	.probe = asoc_ssp_probe,
-	.remove = __devexit_p(asoc_ssp_remove),
+	.remove = asoc_ssp_remove,
 };
 
 module_platform_driver(asoc_ssp_driver);
diff --git a/sound/soc/pxa/pxa2xx-ac97.c b/sound/soc/pxa/pxa2xx-ac97.c
index 06ea274..4b0a009 100644
--- a/sound/soc/pxa/pxa2xx-ac97.c
+++ b/sound/soc/pxa/pxa2xx-ac97.c
@@ -104,7 +104,7 @@
 #define pxa2xx_ac97_resume	NULL
 #endif
 
-static int __devinit pxa2xx_ac97_probe(struct snd_soc_dai *dai)
+static int pxa2xx_ac97_probe(struct snd_soc_dai *dai)
 {
 	return pxa2xx_ac97_hw_probe(to_platform_device(dai->dev));
 }
@@ -234,7 +234,7 @@
 
 EXPORT_SYMBOL_GPL(soc_ac97_ops);
 
-static __devinit int pxa2xx_ac97_dev_probe(struct platform_device *pdev)
+static int pxa2xx_ac97_dev_probe(struct platform_device *pdev)
 {
 	if (pdev->id != -1) {
 		dev_err(&pdev->dev, "PXA2xx has only one AC97 port.\n");
@@ -249,7 +249,7 @@
 			ARRAY_SIZE(pxa_ac97_dai_driver));
 }
 
-static int __devexit pxa2xx_ac97_dev_remove(struct platform_device *pdev)
+static int pxa2xx_ac97_dev_remove(struct platform_device *pdev)
 {
 	snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(pxa_ac97_dai_driver));
 	return 0;
@@ -257,7 +257,7 @@
 
 static struct platform_driver pxa2xx_ac97_driver = {
 	.probe		= pxa2xx_ac97_dev_probe,
-	.remove		= __devexit_p(pxa2xx_ac97_dev_remove),
+	.remove		= pxa2xx_ac97_dev_remove,
 	.driver		= {
 		.name	= "pxa2xx-ac97",
 		.owner	= THIS_MODULE,
diff --git a/sound/soc/pxa/pxa2xx-i2s.c b/sound/soc/pxa/pxa2xx-i2s.c
index 3075a42..6b1a06f 100644
--- a/sound/soc/pxa/pxa2xx-i2s.c
+++ b/sound/soc/pxa/pxa2xx-i2s.c
@@ -365,7 +365,7 @@
 	return snd_soc_register_dai(&pdev->dev, &pxa_i2s_dai);
 }
 
-static int __devexit pxa2xx_i2s_drv_remove(struct platform_device *pdev)
+static int pxa2xx_i2s_drv_remove(struct platform_device *pdev)
 {
 	snd_soc_unregister_dai(&pdev->dev);
 	return 0;
@@ -373,7 +373,7 @@
 
 static struct platform_driver pxa2xx_i2s_driver = {
 	.probe = pxa2xx_i2s_drv_probe,
-	.remove = __devexit_p(pxa2xx_i2s_drv_remove),
+	.remove = pxa2xx_i2s_drv_remove,
 
 	.driver = {
 		.name = "pxa2xx-i2s",
diff --git a/sound/soc/pxa/pxa2xx-pcm.c b/sound/soc/pxa/pxa2xx-pcm.c
index fdd6bed..ecff116 100644
--- a/sound/soc/pxa/pxa2xx-pcm.c
+++ b/sound/soc/pxa/pxa2xx-pcm.c
@@ -120,12 +120,12 @@
 	.pcm_free	= pxa2xx_pcm_free_dma_buffers,
 };
 
-static int __devinit pxa2xx_soc_platform_probe(struct platform_device *pdev)
+static int pxa2xx_soc_platform_probe(struct platform_device *pdev)
 {
 	return snd_soc_register_platform(&pdev->dev, &pxa2xx_soc_platform);
 }
 
-static int __devexit pxa2xx_soc_platform_remove(struct platform_device *pdev)
+static int pxa2xx_soc_platform_remove(struct platform_device *pdev)
 {
 	snd_soc_unregister_platform(&pdev->dev);
 	return 0;
@@ -138,7 +138,7 @@
 	},
 
 	.probe = pxa2xx_soc_platform_probe,
-	.remove = __devexit_p(pxa2xx_soc_platform_remove),
+	.remove = pxa2xx_soc_platform_remove,
 };
 
 module_platform_driver(pxa_pcm_driver);
diff --git a/sound/soc/pxa/tosa.c b/sound/soc/pxa/tosa.c
index 2aec63f..a3fe191 100644
--- a/sound/soc/pxa/tosa.c
+++ b/sound/soc/pxa/tosa.c
@@ -241,7 +241,7 @@
 	.num_links = ARRAY_SIZE(tosa_dai),
 };
 
-static int __devinit tosa_probe(struct platform_device *pdev)
+static int tosa_probe(struct platform_device *pdev)
 {
 	struct snd_soc_card *card = &tosa;
 	int ret;
@@ -262,7 +262,7 @@
 	return ret;
 }
 
-static int __devexit tosa_remove(struct platform_device *pdev)
+static int tosa_remove(struct platform_device *pdev)
 {
 	struct snd_soc_card *card = platform_get_drvdata(pdev);
 
@@ -277,7 +277,7 @@
 		.owner	= THIS_MODULE,
 	},
 	.probe		= tosa_probe,
-	.remove		= __devexit_p(tosa_remove),
+	.remove		= tosa_remove,
 };
 
 module_platform_driver(tosa_driver);
diff --git a/sound/soc/pxa/ttc-dkb.c b/sound/soc/pxa/ttc-dkb.c
index 935491a..f4ea4f6 100644
--- a/sound/soc/pxa/ttc-dkb.c
+++ b/sound/soc/pxa/ttc-dkb.c
@@ -131,7 +131,7 @@
 	.num_dapm_routes = ARRAY_SIZE(ttc_audio_map),
 };
 
-static int __devinit ttc_dkb_probe(struct platform_device *pdev)
+static int ttc_dkb_probe(struct platform_device *pdev)
 {
 	struct snd_soc_card *card = &ttc_dkb_card;
 	int ret;
@@ -146,7 +146,7 @@
 	return ret;
 }
 
-static int __devexit ttc_dkb_remove(struct platform_device *pdev)
+static int ttc_dkb_remove(struct platform_device *pdev)
 {
 	struct snd_soc_card *card = platform_get_drvdata(pdev);
 
@@ -161,7 +161,7 @@
 		.owner	= THIS_MODULE,
 	},
 	.probe		= ttc_dkb_probe,
-	.remove		= __devexit_p(ttc_dkb_remove),
+	.remove		= ttc_dkb_remove,
 };
 
 module_platform_driver(ttc_dkb_driver);
diff --git a/sound/soc/s6000/s6000-i2s.c b/sound/soc/s6000/s6000-i2s.c
index aaabdba..fee4d47 100644
--- a/sound/soc/s6000/s6000-i2s.c
+++ b/sound/soc/s6000/s6000-i2s.c
@@ -436,7 +436,7 @@
 	.ops = &s6000_i2s_dai_ops,
 };
 
-static int __devinit s6000_i2s_probe(struct platform_device *pdev)
+static int s6000_i2s_probe(struct platform_device *pdev)
 {
 	struct s6000_i2s_dev *dev;
 	struct resource *scbmem, *sifmem, *region, *dma1, *dma2;
@@ -566,7 +566,7 @@
 	return ret;
 }
 
-static void __devexit s6000_i2s_remove(struct platform_device *pdev)
+static void s6000_i2s_remove(struct platform_device *pdev)
 {
 	struct s6000_i2s_dev *dev = dev_get_drvdata(&pdev->dev);
 	struct resource *region;
@@ -597,7 +597,7 @@
 
 static struct platform_driver s6000_i2s_driver = {
 	.probe  = s6000_i2s_probe,
-	.remove = __devexit_p(s6000_i2s_remove),
+	.remove = s6000_i2s_remove,
 	.driver = {
 		.name   = "s6000-i2s",
 		.owner  = THIS_MODULE,
diff --git a/sound/soc/s6000/s6000-pcm.c b/sound/soc/s6000/s6000-pcm.c
index 716da86..1358c7d 100644
--- a/sound/soc/s6000/s6000-pcm.c
+++ b/sound/soc/s6000/s6000-pcm.c
@@ -500,12 +500,12 @@
 	.pcm_free = 	s6000_pcm_free,
 };
 
-static int __devinit s6000_soc_platform_probe(struct platform_device *pdev)
+static int s6000_soc_platform_probe(struct platform_device *pdev)
 {
 	return snd_soc_register_platform(&pdev->dev, &s6000_soc_platform);
 }
 
-static int __devexit s6000_soc_platform_remove(struct platform_device *pdev)
+static int s6000_soc_platform_remove(struct platform_device *pdev)
 {
 	snd_soc_unregister_platform(&pdev->dev);
 	return 0;
@@ -518,7 +518,7 @@
 	},
 
 	.probe = s6000_soc_platform_probe,
-	.remove = __devexit_p(s6000_soc_platform_remove),
+	.remove = s6000_soc_platform_remove,
 };
 
 module_platform_driver(s6000_pcm_driver);
diff --git a/sound/soc/samsung/ac97.c b/sound/soc/samsung/ac97.c
index 14fbcd3..0df3c56 100644
--- a/sound/soc/samsung/ac97.c
+++ b/sound/soc/samsung/ac97.c
@@ -370,7 +370,7 @@
 	},
 };
 
-static __devinit int s3c_ac97_probe(struct platform_device *pdev)
+static int s3c_ac97_probe(struct platform_device *pdev)
 {
 	struct resource *mem_res, *dmatx_res, *dmarx_res, *dmamic_res, *irq_res;
 	struct s3c_audio_pdata *ac97_pdata;
@@ -442,7 +442,7 @@
 		ret = -ENODEV;
 		goto err2;
 	}
-	clk_enable(s3c_ac97.ac97_clk);
+	clk_prepare_enable(s3c_ac97.ac97_clk);
 
 	if (ac97_pdata->cfg_gpio(pdev)) {
 		dev_err(&pdev->dev, "Unable to configure gpio\n");
@@ -462,13 +462,20 @@
 	if (ret)
 		goto err5;
 
-	return 0;
+	ret = asoc_dma_platform_register(&pdev->dev);
+	if (ret) {
+		dev_err(&pdev->dev, "failed to get register DMA: %d\n", ret);
+		goto err6;
+	}
 
+	return 0;
+err6:
+	snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(s3c_ac97_dai));
 err5:
 	free_irq(irq_res->start, NULL);
 err4:
 err3:
-	clk_disable(s3c_ac97.ac97_clk);
+	clk_disable_unprepare(s3c_ac97.ac97_clk);
 	clk_put(s3c_ac97.ac97_clk);
 err2:
 	iounmap(s3c_ac97.regs);
@@ -478,17 +485,18 @@
 	return ret;
 }
 
-static __devexit int s3c_ac97_remove(struct platform_device *pdev)
+static int s3c_ac97_remove(struct platform_device *pdev)
 {
 	struct resource *mem_res, *irq_res;
 
+	asoc_dma_platform_unregister(&pdev->dev);
 	snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(s3c_ac97_dai));
 
 	irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
 	if (irq_res)
 		free_irq(irq_res->start, NULL);
 
-	clk_disable(s3c_ac97.ac97_clk);
+	clk_disable_unprepare(s3c_ac97.ac97_clk);
 	clk_put(s3c_ac97.ac97_clk);
 
 	iounmap(s3c_ac97.regs);
@@ -502,7 +510,7 @@
 
 static struct platform_driver s3c_ac97_driver = {
 	.probe  = s3c_ac97_probe,
-	.remove = __devexit_p(s3c_ac97_remove),
+	.remove = s3c_ac97_remove,
 	.driver = {
 		.name = "samsung-ac97",
 		.owner = THIS_MODULE,
diff --git a/sound/soc/samsung/bells.c b/sound/soc/samsung/bells.c
index a2ca156..ceed466 100644
--- a/sound/soc/samsung/bells.c
+++ b/sound/soc/samsung/bells.c
@@ -18,15 +18,6 @@
 #include "../codecs/wm5102.h"
 #include "../codecs/wm9081.h"
 
-/*
- * 44.1kHz based clocks for the SYSCLK domain, use a very high clock
- * to allow all the DSP functionality to be enabled if desired.
- */
-#define SYSCLK_RATE (44100 * 1024)
-
-/* 48kHz based clocks for the ASYNC domain */
-#define ASYNCCLK_RATE (48000 * 512)
-
 /* BCLK2 is fixed at this currently */
 #define BCLK2_RATE (64 * 8000)
 
@@ -36,15 +27,40 @@
  */
 #define MCLK_RATE 24576000
 
-#define WM9081_AUDIO_RATE 44100
-#define WM9081_MCLK_RATE  (WM9081_AUDIO_RATE * 256)
+#define SYS_AUDIO_RATE 44100
+#define SYS_MCLK_RATE  (SYS_AUDIO_RATE * 512)
+
+#define DAI_AP_DSP    0
+#define DAI_DSP_CODEC 1
+#define DAI_CODEC_CP  2
+#define DAI_CODEC_SUB 3
+
+struct bells_drvdata {
+	int sysclk_rate;
+	int asyncclk_rate;
+};
+
+static struct bells_drvdata wm2200_drvdata = {
+	.sysclk_rate = 22579200,
+};
+
+static struct bells_drvdata wm5102_drvdata = {
+	.sysclk_rate = 45158400,
+	.asyncclk_rate = 49152000,
+};
+
+static struct bells_drvdata wm5110_drvdata = {
+	.sysclk_rate = 135475200,
+	.asyncclk_rate = 147456000,
+};
 
 static int bells_set_bias_level(struct snd_soc_card *card,
 				struct snd_soc_dapm_context *dapm,
 				enum snd_soc_bias_level level)
 {
-	struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai;
+	struct snd_soc_dai *codec_dai = card->rtd[DAI_DSP_CODEC].codec_dai;
 	struct snd_soc_codec *codec = codec_dai->codec;
+	struct bells_drvdata *bells = card->drvdata;
 	int ret;
 
 	if (dapm->dev != codec_dai->dev)
@@ -52,18 +68,21 @@
 
 	switch (level) {
 	case SND_SOC_BIAS_PREPARE:
-		if (dapm->bias_level == SND_SOC_BIAS_STANDBY) {
-			ret = snd_soc_codec_set_pll(codec, WM5102_FLL1,
-						    ARIZONA_FLL_SRC_MCLK1,
-						    MCLK_RATE,
-						    SYSCLK_RATE);
-			if (ret < 0)
-				pr_err("Failed to start FLL: %d\n", ret);
+		if (dapm->bias_level != SND_SOC_BIAS_STANDBY)
+			break;
 
+		ret = snd_soc_codec_set_pll(codec, WM5102_FLL1,
+					    ARIZONA_FLL_SRC_MCLK1,
+					    MCLK_RATE,
+					    bells->sysclk_rate);
+		if (ret < 0)
+			pr_err("Failed to start FLL: %d\n", ret);
+
+		if (bells->asyncclk_rate) {
 			ret = snd_soc_codec_set_pll(codec, WM5102_FLL2,
 						    ARIZONA_FLL_SRC_AIF2BCLK,
 						    BCLK2_RATE,
-						    ASYNCCLK_RATE);
+						    bells->asyncclk_rate);
 			if (ret < 0)
 				pr_err("Failed to start FLL: %d\n", ret);
 		}
@@ -80,8 +99,9 @@
 				     struct snd_soc_dapm_context *dapm,
 				     enum snd_soc_bias_level level)
 {
-	struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai;
+	struct snd_soc_dai *codec_dai = card->rtd[DAI_DSP_CODEC].codec_dai;
 	struct snd_soc_codec *codec = codec_dai->codec;
+	struct bells_drvdata *bells = card->drvdata;
 	int ret;
 
 	if (dapm->dev != codec_dai->dev)
@@ -95,10 +115,13 @@
 			return ret;
 		}
 
-		ret = snd_soc_codec_set_pll(codec, WM5102_FLL2, 0, 0, 0);
-		if (ret < 0) {
-			pr_err("Failed to stop FLL: %d\n", ret);
-			return ret;
+		if (bells->asyncclk_rate) {
+			ret = snd_soc_codec_set_pll(codec, WM5102_FLL2,
+						    0, 0, 0);
+			if (ret < 0) {
+				pr_err("Failed to stop FLL: %d\n", ret);
+				return ret;
+			}
 		}
 		break;
 
@@ -113,56 +136,73 @@
 
 static int bells_late_probe(struct snd_soc_card *card)
 {
-	struct snd_soc_codec *codec = card->rtd[0].codec;
-	struct snd_soc_dai *aif1_dai = card->rtd[0].codec_dai;
-	struct snd_soc_dai *aif2_dai = card->rtd[1].cpu_dai;
-	struct snd_soc_dai *aif3_dai = card->rtd[2].cpu_dai;
-	struct snd_soc_dai *wm9081_dai = card->rtd[2].codec_dai;
+	struct bells_drvdata *bells = card->drvdata;
+	struct snd_soc_codec *wm0010 = card->rtd[DAI_AP_DSP].codec;
+	struct snd_soc_codec *codec = card->rtd[DAI_DSP_CODEC].codec;
+	struct snd_soc_dai *aif1_dai = card->rtd[DAI_DSP_CODEC].codec_dai;
+	struct snd_soc_dai *aif2_dai;
+	struct snd_soc_dai *aif3_dai;
+	struct snd_soc_dai *wm9081_dai;
 	int ret;
 
-	ret = snd_soc_dai_set_sysclk(aif1_dai, ARIZONA_CLK_SYSCLK, 0, 0);
+	ret = snd_soc_codec_set_sysclk(codec, ARIZONA_CLK_SYSCLK,
+				       ARIZONA_CLK_SRC_FLL1,
+				       bells->sysclk_rate,
+				       SND_SOC_CLOCK_IN);
 	if (ret != 0) {
-		dev_err(aif1_dai->dev, "Failed to set AIF1 clock: %d\n", ret);
+		dev_err(codec->dev, "Failed to set SYSCLK: %d\n", ret);
 		return ret;
 	}
 
+	ret = snd_soc_codec_set_sysclk(wm0010, 0, 0, SYS_MCLK_RATE, 0);
+	if (ret != 0) {
+		dev_err(wm0010->dev, "Failed to set WM0010 clock: %d\n", ret);
+		return ret;
+	}
+
+	ret = snd_soc_dai_set_sysclk(aif1_dai, ARIZONA_CLK_SYSCLK, 0, 0);
+	if (ret != 0)
+		dev_err(aif1_dai->dev, "Failed to set AIF1 clock: %d\n", ret);
+
+	ret = snd_soc_codec_set_sysclk(codec, ARIZONA_CLK_OPCLK, 0,
+				       SYS_MCLK_RATE, SND_SOC_CLOCK_OUT);
+	if (ret != 0)
+		dev_err(codec->dev, "Failed to set OPCLK: %d\n", ret);
+
+	if (card->num_rtd == DAI_CODEC_CP)
+		return 0;
+
+	ret = snd_soc_codec_set_sysclk(codec, ARIZONA_CLK_ASYNCCLK,
+				       ARIZONA_CLK_SRC_FLL2,
+				       bells->asyncclk_rate,
+				       SND_SOC_CLOCK_IN);
+	if (ret != 0) {
+		dev_err(codec->dev, "Failed to set ASYNCCLK: %d\n", ret);
+		return ret;
+	}
+
+	aif2_dai = card->rtd[DAI_CODEC_CP].cpu_dai;
+
 	ret = snd_soc_dai_set_sysclk(aif2_dai, ARIZONA_CLK_ASYNCCLK, 0, 0);
 	if (ret != 0) {
 		dev_err(aif2_dai->dev, "Failed to set AIF2 clock: %d\n", ret);
 		return ret;
 	}
 
+	if (card->num_rtd == DAI_CODEC_SUB)
+		return 0;
+
+	aif3_dai = card->rtd[DAI_CODEC_SUB].cpu_dai;
+	wm9081_dai = card->rtd[DAI_CODEC_SUB].codec_dai;
+
 	ret = snd_soc_dai_set_sysclk(aif3_dai, ARIZONA_CLK_SYSCLK, 0, 0);
 	if (ret != 0) {
 		dev_err(aif1_dai->dev, "Failed to set AIF1 clock: %d\n", ret);
 		return ret;
 	}
 
-	ret = snd_soc_codec_set_sysclk(codec, ARIZONA_CLK_SYSCLK,
-				       ARIZONA_CLK_SRC_FLL1, SYSCLK_RATE,
-				       SND_SOC_CLOCK_IN);
-	if (ret != 0) {
-		dev_err(codec->dev, "Failed to set SYSCLK: %d\n", ret);
-		return ret;
-	}
-
-	ret = snd_soc_codec_set_sysclk(codec, ARIZONA_CLK_OPCLK, 0,
-				       WM9081_MCLK_RATE, SND_SOC_CLOCK_OUT);
-	if (ret != 0) {
-		dev_err(codec->dev, "Failed to set OPCLK: %d\n", ret);
-		return ret;
-	}
-
-	ret = snd_soc_codec_set_sysclk(codec, ARIZONA_CLK_ASYNCCLK,
-				       ARIZONA_CLK_SRC_FLL2, ASYNCCLK_RATE,
-				       SND_SOC_CLOCK_IN);
-	if (ret != 0) {
-		dev_err(codec->dev, "Failed to set SYSCLK: %d\n", ret);
-		return ret;
-	}
-
 	ret = snd_soc_codec_set_sysclk(wm9081_dai->codec, WM9081_SYSCLK_MCLK,
-				       0, WM9081_MCLK_RATE, 0);
+				       0, SYS_MCLK_RATE, 0);
 	if (ret != 0) {
 		dev_err(wm9081_dai->dev, "Failed to set MCLK: %d\n", ret);
 		return ret;
@@ -181,22 +221,57 @@
 
 static const struct snd_soc_pcm_stream sub_params = {
 	.formats = SNDRV_PCM_FMTBIT_S32_LE,
-	.rate_min = WM9081_AUDIO_RATE,
-	.rate_max = WM9081_AUDIO_RATE,
+	.rate_min = SYS_AUDIO_RATE,
+	.rate_max = SYS_AUDIO_RATE,
 	.channels_min = 2,
 	.channels_max = 2,
 };
 
+static struct snd_soc_dai_link bells_dai_wm2200[] = {
+	{
+		.name = "CPU-DSP",
+		.stream_name = "CPU-DSP",
+		.cpu_dai_name = "samsung-i2s.0",
+		.codec_dai_name = "wm0010-sdi1",
+		.platform_name = "samsung-i2s.0",
+		.codec_name = "spi0.0",
+		.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
+				| SND_SOC_DAIFMT_CBM_CFM,
+	},
+	{
+		.name = "DSP-CODEC",
+		.stream_name = "DSP-CODEC",
+		.cpu_dai_name = "wm0010-sdi2",
+		.codec_dai_name = "wm2200",
+		.codec_name = "wm2200.1-003a",
+		.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
+				| SND_SOC_DAIFMT_CBM_CFM,
+		.params = &sub_params,
+		.ignore_suspend = 1,
+	},
+};
+
 static struct snd_soc_dai_link bells_dai_wm5102[] = {
 	{
-		.name = "CPU",
-		.stream_name = "CPU",
+		.name = "CPU-DSP",
+		.stream_name = "CPU-DSP",
 		.cpu_dai_name = "samsung-i2s.0",
+		.codec_dai_name = "wm0010-sdi1",
+		.platform_name = "samsung-i2s.0",
+		.codec_name = "spi0.0",
+		.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
+				| SND_SOC_DAIFMT_CBM_CFM,
+	},
+	{
+		.name = "DSP-CODEC",
+		.stream_name = "DSP-CODEC",
+		.cpu_dai_name = "wm0010-sdi2",
 		.codec_dai_name = "wm5102-aif1",
-		.platform_name = "samsung-audio",
 		.codec_name = "wm5102-codec",
 		.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
 				| SND_SOC_DAIFMT_CBM_CFM,
+		.params = &sub_params,
+		.ignore_suspend = 1,
 	},
 	{
 		.name = "Baseband",
@@ -224,14 +299,25 @@
 
 static struct snd_soc_dai_link bells_dai_wm5110[] = {
 	{
-		.name = "CPU",
-		.stream_name = "CPU",
+		.name = "CPU-DSP",
+		.stream_name = "CPU-DSP",
 		.cpu_dai_name = "samsung-i2s.0",
+		.codec_dai_name = "wm0010-sdi1",
+		.platform_name = "samsung-i2s.0",
+		.codec_name = "spi0.0",
+		.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
+				| SND_SOC_DAIFMT_CBM_CFM,
+	},
+	{
+		.name = "DSP-CODEC",
+		.stream_name = "DSP-CODEC",
+		.cpu_dai_name = "wm0010-sdi2",
 		.codec_dai_name = "wm5110-aif1",
-		.platform_name = "samsung-audio",
 		.codec_name = "wm5110-codec",
 		.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
 				| SND_SOC_DAIFMT_CBM_CFM,
+		.params = &sub_params,
+		.ignore_suspend = 1,
 	},
 	{
 		.name = "Baseband",
@@ -270,6 +356,24 @@
 
 static struct snd_soc_card bells_cards[] = {
 	{
+		.name = "Bells WM2200",
+		.owner = THIS_MODULE,
+		.dai_link = bells_dai_wm2200,
+		.num_links = ARRAY_SIZE(bells_dai_wm2200),
+		.codec_conf = bells_codec_conf,
+		.num_configs = ARRAY_SIZE(bells_codec_conf),
+
+		.late_probe = bells_late_probe,
+
+		.dapm_routes = bells_routes,
+		.num_dapm_routes = ARRAY_SIZE(bells_routes),
+
+		.set_bias_level = bells_set_bias_level,
+		.set_bias_level_post = bells_set_bias_level_post,
+
+		.drvdata = &wm2200_drvdata,
+	},
+	{
 		.name = "Bells WM5102",
 		.owner = THIS_MODULE,
 		.dai_link = bells_dai_wm5102,
@@ -284,6 +388,8 @@
 
 		.set_bias_level = bells_set_bias_level,
 		.set_bias_level_post = bells_set_bias_level_post,
+
+		.drvdata = &wm5102_drvdata,
 	},
 	{
 		.name = "Bells WM5110",
@@ -300,11 +406,13 @@
 
 		.set_bias_level = bells_set_bias_level,
 		.set_bias_level_post = bells_set_bias_level_post,
+
+		.drvdata = &wm5110_drvdata,
 	},
 };
 
 
-static __devinit int bells_probe(struct platform_device *pdev)
+static int bells_probe(struct platform_device *pdev)
 {
 	int ret;
 
@@ -321,7 +429,7 @@
 	return 0;
 }
 
-static int __devexit bells_remove(struct platform_device *pdev)
+static int bells_remove(struct platform_device *pdev)
 {
 	snd_soc_unregister_card(&bells_cards[pdev->id]);
 
@@ -335,7 +443,7 @@
 		.pm = &snd_soc_pm_ops,
 	},
 	.probe = bells_probe,
-	.remove = __devexit_p(bells_remove),
+	.remove = bells_remove,
 };
 
 module_platform_driver(bells_driver);
diff --git a/sound/soc/samsung/dma.c b/sound/soc/samsung/dma.c
index b70964e..db87628 100644
--- a/sound/soc/samsung/dma.c
+++ b/sound/soc/samsung/dma.c
@@ -432,30 +432,18 @@
 	.pcm_free	= dma_free_dma_buffers,
 };
 
-static int __devinit samsung_asoc_platform_probe(struct platform_device *pdev)
+int asoc_dma_platform_register(struct device *dev)
 {
-	return snd_soc_register_platform(&pdev->dev, &samsung_asoc_platform);
+	return snd_soc_register_platform(dev, &samsung_asoc_platform);
 }
+EXPORT_SYMBOL_GPL(asoc_dma_platform_register);
 
-static int __devexit samsung_asoc_platform_remove(struct platform_device *pdev)
+void asoc_dma_platform_unregister(struct device *dev)
 {
-	snd_soc_unregister_platform(&pdev->dev);
-	return 0;
+	snd_soc_unregister_platform(dev);
 }
-
-static struct platform_driver asoc_dma_driver = {
-	.driver = {
-		.name = "samsung-audio",
-		.owner = THIS_MODULE,
-	},
-
-	.probe = samsung_asoc_platform_probe,
-	.remove = __devexit_p(samsung_asoc_platform_remove),
-};
-
-module_platform_driver(asoc_dma_driver);
+EXPORT_SYMBOL_GPL(asoc_dma_platform_unregister);
 
 MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>");
 MODULE_DESCRIPTION("Samsung ASoC DMA Driver");
 MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:samsung-audio");
diff --git a/sound/soc/samsung/dma.h b/sound/soc/samsung/dma.h
index 7d1ead7..73d8c7c 100644
--- a/sound/soc/samsung/dma.h
+++ b/sound/soc/samsung/dma.h
@@ -21,4 +21,7 @@
 	struct samsung_dma_ops *ops;
 };
 
+int asoc_dma_platform_register(struct device *dev);
+void asoc_dma_platform_unregister(struct device *dev);
+
 #endif
diff --git a/sound/soc/samsung/goni_wm8994.c b/sound/soc/samsung/goni_wm8994.c
index c23c2ae..d37ede5 100644
--- a/sound/soc/samsung/goni_wm8994.c
+++ b/sound/soc/samsung/goni_wm8994.c
@@ -228,7 +228,7 @@
 	.stream_name = "WM8994 HiFi",
 	.cpu_dai_name = "samsung-i2s.0",
 	.codec_dai_name = "wm8994-aif1",
-	.platform_name = "samsung-audio",
+	.platform_name = "samsung-i2s.0",
 	.codec_name = "wm8994-codec.0-001a",
 	.init = goni_wm8994_init,
 	.ops = &goni_hifi_ops,
diff --git a/sound/soc/samsung/h1940_uda1380.c b/sound/soc/samsung/h1940_uda1380.c
index 6e32577..3870e96 100644
--- a/sound/soc/samsung/h1940_uda1380.c
+++ b/sound/soc/samsung/h1940_uda1380.c
@@ -207,7 +207,7 @@
 		.cpu_dai_name	= "s3c24xx-iis",
 		.codec_dai_name	= "uda1380-hifi",
 		.init		= h1940_uda1380_init,
-		.platform_name	= "samsung-audio",
+		.platform_name	= "s3c24xx-iis",
 		.codec_name	= "uda1380-codec.0-001a",
 		.ops		= &h1940_ops,
 	},
diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c
index 40b00a1..d2d124f 100644
--- a/sound/soc/samsung/i2s.c
+++ b/sound/soc/samsung/i2s.c
@@ -49,8 +49,6 @@
 	struct clk *clk;
 	/* Clock for generating I2S signals */
 	struct clk *op_clk;
-	/* Array of clock names for op_clk */
-	const char **src_clk;
 	/* Pointer to the Primary_Fifo if this is Sec_Fifo, NULL otherwise */
 	struct i2s_dai *pri_dai;
 	/* Pointer to the Secondary_Fifo if it has one, NULL otherwise */
@@ -423,7 +421,7 @@
 			if (i2s->op_clk) {
 				if ((clk_id && !(mod & MOD_IMS_SYSMUX)) ||
 					(!clk_id && (mod & MOD_IMS_SYSMUX))) {
-					clk_disable(i2s->op_clk);
+					clk_disable_unprepare(i2s->op_clk);
 					clk_put(i2s->op_clk);
 				} else {
 					i2s->rclk_srcrate =
@@ -432,9 +430,13 @@
 				}
 			}
 
-			i2s->op_clk = clk_get(&i2s->pdev->dev,
-						i2s->src_clk[clk_id]);
-			clk_enable(i2s->op_clk);
+			if (clk_id)
+				i2s->op_clk = clk_get(&i2s->pdev->dev,
+						"i2s_opclk1");
+			else
+				i2s->op_clk = clk_get(&i2s->pdev->dev,
+						"i2s_opclk0");
+			clk_prepare_enable(i2s->op_clk);
 			i2s->rclk_srcrate = clk_get_rate(i2s->op_clk);
 
 			/* Over-ride the other's */
@@ -880,7 +882,7 @@
 		iounmap(i2s->addr);
 		return -ENOENT;
 	}
-	clk_enable(i2s->clk);
+	clk_prepare_enable(i2s->clk);
 
 	if (other) {
 		other->addr = i2s->addr;
@@ -922,7 +924,7 @@
 		if (i2s->quirks & QUIRK_NEED_RSTCLR)
 			writel(0, i2s->addr + I2SCON);
 
-		clk_disable(i2s->clk);
+		clk_disable_unprepare(i2s->clk);
 		clk_put(i2s->clk);
 
 		iounmap(i2s->addr);
@@ -950,8 +952,7 @@
 					SNDRV_PCM_FMTBIT_S16_LE | \
 					SNDRV_PCM_FMTBIT_S24_LE)
 
-static __devinit
-struct i2s_dai *i2s_alloc_dai(struct platform_device *pdev, bool sec)
+static struct i2s_dai *i2s_alloc_dai(struct platform_device *pdev, bool sec)
 {
 	struct i2s_dai *i2s;
 
@@ -992,7 +993,7 @@
 	return i2s;
 }
 
-static __devinit int samsung_i2s_probe(struct platform_device *pdev)
+static int samsung_i2s_probe(struct platform_device *pdev)
 {
 	u32 dma_pl_chan, dma_cp_chan, dma_pl_sec_chan;
 	struct i2s_dai *pri_dai, *sec_dai = NULL;
@@ -1007,6 +1008,7 @@
 		sec_dai = dev_get_drvdata(&pdev->dev);
 		snd_soc_register_dai(&sec_dai->pdev->dev,
 			&sec_dai->i2s_dai_drv);
+		asoc_dma_platform_register(&pdev->dev);
 		return 0;
 	}
 
@@ -1067,7 +1069,6 @@
 		(struct s3c2410_dma_client *)&pri_dai->dma_capture;
 	pri_dai->dma_playback.channel = dma_pl_chan;
 	pri_dai->dma_capture.channel = dma_cp_chan;
-	pri_dai->src_clk = i2s_cfg->src_clk;
 	pri_dai->dma_playback.dma_size = 4;
 	pri_dai->dma_capture.dma_size = 4;
 	pri_dai->base = regs_base;
@@ -1088,7 +1089,6 @@
 			(struct s3c2410_dma_client *)&sec_dai->dma_playback;
 		/* Use iDMA always if SysDMA not provided */
 		sec_dai->dma_playback.channel = dma_pl_sec_chan ? : -1;
-		sec_dai->src_clk = i2s_cfg->src_clk;
 		sec_dai->dma_playback.dma_size = 4;
 		sec_dai->base = regs_base;
 		sec_dai->quirks = quirks;
@@ -1107,6 +1107,8 @@
 
 	pm_runtime_enable(&pdev->dev);
 
+	asoc_dma_platform_register(&pdev->dev);
+
 	return 0;
 err:
 	release_mem_region(regs_base, resource_size(res));
@@ -1114,7 +1116,7 @@
 	return ret;
 }
 
-static __devexit int samsung_i2s_remove(struct platform_device *pdev)
+static int samsung_i2s_remove(struct platform_device *pdev)
 {
 	struct i2s_dai *i2s, *other;
 	struct resource *res;
@@ -1135,6 +1137,7 @@
 	i2s->pri_dai = NULL;
 	i2s->sec_dai = NULL;
 
+	asoc_dma_platform_unregister(&pdev->dev);
 	snd_soc_unregister_dai(&pdev->dev);
 
 	return 0;
@@ -1142,7 +1145,7 @@
 
 static struct platform_driver samsung_i2s_driver = {
 	.probe  = samsung_i2s_probe,
-	.remove = __devexit_p(samsung_i2s_remove),
+	.remove = samsung_i2s_remove,
 	.driver = {
 		.name = "samsung-i2s",
 		.owner = THIS_MODULE,
diff --git a/sound/soc/samsung/idma.c b/sound/soc/samsung/idma.c
index c227c31..a07950b 100644
--- a/sound/soc/samsung/idma.c
+++ b/sound/soc/samsung/idma.c
@@ -416,12 +416,12 @@
 	.pcm_free = idma_free,
 };
 
-static int __devinit asoc_idma_platform_probe(struct platform_device *pdev)
+static int asoc_idma_platform_probe(struct platform_device *pdev)
 {
 	return snd_soc_register_platform(&pdev->dev, &asoc_idma_platform);
 }
 
-static int __devexit asoc_idma_platform_remove(struct platform_device *pdev)
+static int asoc_idma_platform_remove(struct platform_device *pdev)
 {
 	snd_soc_unregister_platform(&pdev->dev);
 	return 0;
@@ -434,7 +434,7 @@
 	},
 
 	.probe = asoc_idma_platform_probe,
-	.remove = __devexit_p(asoc_idma_platform_remove),
+	.remove = asoc_idma_platform_remove,
 };
 
 module_platform_driver(asoc_idma_driver);
diff --git a/sound/soc/samsung/jive_wm8750.c b/sound/soc/samsung/jive_wm8750.c
index 1578663..b5f6abd 100644
--- a/sound/soc/samsung/jive_wm8750.c
+++ b/sound/soc/samsung/jive_wm8750.c
@@ -118,7 +118,7 @@
 	.stream_name	= "WM8750",
 	.cpu_dai_name	= "s3c2412-i2s",
 	.codec_dai_name = "wm8750-hifi",
-	.platform_name	= "samsung-audio",
+	.platform_name	= "s3c2412-i2s",
 	.codec_name	= "wm8750.0-001a",
 	.init		= jive_wm8750_init,
 	.ops		= &jive_ops,
diff --git a/sound/soc/samsung/littlemill.c b/sound/soc/samsung/littlemill.c
index ee52c8a0..bfb91f3 100644
--- a/sound/soc/samsung/littlemill.c
+++ b/sound/soc/samsung/littlemill.c
@@ -145,7 +145,7 @@
 		.stream_name = "CPU",
 		.cpu_dai_name = "samsung-i2s.0",
 		.codec_dai_name = "wm8994-aif1",
-		.platform_name = "samsung-audio",
+		.platform_name = "samsung-i2s.0",
 		.codec_name = "wm8994-codec",
 		.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
 				| SND_SOC_DAIFMT_CBM_CFM,
@@ -270,7 +270,7 @@
 		return ret;
 
 	/* This will check device compatibility itself */
-	wm8958_mic_detect(codec, &littlemill_headset, NULL, NULL);
+	wm8958_mic_detect(codec, &littlemill_headset, NULL, NULL, NULL, NULL);
 
 	/* As will this */
 	wm8994_mic_detect(codec, &littlemill_headset, 1);
@@ -297,7 +297,7 @@
 	.late_probe = littlemill_late_probe,
 };
 
-static __devinit int littlemill_probe(struct platform_device *pdev)
+static int littlemill_probe(struct platform_device *pdev)
 {
 	struct snd_soc_card *card = &littlemill;
 	int ret;
@@ -314,7 +314,7 @@
 	return 0;
 }
 
-static int __devexit littlemill_remove(struct platform_device *pdev)
+static int littlemill_remove(struct platform_device *pdev)
 {
 	struct snd_soc_card *card = platform_get_drvdata(pdev);
 
@@ -330,7 +330,7 @@
 		.pm = &snd_soc_pm_ops,
 	},
 	.probe = littlemill_probe,
-	.remove = __devexit_p(littlemill_remove),
+	.remove = littlemill_remove,
 };
 
 module_platform_driver(littlemill_driver);
diff --git a/sound/soc/samsung/ln2440sbc_alc650.c b/sound/soc/samsung/ln2440sbc_alc650.c
index 69c4a59..9342fc27 100644
--- a/sound/soc/samsung/ln2440sbc_alc650.c
+++ b/sound/soc/samsung/ln2440sbc_alc650.c
@@ -28,7 +28,7 @@
 	.cpu_dai_name = "samsung-ac97",
 	.codec_dai_name = "ac97-hifi",
 	.codec_name = "ac97-codec",
-	.platform_name = "samsung-audio",
+	.platform_name = "samsung-ac97",
 },
 };
 
diff --git a/sound/soc/samsung/lowland.c b/sound/soc/samsung/lowland.c
index 6abf341..570cf52 100644
--- a/sound/soc/samsung/lowland.c
+++ b/sound/soc/samsung/lowland.c
@@ -99,7 +99,7 @@
 		.stream_name = "CPU",
 		.cpu_dai_name = "samsung-i2s.0",
 		.codec_dai_name = "wm5100-aif1",
-		.platform_name = "samsung-audio",
+		.platform_name = "samsung-i2s.0",
 		.codec_name = "wm5100.1-001a",
 		.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
 				SND_SOC_DAIFMT_CBM_CFM,
@@ -180,7 +180,7 @@
 	.num_dapm_routes = ARRAY_SIZE(audio_paths),
 };
 
-static __devinit int lowland_probe(struct platform_device *pdev)
+static int lowland_probe(struct platform_device *pdev)
 {
 	struct snd_soc_card *card = &lowland;
 	int ret;
@@ -197,7 +197,7 @@
 	return 0;
 }
 
-static int __devexit lowland_remove(struct platform_device *pdev)
+static int lowland_remove(struct platform_device *pdev)
 {
 	struct snd_soc_card *card = platform_get_drvdata(pdev);
 
@@ -213,7 +213,7 @@
 		.pm = &snd_soc_pm_ops,
 	},
 	.probe = lowland_probe,
-	.remove = __devexit_p(lowland_remove),
+	.remove = lowland_remove,
 };
 
 module_platform_driver(lowland_driver);
diff --git a/sound/soc/samsung/neo1973_wm8753.c b/sound/soc/samsung/neo1973_wm8753.c
index 321d511..c7e965f 100644
--- a/sound/soc/samsung/neo1973_wm8753.c
+++ b/sound/soc/samsung/neo1973_wm8753.c
@@ -364,7 +364,7 @@
 { /* Hifi Playback - for similatious use with voice below */
 	.name = "WM8753",
 	.stream_name = "WM8753 HiFi",
-	.platform_name = "samsung-audio",
+	.platform_name = "s3c24xx-iis",
 	.cpu_dai_name = "s3c24xx-iis",
 	.codec_dai_name = "wm8753-hifi",
 	.codec_name = "wm8753.0-001a",
diff --git a/sound/soc/samsung/pcm.c b/sound/soc/samsung/pcm.c
index c860819..13bab79 100644
--- a/sound/soc/samsung/pcm.c
+++ b/sound/soc/samsung/pcm.c
@@ -490,7 +490,7 @@
 	},
 };
 
-static __devinit int s3c_pcm_dev_probe(struct platform_device *pdev)
+static int s3c_pcm_dev_probe(struct platform_device *pdev)
 {
 	struct s3c_pcm_info *pcm;
 	struct resource *mem_res, *dmatx_res, *dmarx_res;
@@ -543,7 +543,7 @@
 		ret = PTR_ERR(pcm->cclk);
 		goto err1;
 	}
-	clk_enable(pcm->cclk);
+	clk_prepare_enable(pcm->cclk);
 
 	/* record our pcm structure for later use in the callbacks */
 	dev_set_drvdata(&pdev->dev, pcm);
@@ -568,7 +568,7 @@
 		ret = -ENOENT;
 		goto err4;
 	}
-	clk_enable(pcm->pclk);
+	clk_prepare_enable(pcm->pclk);
 
 	s3c_pcm_stereo_in[pdev->id].dma_addr = mem_res->start
 							+ S3C_PCM_RXFIFO;
@@ -589,27 +589,36 @@
 		goto err5;
 	}
 
+	ret = asoc_dma_platform_register(&pdev->dev);
+	if (ret) {
+		dev_err(&pdev->dev, "failed to get register DMA: %d\n", ret);
+		goto err6;
+	}
+
 	return 0;
 
+err6:
+	snd_soc_unregister_dai(&pdev->dev);
 err5:
-	clk_disable(pcm->pclk);
+	clk_disable_unprepare(pcm->pclk);
 	clk_put(pcm->pclk);
 err4:
 	iounmap(pcm->regs);
 err3:
 	release_mem_region(mem_res->start, resource_size(mem_res));
 err2:
-	clk_disable(pcm->cclk);
+	clk_disable_unprepare(pcm->cclk);
 	clk_put(pcm->cclk);
 err1:
 	return ret;
 }
 
-static __devexit int s3c_pcm_dev_remove(struct platform_device *pdev)
+static int s3c_pcm_dev_remove(struct platform_device *pdev)
 {
 	struct s3c_pcm_info *pcm = &s3c_pcm[pdev->id];
 	struct resource *mem_res;
 
+	asoc_dma_platform_unregister(&pdev->dev);
 	snd_soc_unregister_dai(&pdev->dev);
 
 	pm_runtime_disable(&pdev->dev);
@@ -619,8 +628,8 @@
 	mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	release_mem_region(mem_res->start, resource_size(mem_res));
 
-	clk_disable(pcm->cclk);
-	clk_disable(pcm->pclk);
+	clk_disable_unprepare(pcm->cclk);
+	clk_disable_unprepare(pcm->pclk);
 	clk_put(pcm->pclk);
 	clk_put(pcm->cclk);
 
@@ -629,7 +638,7 @@
 
 static struct platform_driver s3c_pcm_driver = {
 	.probe  = s3c_pcm_dev_probe,
-	.remove = __devexit_p(s3c_pcm_dev_remove),
+	.remove = s3c_pcm_dev_remove,
 	.driver = {
 		.name = "samsung-pcm",
 		.owner = THIS_MODULE,
diff --git a/sound/soc/samsung/rx1950_uda1380.c b/sound/soc/samsung/rx1950_uda1380.c
index 21e1236..a5826ea 100644
--- a/sound/soc/samsung/rx1950_uda1380.c
+++ b/sound/soc/samsung/rx1950_uda1380.c
@@ -85,7 +85,7 @@
 		.cpu_dai_name	= "s3c24xx-iis",
 		.codec_dai_name	= "uda1380-hifi",
 		.init		= rx1950_uda1380_init,
-		.platform_name	= "samsung-audio",
+		.platform_name	= "s3c24xx-iis",
 		.codec_name	= "uda1380-codec.0-001a",
 		.ops		= &rx1950_ops,
 	},
diff --git a/sound/soc/samsung/s3c2412-i2s.c b/sound/soc/samsung/s3c2412-i2s.c
index ac7701b..2213377 100644
--- a/sound/soc/samsung/s3c2412-i2s.c
+++ b/sound/soc/samsung/s3c2412-i2s.c
@@ -160,20 +160,38 @@
 	.ops = &s3c2412_i2s_dai_ops,
 };
 
-static __devinit int s3c2412_iis_dev_probe(struct platform_device *pdev)
+static int s3c2412_iis_dev_probe(struct platform_device *pdev)
 {
-	return s3c_i2sv2_register_dai(&pdev->dev, -1, &s3c2412_i2s_dai);
+	int ret = 0;
+
+	ret = s3c_i2sv2_register_dai(&pdev->dev, -1, &s3c2412_i2s_dai);
+	if (ret) {
+		pr_err("failed to register the dai\n");
+		return ret;
+	}
+
+	ret = asoc_dma_platform_register(&pdev->dev);
+	if (ret) {
+		pr_err("failed to register the DMA: %d\n", ret);
+		goto err;
+	}
+
+	return 0;
+err:
+	snd_soc_unregister_dai(&pdev->dev);
+	return ret;
 }
 
-static __devexit int s3c2412_iis_dev_remove(struct platform_device *pdev)
+static int s3c2412_iis_dev_remove(struct platform_device *pdev)
 {
+	asoc_dma_platform_unregister(&pdev->dev);
 	snd_soc_unregister_dai(&pdev->dev);
 	return 0;
 }
 
 static struct platform_driver s3c2412_iis_driver = {
 	.probe  = s3c2412_iis_dev_probe,
-	.remove = __devexit_p(s3c2412_iis_dev_remove),
+	.remove = s3c2412_iis_dev_remove,
 	.driver = {
 		.name = "s3c2412-iis",
 		.owner = THIS_MODULE,
diff --git a/sound/soc/samsung/s3c24xx-i2s.c b/sound/soc/samsung/s3c24xx-i2s.c
index 0aae3a3..ee10e87 100644
--- a/sound/soc/samsung/s3c24xx-i2s.c
+++ b/sound/soc/samsung/s3c24xx-i2s.c
@@ -465,20 +465,38 @@
 	.ops = &s3c24xx_i2s_dai_ops,
 };
 
-static __devinit int s3c24xx_iis_dev_probe(struct platform_device *pdev)
+static int s3c24xx_iis_dev_probe(struct platform_device *pdev)
 {
-	return snd_soc_register_dai(&pdev->dev, &s3c24xx_i2s_dai);
+	int ret = 0;
+
+	ret = s3c_i2sv2_register_dai(&pdev->dev, -1, &s3c2412_i2s_dai);
+	if (ret) {
+		pr_err("failed to register the dai\n");
+		return ret;
+	}
+
+	ret = asoc_dma_platform_register(&pdev->dev);
+	if (ret) {
+		pr_err("failed to register the dma: %d\n", ret);
+		goto err;
+	}
+
+	return 0;
+err:
+	snd_soc_unregister_dai(&pdev->dev);
+	return ret;
 }
 
-static __devexit int s3c24xx_iis_dev_remove(struct platform_device *pdev)
+static int s3c24xx_iis_dev_remove(struct platform_device *pdev)
 {
+	asoc_dma_platform_unregister(&pdev->dev);
 	snd_soc_unregister_dai(&pdev->dev);
 	return 0;
 }
 
 static struct platform_driver s3c24xx_iis_driver = {
 	.probe  = s3c24xx_iis_dev_probe,
-	.remove = __devexit_p(s3c24xx_iis_dev_remove),
+	.remove = s3c24xx_iis_dev_remove,
 	.driver = {
 		.name = "s3c24xx-iis",
 		.owner = THIS_MODULE,
diff --git a/sound/soc/samsung/s3c24xx_simtec.c b/sound/soc/samsung/s3c24xx_simtec.c
index 335a7d8..2c015f6 100644
--- a/sound/soc/samsung/s3c24xx_simtec.c
+++ b/sound/soc/samsung/s3c24xx_simtec.c
@@ -313,8 +313,8 @@
 EXPORT_SYMBOL_GPL(simtec_audio_pmops);
 #endif
 
-int __devinit simtec_audio_core_probe(struct platform_device *pdev,
-				      struct snd_soc_card *card)
+int simtec_audio_core_probe(struct platform_device *pdev,
+			    struct snd_soc_card *card)
 {
 	struct platform_device *snd_dev;
 	int ret;
@@ -371,7 +371,7 @@
 }
 EXPORT_SYMBOL_GPL(simtec_audio_core_probe);
 
-int __devexit simtec_audio_remove(struct platform_device *pdev)
+int simtec_audio_remove(struct platform_device *pdev)
 {
 	struct platform_device *snd_dev = platform_get_drvdata(pdev);
 
diff --git a/sound/soc/samsung/s3c24xx_simtec_hermes.c b/sound/soc/samsung/s3c24xx_simtec_hermes.c
index 7ace6a8..d8a0543 100644
--- a/sound/soc/samsung/s3c24xx_simtec_hermes.c
+++ b/sound/soc/samsung/s3c24xx_simtec_hermes.c
@@ -82,7 +82,7 @@
 	.codec_name	= "tlv320aic3x-codec.0-001a",
 	.cpu_dai_name	= "s3c24xx-iis",
 	.codec_dai_name = "tlv320aic3x-hifi",
-	.platform_name	= "samsung-audio",
+	.platform_name	= "s3c24xx-iis",
 	.init		= simtec_hermes_init,
 };
 
@@ -99,7 +99,7 @@
 	.num_dapm_routes = ARRAY_SIZE(base_map),
 };
 
-static int __devinit simtec_audio_hermes_probe(struct platform_device *pd)
+static int simtec_audio_hermes_probe(struct platform_device *pd)
 {
 	dev_info(&pd->dev, "probing....\n");
 	return simtec_audio_core_probe(pd, &snd_soc_machine_simtec_aic33);
@@ -112,7 +112,7 @@
 		.pm	= simtec_audio_pm,
 	},
 	.probe	= simtec_audio_hermes_probe,
-	.remove	= __devexit_p(simtec_audio_remove),
+	.remove	= simtec_audio_remove,
 };
 
 module_platform_driver(simtec_audio_hermes_platdrv);
diff --git a/sound/soc/samsung/s3c24xx_simtec_tlv320aic23.c b/sound/soc/samsung/s3c24xx_simtec_tlv320aic23.c
index c42d5f0..1ac0d7a 100644
--- a/sound/soc/samsung/s3c24xx_simtec_tlv320aic23.c
+++ b/sound/soc/samsung/s3c24xx_simtec_tlv320aic23.c
@@ -71,7 +71,7 @@
 	.codec_name	= "tlv320aic3x-codec.0-001a",
 	.cpu_dai_name	= "s3c24xx-iis",
 	.codec_dai_name = "tlv320aic3x-hifi",
-	.platform_name	= "samsung-audio",
+	.platform_name	= "s3c24xx-iis",
 	.init		= simtec_tlv320aic23_init,
 };
 
@@ -88,7 +88,7 @@
 	.num_dapm_routes = ARRAY_SIZE(base_map),
 };
 
-static int __devinit simtec_audio_tlv320aic23_probe(struct platform_device *pd)
+static int simtec_audio_tlv320aic23_probe(struct platform_device *pd)
 {
 	return simtec_audio_core_probe(pd, &snd_soc_machine_simtec_aic23);
 }
@@ -100,7 +100,7 @@
 		.pm	= simtec_audio_pm,
 	},
 	.probe	= simtec_audio_tlv320aic23_probe,
-	.remove	= __devexit_p(simtec_audio_remove),
+	.remove	= simtec_audio_remove,
 };
 
 module_platform_driver(simtec_audio_tlv320aic23_driver);
diff --git a/sound/soc/samsung/s3c24xx_uda134x.c b/sound/soc/samsung/s3c24xx_uda134x.c
index d731042..333e1b7 100644
--- a/sound/soc/samsung/s3c24xx_uda134x.c
+++ b/sound/soc/samsung/s3c24xx_uda134x.c
@@ -224,7 +224,7 @@
 	.codec_dai_name = "uda134x-hifi",
 	.cpu_dai_name = "s3c24xx-iis",
 	.ops = &s3c24xx_uda134x_ops,
-	.platform_name	= "samsung-audio",
+	.platform_name	= "s3c24xx-iis",
 };
 
 static struct snd_soc_card snd_soc_s3c24xx_uda134x = {
diff --git a/sound/soc/samsung/smartq_wm8987.c b/sound/soc/samsung/smartq_wm8987.c
index f2dcb42..58ae3237 100644
--- a/sound/soc/samsung/smartq_wm8987.c
+++ b/sound/soc/samsung/smartq_wm8987.c
@@ -189,7 +189,7 @@
 		.stream_name	= "SmartQ Hi-Fi",
 		.cpu_dai_name	= "samsung-i2s.0",
 		.codec_dai_name	= "wm8750-hifi",
-		.platform_name	= "samsung-audio",
+		.platform_name	= "samsung-i2s.0",
 		.codec_name	= "wm8750.0-0x1a",
 		.init		= smartq_wm8987_init,
 		.ops		= &smartq_hifi_ops,
diff --git a/sound/soc/samsung/smdk2443_wm9710.c b/sound/soc/samsung/smdk2443_wm9710.c
index 720ba29..c390aad6 100644
--- a/sound/soc/samsung/smdk2443_wm9710.c
+++ b/sound/soc/samsung/smdk2443_wm9710.c
@@ -24,7 +24,7 @@
 	.cpu_dai_name = "samsung-ac97",
 	.codec_dai_name = "ac97-hifi",
 	.codec_name = "ac97-codec",
-	.platform_name = "samsung-audio",
+	.platform_name = "samsung-ac97",
 },
 };
 
diff --git a/sound/soc/samsung/smdk_spdif.c b/sound/soc/samsung/smdk_spdif.c
index beaa9c1..a2f2363 100644
--- a/sound/soc/samsung/smdk_spdif.c
+++ b/sound/soc/samsung/smdk_spdif.c
@@ -151,7 +151,7 @@
 static struct snd_soc_dai_link smdk_dai = {
 	.name = "S/PDIF",
 	.stream_name = "S/PDIF PCM Playback",
-	.platform_name = "samsung-audio",
+	.platform_name = "samsung-spdif",
 	.cpu_dai_name = "samsung-spdif",
 	.codec_dai_name = "dit-hifi",
 	.codec_name = "spdif-dit",
diff --git a/sound/soc/samsung/smdk_wm8580.c b/sound/soc/samsung/smdk_wm8580.c
index ade2809..7e2b710 100644
--- a/sound/soc/samsung/smdk_wm8580.c
+++ b/sound/soc/samsung/smdk_wm8580.c
@@ -176,7 +176,7 @@
 		.stream_name = "Playback",
 		.cpu_dai_name = "samsung-i2s.0",
 		.codec_dai_name = "wm8580-hifi-playback",
-		.platform_name = "samsung-audio",
+		.platform_name = "samsung-i2s.0",
 		.codec_name = "wm8580.0-001b",
 		.ops = &smdk_ops,
 	},
@@ -185,7 +185,7 @@
 		.stream_name = "Capture",
 		.cpu_dai_name = "samsung-i2s.0",
 		.codec_dai_name = "wm8580-hifi-capture",
-		.platform_name = "samsung-audio",
+		.platform_name = "samsung-i2s.0",
 		.codec_name = "wm8580.0-001b",
 		.init = smdk_wm8580_init_paiftx,
 		.ops = &smdk_ops,
@@ -195,7 +195,7 @@
 		.stream_name = "Playback",
 		.cpu_dai_name = "samsung-i2s.x",
 		.codec_dai_name = "wm8580-hifi-playback",
-		.platform_name = "samsung-audio",
+		.platform_name = "samsung-i2s.x",
 		.codec_name = "wm8580.0-001b",
 		.ops = &smdk_ops,
 	},
diff --git a/sound/soc/samsung/smdk_wm8580pcm.c b/sound/soc/samsung/smdk_wm8580pcm.c
index fab5322..e43bd42 100644
--- a/sound/soc/samsung/smdk_wm8580pcm.c
+++ b/sound/soc/samsung/smdk_wm8580pcm.c
@@ -135,7 +135,7 @@
 		.stream_name = "Capture",
 		.cpu_dai_name = "samsung-pcm.0",
 		.codec_dai_name = "wm8580-hifi-capture",
-		.platform_name = "samsung-audio",
+		.platform_name = "samsung-pcm.0",
 		.codec_name = "wm8580.0-001b",
 		.ops = &smdk_wm8580_pcm_ops,
 	},
@@ -153,7 +153,7 @@
  * is absent (or not connected), so we connect EXT_VOICE_CLK(OSC4),
  * 2.0484Mhz, directly with MCLK both Codec and SoC.
  */
-static int __devinit snd_smdk_probe(struct platform_device *pdev)
+static int snd_smdk_probe(struct platform_device *pdev)
 {
 	int ret = 0;
 
@@ -173,7 +173,7 @@
 	return 0;
 }
 
-static int __devexit snd_smdk_remove(struct platform_device *pdev)
+static int snd_smdk_remove(struct platform_device *pdev)
 {
 	snd_soc_unregister_card(&smdk_pcm);
 	platform_set_drvdata(pdev, NULL);
@@ -186,7 +186,7 @@
 		.name = "samsung-smdk-pcm",
 	},
 	.probe = snd_smdk_probe,
-	.remove = __devexit_p(snd_smdk_remove),
+	.remove = snd_smdk_remove,
 };
 
 module_platform_driver(snd_smdk_driver);
diff --git a/sound/soc/samsung/smdk_wm8994.c b/sound/soc/samsung/smdk_wm8994.c
index 48dd4dd..b0d0ab8 100644
--- a/sound/soc/samsung/smdk_wm8994.c
+++ b/sound/soc/samsung/smdk_wm8994.c
@@ -127,7 +127,7 @@
 		.stream_name = "Pri_Dai",
 		.cpu_dai_name = "samsung-i2s.0",
 		.codec_dai_name = "wm8994-aif1",
-		.platform_name = "samsung-audio",
+		.platform_name = "samsung-i2s.0",
 		.codec_name = "wm8994-codec",
 		.init = smdk_wm8994_init_paiftx,
 		.ops = &smdk_ops,
@@ -136,7 +136,7 @@
 		.stream_name = "Sec_Dai",
 		.cpu_dai_name = "samsung-i2s.4",
 		.codec_dai_name = "wm8994-aif1",
-		.platform_name = "samsung-audio",
+		.platform_name = "samsung-i2s.4",
 		.codec_name = "wm8994-codec",
 		.ops = &smdk_ops,
 	},
@@ -150,7 +150,7 @@
 };
 
 
-static int __devinit smdk_audio_probe(struct platform_device *pdev)
+static int smdk_audio_probe(struct platform_device *pdev)
 {
 	int ret;
 	struct snd_soc_card *card = &smdk;
@@ -164,7 +164,7 @@
 	return ret;
 }
 
-static int __devexit smdk_audio_remove(struct platform_device *pdev)
+static int smdk_audio_remove(struct platform_device *pdev)
 {
 	struct snd_soc_card *card = platform_get_drvdata(pdev);
 
@@ -179,7 +179,7 @@
 		.owner	= THIS_MODULE,
 	},
 	.probe		= smdk_audio_probe,
-	.remove		= __devexit_p(smdk_audio_remove),
+	.remove		= smdk_audio_remove,
 };
 
 module_platform_driver(smdk_audio_driver);
diff --git a/sound/soc/samsung/smdk_wm8994pcm.c b/sound/soc/samsung/smdk_wm8994pcm.c
index 77ecba9..3688a32 100644
--- a/sound/soc/samsung/smdk_wm8994pcm.c
+++ b/sound/soc/samsung/smdk_wm8994pcm.c
@@ -116,7 +116,7 @@
 		.stream_name = "Primary PCM",
 		.cpu_dai_name = "samsung-pcm.0",
 		.codec_dai_name = "wm8994-aif1",
-		.platform_name = "samsung-audio",
+		.platform_name = "samsung-pcm.0",
 		.codec_name = "wm8994-codec",
 		.ops = &smdk_wm8994_pcm_ops,
 	},
@@ -129,7 +129,7 @@
 	.num_links = 1,
 };
 
-static int __devinit snd_smdk_probe(struct platform_device *pdev)
+static int snd_smdk_probe(struct platform_device *pdev)
 {
 	int ret = 0;
 
@@ -143,7 +143,7 @@
 	return 0;
 }
 
-static int __devexit snd_smdk_remove(struct platform_device *pdev)
+static int snd_smdk_remove(struct platform_device *pdev)
 {
 	snd_soc_unregister_card(&smdk_pcm);
 	platform_set_drvdata(pdev, NULL);
@@ -156,7 +156,7 @@
 		.name = "samsung-smdk-pcm",
 	},
 	.probe = snd_smdk_probe,
-	.remove = __devexit_p(snd_smdk_remove),
+	.remove = snd_smdk_remove,
 };
 
 module_platform_driver(snd_smdk_driver);
diff --git a/sound/soc/samsung/smdk_wm9713.c b/sound/soc/samsung/smdk_wm9713.c
index 55b2ca7..0d20e4e 100644
--- a/sound/soc/samsung/smdk_wm9713.c
+++ b/sound/soc/samsung/smdk_wm9713.c
@@ -42,7 +42,7 @@
 static struct snd_soc_dai_link smdk_dai = {
 	.name = "AC97",
 	.stream_name = "AC97 PCM",
-	.platform_name = "samsung-audio",
+	.platform_name = "samsung-ac97",
 	.cpu_dai_name = "samsung-ac97",
 	.codec_dai_name = "wm9713-hifi",
 	.codec_name = "wm9713-codec",
diff --git a/sound/soc/samsung/spdif.c b/sound/soc/samsung/spdif.c
index bc24c7a..5008e5b 100644
--- a/sound/soc/samsung/spdif.c
+++ b/sound/soc/samsung/spdif.c
@@ -357,7 +357,7 @@
 	.resume = spdif_resume,
 };
 
-static __devinit int spdif_probe(struct platform_device *pdev)
+static int spdif_probe(struct platform_device *pdev)
 {
 	struct s3c_audio_pdata *spdif_pdata;
 	struct resource *mem_res, *dma_res;
@@ -397,7 +397,7 @@
 		ret = -ENOENT;
 		goto err0;
 	}
-	clk_enable(spdif->pclk);
+	clk_prepare_enable(spdif->pclk);
 
 	spdif->sclk = clk_get(&pdev->dev, "sclk_spdif");
 	if (IS_ERR(spdif->sclk)) {
@@ -405,7 +405,7 @@
 		ret = -ENOENT;
 		goto err1;
 	}
-	clk_enable(spdif->sclk);
+	clk_prepare_enable(spdif->sclk);
 
 	/* Request S/PDIF Register's memory region */
 	if (!request_mem_region(mem_res->start,
@@ -437,27 +437,35 @@
 
 	spdif->dma_playback = &spdif_stereo_out;
 
-	return 0;
+	ret = asoc_dma_platform_register(&pdev->dev);
+	if (ret) {
+		dev_err(&pdev->dev, "failed to register DMA: %d\n", ret);
+		goto err5;
+	}
 
+	return 0;
+err5:
+	snd_soc_unregister_dai(&pdev->dev);
 err4:
 	iounmap(spdif->regs);
 err3:
 	release_mem_region(mem_res->start, resource_size(mem_res));
 err2:
-	clk_disable(spdif->sclk);
+	clk_disable_unprepare(spdif->sclk);
 	clk_put(spdif->sclk);
 err1:
-	clk_disable(spdif->pclk);
+	clk_disable_unprepare(spdif->pclk);
 	clk_put(spdif->pclk);
 err0:
 	return ret;
 }
 
-static __devexit int spdif_remove(struct platform_device *pdev)
+static int spdif_remove(struct platform_device *pdev)
 {
 	struct samsung_spdif_info *spdif = &spdif_info;
 	struct resource *mem_res;
 
+	asoc_dma_platform_unregister(&pdev->dev);
 	snd_soc_unregister_dai(&pdev->dev);
 
 	iounmap(spdif->regs);
@@ -466,9 +474,9 @@
 	if (mem_res)
 		release_mem_region(mem_res->start, resource_size(mem_res));
 
-	clk_disable(spdif->sclk);
+	clk_disable_unprepare(spdif->sclk);
 	clk_put(spdif->sclk);
-	clk_disable(spdif->pclk);
+	clk_disable_unprepare(spdif->pclk);
 	clk_put(spdif->pclk);
 
 	return 0;
@@ -476,7 +484,7 @@
 
 static struct platform_driver samsung_spdif_driver = {
 	.probe	= spdif_probe,
-	.remove	= __devexit_p(spdif_remove),
+	.remove	= spdif_remove,
 	.driver	= {
 		.name	= "samsung-spdif",
 		.owner	= THIS_MODULE,
diff --git a/sound/soc/samsung/speyside.c b/sound/soc/samsung/speyside.c
index c7e1c28..57df90d 100644
--- a/sound/soc/samsung/speyside.c
+++ b/sound/soc/samsung/speyside.c
@@ -198,7 +198,7 @@
 		.stream_name = "CPU-DSP",
 		.cpu_dai_name = "samsung-i2s.0",
 		.codec_dai_name = "wm0010-sdi1",
-		.platform_name = "samsung-audio",
+		.platform_name = "samsung-i2s.0",
 		.codec_name = "spi0.0",
 		.init = speyside_wm0010_init,
 		.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
@@ -320,7 +320,7 @@
 	.late_probe = speyside_late_probe,
 };
 
-static __devinit int speyside_probe(struct platform_device *pdev)
+static int speyside_probe(struct platform_device *pdev)
 {
 	struct snd_soc_card *card = &speyside;
 	int ret;
@@ -337,7 +337,7 @@
 	return 0;
 }
 
-static int __devexit speyside_remove(struct platform_device *pdev)
+static int speyside_remove(struct platform_device *pdev)
 {
 	struct snd_soc_card *card = platform_get_drvdata(pdev);
 
@@ -353,7 +353,7 @@
 		.pm = &snd_soc_pm_ops,
 	},
 	.probe = speyside_probe,
-	.remove = __devexit_p(speyside_remove),
+	.remove = speyside_remove,
 };
 
 module_platform_driver(speyside_driver);
diff --git a/sound/soc/samsung/tobermory.c b/sound/soc/samsung/tobermory.c
index 9199649..f21ff60 100644
--- a/sound/soc/samsung/tobermory.c
+++ b/sound/soc/samsung/tobermory.c
@@ -110,7 +110,7 @@
 		.stream_name = "CPU",
 		.cpu_dai_name = "samsung-i2s.0",
 		.codec_dai_name = "wm8962",
-		.platform_name = "samsung-audio",
+		.platform_name = "samsung-i2s.0",
 		.codec_name = "wm8962.1-001a",
 		.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
 				| SND_SOC_DAIFMT_CBM_CFM,
@@ -214,7 +214,7 @@
 	.late_probe = tobermory_late_probe,
 };
 
-static __devinit int tobermory_probe(struct platform_device *pdev)
+static int tobermory_probe(struct platform_device *pdev)
 {
 	struct snd_soc_card *card = &tobermory;
 	int ret;
@@ -231,7 +231,7 @@
 	return 0;
 }
 
-static int __devexit tobermory_remove(struct platform_device *pdev)
+static int tobermory_remove(struct platform_device *pdev)
 {
 	struct snd_soc_card *card = platform_get_drvdata(pdev);
 
@@ -247,7 +247,7 @@
 		.pm = &snd_soc_pm_ops,
 	},
 	.probe = tobermory_probe,
-	.remove = __devexit_p(tobermory_remove),
+	.remove = tobermory_remove,
 };
 
 module_platform_driver(tobermory_driver);
diff --git a/sound/soc/sh/dma-sh7760.c b/sound/soc/sh/dma-sh7760.c
index 7da2018..19eff8f 100644
--- a/sound/soc/sh/dma-sh7760.c
+++ b/sound/soc/sh/dma-sh7760.c
@@ -348,12 +348,12 @@
 	.pcm_free	= camelot_pcm_free,
 };
 
-static int __devinit sh7760_soc_platform_probe(struct platform_device *pdev)
+static int sh7760_soc_platform_probe(struct platform_device *pdev)
 {
 	return snd_soc_register_platform(&pdev->dev, &sh7760_soc_platform);
 }
 
-static int __devexit sh7760_soc_platform_remove(struct platform_device *pdev)
+static int sh7760_soc_platform_remove(struct platform_device *pdev)
 {
 	snd_soc_unregister_platform(&pdev->dev);
 	return 0;
@@ -366,7 +366,7 @@
 	},
 
 	.probe = sh7760_soc_platform_probe,
-	.remove = __devexit_p(sh7760_soc_platform_remove),
+	.remove = sh7760_soc_platform_remove,
 };
 
 module_platform_driver(sh7760_pcm_driver);
diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
index 9d7f307..a606d0f 100644
--- a/sound/soc/sh/fsi.c
+++ b/sound/soc/sh/fsi.c
@@ -22,6 +22,7 @@
 #include <linux/module.h>
 #include <linux/workqueue.h>
 #include <sound/soc.h>
+#include <sound/pcm_params.h>
 #include <sound/sh_fsi.h>
 
 /* PortA/PortB register */
@@ -189,6 +190,14 @@
  */
 
 /*
+ *	FSI clock
+ *
+ * FSIxCLK [CPG] (ick) ------->	|
+ *				|-> FSI_DIV (div)-> FSI2
+ * FSIxCK [external] (xck) --->	|
+ */
+
+/*
  *		struct
  */
 
@@ -228,6 +237,20 @@
 	dma_addr_t		dma;
 };
 
+struct fsi_clk {
+	/* see [FSI clock] */
+	struct clk *own;
+	struct clk *xck;
+	struct clk *ick;
+	struct clk *div;
+	int (*set_rate)(struct device *dev,
+			struct fsi_priv *fsi,
+			unsigned long rate);
+
+	unsigned long rate;
+	unsigned int count;
+};
+
 struct fsi_priv {
 	void __iomem *base;
 	struct fsi_master *master;
@@ -236,11 +259,17 @@
 	struct fsi_stream playback;
 	struct fsi_stream capture;
 
+	struct fsi_clk clock;
+
 	u32 fmt;
 
 	int chan_num:16;
 	int clk_master:1;
+	int clk_cpg:1;
 	int spdif:1;
+	int enable_stream:1;
+	int bit_clk_inv:1;
+	int lr_clk_inv:1;
 
 	long rate;
 };
@@ -370,6 +399,11 @@
 	return fsi->spdif;
 }
 
+static int fsi_is_enable_stream(struct fsi_priv *fsi)
+{
+	return fsi->enable_stream;
+}
+
 static int fsi_is_play(struct snd_pcm_substream *substream)
 {
 	return substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
@@ -717,14 +751,335 @@
 /*
  *		clock function
  */
+static int fsi_clk_init(struct device *dev,
+			struct fsi_priv *fsi,
+			int xck,
+			int ick,
+			int div,
+			int (*set_rate)(struct device *dev,
+					struct fsi_priv *fsi,
+					unsigned long rate))
+{
+	struct fsi_clk *clock = &fsi->clock;
+	int is_porta = fsi_is_port_a(fsi);
+
+	clock->xck	= NULL;
+	clock->ick	= NULL;
+	clock->div	= NULL;
+	clock->rate	= 0;
+	clock->count	= 0;
+	clock->set_rate	= set_rate;
+
+	clock->own = devm_clk_get(dev, NULL);
+	if (IS_ERR(clock->own))
+		return -EINVAL;
+
+	/* external clock */
+	if (xck) {
+		clock->xck = devm_clk_get(dev, is_porta ? "xcka" : "xckb");
+		if (IS_ERR(clock->xck)) {
+			dev_err(dev, "can't get xck clock\n");
+			return -EINVAL;
+		}
+		if (clock->xck == clock->own) {
+			dev_err(dev, "cpu doesn't support xck clock\n");
+			return -EINVAL;
+		}
+	}
+
+	/* FSIACLK/FSIBCLK */
+	if (ick) {
+		clock->ick = devm_clk_get(dev,  is_porta ? "icka" : "ickb");
+		if (IS_ERR(clock->ick)) {
+			dev_err(dev, "can't get ick clock\n");
+			return -EINVAL;
+		}
+		if (clock->ick == clock->own) {
+			dev_err(dev, "cpu doesn't support ick clock\n");
+			return -EINVAL;
+		}
+	}
+
+	/* FSI-DIV */
+	if (div) {
+		clock->div = devm_clk_get(dev,  is_porta ? "diva" : "divb");
+		if (IS_ERR(clock->div)) {
+			dev_err(dev, "can't get div clock\n");
+			return -EINVAL;
+		}
+		if (clock->div == clock->own) {
+			dev_err(dev, "cpu doens't support div clock\n");
+			return -EINVAL;
+		}
+	}
+
+	return 0;
+}
+
+#define fsi_clk_invalid(fsi) fsi_clk_valid(fsi, 0)
+static void fsi_clk_valid(struct fsi_priv *fsi, unsigned long rate)
+{
+	fsi->clock.rate = rate;
+}
+
+static int fsi_clk_is_valid(struct fsi_priv *fsi)
+{
+	return	fsi->clock.set_rate &&
+		fsi->clock.rate;
+}
+
+static int fsi_clk_enable(struct device *dev,
+			  struct fsi_priv *fsi,
+			  unsigned long rate)
+{
+	struct fsi_clk *clock = &fsi->clock;
+	int ret = -EINVAL;
+
+	if (!fsi_clk_is_valid(fsi))
+		return ret;
+
+	if (0 == clock->count) {
+		ret = clock->set_rate(dev, fsi, rate);
+		if (ret < 0) {
+			fsi_clk_invalid(fsi);
+			return ret;
+		}
+
+		if (clock->xck)
+			clk_enable(clock->xck);
+		if (clock->ick)
+			clk_enable(clock->ick);
+		if (clock->div)
+			clk_enable(clock->div);
+
+		clock->count++;
+	}
+
+	return ret;
+}
+
+static int fsi_clk_disable(struct device *dev,
+			    struct fsi_priv *fsi)
+{
+	struct fsi_clk *clock = &fsi->clock;
+
+	if (!fsi_clk_is_valid(fsi))
+		return -EINVAL;
+
+	if (1 == clock->count--) {
+		if (clock->xck)
+			clk_disable(clock->xck);
+		if (clock->ick)
+			clk_disable(clock->ick);
+		if (clock->div)
+			clk_disable(clock->div);
+	}
+
+	return 0;
+}
+
+static int fsi_clk_set_ackbpf(struct device *dev,
+			      struct fsi_priv *fsi,
+			      int ackmd, int bpfmd)
+{
+	u32 data = 0;
+
+	/* check ackmd/bpfmd relationship */
+	if (bpfmd > ackmd) {
+		dev_err(dev, "unsupported rate (%d/%d)\n", ackmd, bpfmd);
+		return -EINVAL;
+	}
+
+	/*  ACKMD */
+	switch (ackmd) {
+	case 512:
+		data |= (0x0 << 12);
+		break;
+	case 256:
+		data |= (0x1 << 12);
+		break;
+	case 128:
+		data |= (0x2 << 12);
+		break;
+	case 64:
+		data |= (0x3 << 12);
+		break;
+	case 32:
+		data |= (0x4 << 12);
+		break;
+	default:
+		dev_err(dev, "unsupported ackmd (%d)\n", ackmd);
+		return -EINVAL;
+	}
+
+	/* BPFMD */
+	switch (bpfmd) {
+	case 32:
+		data |= (0x0 << 8);
+		break;
+	case 64:
+		data |= (0x1 << 8);
+		break;
+	case 128:
+		data |= (0x2 << 8);
+		break;
+	case 256:
+		data |= (0x3 << 8);
+		break;
+	case 512:
+		data |= (0x4 << 8);
+		break;
+	case 16:
+		data |= (0x7 << 8);
+		break;
+	default:
+		dev_err(dev, "unsupported bpfmd (%d)\n", bpfmd);
+		return -EINVAL;
+	}
+
+	dev_dbg(dev, "ACKMD/BPFMD = %d/%d\n", ackmd, bpfmd);
+
+	fsi_reg_mask_set(fsi, CKG1, (ACKMD_MASK | BPFMD_MASK) , data);
+	udelay(10);
+
+	return 0;
+}
+
+static int fsi_clk_set_rate_external(struct device *dev,
+				     struct fsi_priv *fsi,
+				     unsigned long rate)
+{
+	struct clk *xck = fsi->clock.xck;
+	struct clk *ick = fsi->clock.ick;
+	unsigned long xrate;
+	int ackmd, bpfmd;
+	int ret = 0;
+
+	/* check clock rate */
+	xrate = clk_get_rate(xck);
+	if (xrate % rate) {
+		dev_err(dev, "unsupported clock rate\n");
+		return -EINVAL;
+	}
+
+	clk_set_parent(ick, xck);
+	clk_set_rate(ick, xrate);
+
+	bpfmd = fsi->chan_num * 32;
+	ackmd = xrate / rate;
+
+	dev_dbg(dev, "external/rate = %ld/%ld\n", xrate, rate);
+
+	ret = fsi_clk_set_ackbpf(dev, fsi, ackmd, bpfmd);
+	if (ret < 0)
+		dev_err(dev, "%s failed", __func__);
+
+	return ret;
+}
+
+static int fsi_clk_set_rate_cpg(struct device *dev,
+				struct fsi_priv *fsi,
+				unsigned long rate)
+{
+	struct clk *ick = fsi->clock.ick;
+	struct clk *div = fsi->clock.div;
+	unsigned long target = 0; /* 12288000 or 11289600 */
+	unsigned long actual, cout;
+	unsigned long diff, min;
+	unsigned long best_cout, best_act;
+	int adj;
+	int ackmd, bpfmd;
+	int ret = -EINVAL;
+
+	if (!(12288000 % rate))
+		target = 12288000;
+	if (!(11289600 % rate))
+		target = 11289600;
+	if (!target) {
+		dev_err(dev, "unsupported rate\n");
+		return ret;
+	}
+
+	bpfmd = fsi->chan_num * 32;
+	ackmd = target / rate;
+	ret = fsi_clk_set_ackbpf(dev, fsi, ackmd, bpfmd);
+	if (ret < 0) {
+		dev_err(dev, "%s failed", __func__);
+		return ret;
+	}
+
+	/*
+	 * The clock flow is
+	 *
+	 * [CPG] = cout => [FSI_DIV] = audio => [FSI] => [codec]
+	 *
+	 * But, it needs to find best match of CPG and FSI_DIV
+	 * combination, since it is difficult to generate correct
+	 * frequency of audio clock from ick clock only.
+	 * Because ick is created from its parent clock.
+	 *
+	 * target	= rate x [512/256/128/64]fs
+	 * cout		= round(target x adjustment)
+	 * actual	= cout / adjustment (by FSI-DIV) ~= target
+	 * audio	= actual
+	 */
+	min = ~0;
+	best_cout = 0;
+	best_act = 0;
+	for (adj = 1; adj < 0xffff; adj++) {
+
+		cout = target * adj;
+		if (cout > 100000000) /* max clock = 100MHz */
+			break;
+
+		/* cout/actual audio clock */
+		cout	= clk_round_rate(ick, cout);
+		actual	= cout / adj;
+
+		/* find best frequency */
+		diff = abs(actual - target);
+		if (diff < min) {
+			min		= diff;
+			best_cout	= cout;
+			best_act	= actual;
+		}
+	}
+
+	ret = clk_set_rate(ick, best_cout);
+	if (ret < 0) {
+		dev_err(dev, "ick clock failed\n");
+		return -EIO;
+	}
+
+	ret = clk_set_rate(div, clk_round_rate(div, best_act));
+	if (ret < 0) {
+		dev_err(dev, "div clock failed\n");
+		return -EIO;
+	}
+
+	dev_dbg(dev, "ick/div = %ld/%ld\n",
+		clk_get_rate(ick), clk_get_rate(div));
+
+	return ret;
+}
+
 static int fsi_set_master_clk(struct device *dev, struct fsi_priv *fsi,
 			      long rate, int enable)
 {
 	set_rate_func set_rate = fsi_get_info_set_rate(fsi);
 	int ret;
 
-	if (!set_rate)
-		return 0;
+	/*
+	 * CAUTION
+	 *
+	 * set_rate will be deleted
+	 */
+	if (!set_rate) {
+		if (enable)
+			return fsi_clk_enable(dev, fsi, rate);
+		else
+			return fsi_clk_disable(dev, fsi);
+	}
 
 	ret = set_rate(dev, rate, enable);
 	if (ret < 0) /* error */
@@ -792,10 +1147,9 @@
  */
 static void fsi_pio_push16(struct fsi_priv *fsi, u8 *_buf, int samples)
 {
-	u32 enable_stream = fsi_get_info_flags(fsi) & SH_FSI_ENABLE_STREAM_MODE;
 	int i;
 
-	if (enable_stream) {
+	if (fsi_is_enable_stream(fsi)) {
 		/*
 		 * stream mode
 		 * see
@@ -953,8 +1307,6 @@
 
 static int fsi_pio_push_init(struct fsi_priv *fsi, struct fsi_stream *io)
 {
-	u32 enable_stream = fsi_get_info_flags(fsi) & SH_FSI_ENABLE_STREAM_MODE;
-
 	/*
 	 * we can use 16bit stream mode
 	 * when "playback" and "16bit data"
@@ -962,7 +1314,7 @@
 	 * see
 	 *	fsi_pio_push16()
 	 */
-	if (enable_stream)
+	if (fsi_is_enable_stream(fsi))
 		io->bus_option = BUSOP_SET(24, PACKAGE_24BITBUS_BACK) |
 				 BUSOP_SET(16, PACKAGE_16BITBUS_STREAM);
 	else
@@ -1296,6 +1648,16 @@
 
 	/* clock inversion (CKG2) */
 	data = 0;
+	if (fsi->bit_clk_inv)
+		data |= (1 << 0);
+	if (fsi->lr_clk_inv)
+		data |= (1 << 4);
+	if (fsi_is_clk_master(fsi))
+		data <<= 8;
+	/* FIXME
+	 *
+	 * SH_FSI_xxx_INV style will be removed
+	 */
 	if (SH_FSI_LRM_INV & flags)
 		data |= 1 << 12;
 	if (SH_FSI_BRM_INV & flags)
@@ -1334,14 +1696,21 @@
 	/* fifo init */
 	fsi_fifo_init(fsi, io, dev);
 
+	/* start master clock */
+	if (fsi_is_clk_master(fsi))
+		return fsi_set_master_clk(dev, fsi, fsi->rate, 1);
+
 	return 0;
 }
 
-static void fsi_hw_shutdown(struct fsi_priv *fsi,
+static int fsi_hw_shutdown(struct fsi_priv *fsi,
 			    struct device *dev)
 {
+	/* stop master clock */
 	if (fsi_is_clk_master(fsi))
-		fsi_set_master_clk(dev, fsi, fsi->rate, 0);
+		return fsi_set_master_clk(dev, fsi, fsi->rate, 0);
+
+	return 0;
 }
 
 static int fsi_dai_startup(struct snd_pcm_substream *substream,
@@ -1349,6 +1718,7 @@
 {
 	struct fsi_priv *fsi = fsi_get_priv(substream);
 
+	fsi_clk_invalid(fsi);
 	fsi->rate = 0;
 
 	return 0;
@@ -1359,6 +1729,7 @@
 {
 	struct fsi_priv *fsi = fsi_get_priv(substream);
 
+	fsi_clk_invalid(fsi);
 	fsi->rate = 0;
 }
 
@@ -1372,13 +1743,16 @@
 	switch (cmd) {
 	case SNDRV_PCM_TRIGGER_START:
 		fsi_stream_init(fsi, io, substream);
-		fsi_hw_startup(fsi, io, dai->dev);
-		ret = fsi_stream_transfer(io);
-		if (0 == ret)
+		if (!ret)
+			ret = fsi_hw_startup(fsi, io, dai->dev);
+		if (!ret)
+			ret = fsi_stream_transfer(io);
+		if (!ret)
 			fsi_stream_start(fsi, io);
 		break;
 	case SNDRV_PCM_TRIGGER_STOP:
-		fsi_hw_shutdown(fsi, dai->dev);
+		if (!ret)
+			ret = fsi_hw_shutdown(fsi, dai->dev);
 		fsi_stream_stop(fsi, io);
 		fsi_stream_quit(fsi, io);
 		break;
@@ -1414,7 +1788,6 @@
 
 	fsi->fmt = CR_DTMD_SPDIF_PCM | CR_PCM;
 	fsi->chan_num = 2;
-	fsi->spdif = 1;
 
 	return 0;
 }
@@ -1423,7 +1796,6 @@
 {
 	struct fsi_priv *fsi = fsi_get_priv_frm_dai(dai);
 	set_rate_func set_rate = fsi_get_info_set_rate(fsi);
-	u32 flags = fsi_get_info_flags(fsi);
 	int ret;
 
 	/* set master/slave audio interface */
@@ -1437,22 +1809,49 @@
 		return -EINVAL;
 	}
 
-	if (fsi_is_clk_master(fsi) && !set_rate) {
-		dev_err(dai->dev, "platform doesn't have set_rate\n");
-		return -EINVAL;
+	/* set clock inversion */
+	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+	case SND_SOC_DAIFMT_NB_IF:
+		fsi->bit_clk_inv = 0;
+		fsi->lr_clk_inv = 1;
+		break;
+	case SND_SOC_DAIFMT_IB_NF:
+		fsi->bit_clk_inv = 1;
+		fsi->lr_clk_inv = 0;
+		break;
+	case SND_SOC_DAIFMT_IB_IF:
+		fsi->bit_clk_inv = 1;
+		fsi->lr_clk_inv = 1;
+		break;
+	case SND_SOC_DAIFMT_NB_NF:
+	default:
+		fsi->bit_clk_inv = 0;
+		fsi->lr_clk_inv = 0;
+		break;
+	}
+
+	if (fsi_is_clk_master(fsi)) {
+		/*
+		 * CAUTION
+		 *
+		 * set_rate will be deleted
+		 */
+		if (set_rate)
+			dev_warn(dai->dev, "set_rate will be removed soon\n");
+
+		if (fsi->clk_cpg)
+			fsi_clk_init(dai->dev, fsi, 0, 1, 1,
+				     fsi_clk_set_rate_cpg);
+		else
+			fsi_clk_init(dai->dev, fsi, 1, 1, 0,
+				     fsi_clk_set_rate_external);
 	}
 
 	/* set format */
-	switch (flags & SH_FSI_FMT_MASK) {
-	case SH_FSI_FMT_DAI:
-		ret = fsi_set_fmt_dai(fsi, fmt & SND_SOC_DAIFMT_FORMAT_MASK);
-		break;
-	case SH_FSI_FMT_SPDIF:
+	if (fsi_is_spdif(fsi))
 		ret = fsi_set_fmt_spdif(fsi);
-		break;
-	default:
-		ret = -EINVAL;
-	}
+	else
+		ret = fsi_set_fmt_dai(fsi, fmt & SND_SOC_DAIFMT_FORMAT_MASK);
 
 	return ret;
 }
@@ -1462,19 +1861,13 @@
 			     struct snd_soc_dai *dai)
 {
 	struct fsi_priv *fsi = fsi_get_priv(substream);
-	long rate = params_rate(params);
-	int ret;
 
-	if (!fsi_is_clk_master(fsi))
-		return 0;
+	if (fsi_is_clk_master(fsi)) {
+		fsi->rate = params_rate(params);
+		fsi_clk_valid(fsi, fsi->rate);
+	}
 
-	ret = fsi_set_master_clk(dai->dev, fsi, rate, 1);
-	if (ret < 0)
-		return ret;
-
-	fsi->rate = rate;
-
-	return ret;
+	return 0;
 }
 
 static const struct snd_soc_dai_ops fsi_dai_ops = {
@@ -1498,7 +1891,7 @@
 	.rates			= FSI_RATES,
 	.rate_min		= 8000,
 	.rate_max		= 192000,
-	.channels_min		= 1,
+	.channels_min		= 2,
 	.channels_max		= 2,
 	.buffer_bytes_max	= 64 * 1024,
 	.period_bytes_min	= 32,
@@ -1586,14 +1979,14 @@
 		.playback = {
 			.rates		= FSI_RATES,
 			.formats	= FSI_FMTS,
-			.channels_min	= 1,
-			.channels_max	= 8,
+			.channels_min	= 2,
+			.channels_max	= 2,
 		},
 		.capture = {
 			.rates		= FSI_RATES,
 			.formats	= FSI_FMTS,
-			.channels_min	= 1,
-			.channels_max	= 8,
+			.channels_min	= 2,
+			.channels_max	= 2,
 		},
 		.ops = &fsi_dai_ops,
 	},
@@ -1602,14 +1995,14 @@
 		.playback = {
 			.rates		= FSI_RATES,
 			.formats	= FSI_FMTS,
-			.channels_min	= 1,
-			.channels_max	= 8,
+			.channels_min	= 2,
+			.channels_max	= 2,
 		},
 		.capture = {
 			.rates		= FSI_RATES,
 			.formats	= FSI_FMTS,
-			.channels_min	= 1,
-			.channels_max	= 8,
+			.channels_min	= 2,
+			.channels_max	= 2,
 		},
 		.ops = &fsi_dai_ops,
 	},
@@ -1624,15 +2017,29 @@
 /*
  *		platform function
  */
-static void fsi_handler_init(struct fsi_priv *fsi)
+static void fsi_port_info_init(struct fsi_priv *fsi,
+			       struct sh_fsi_port_info *info)
+{
+	if (info->flags & SH_FSI_FMT_SPDIF)
+		fsi->spdif = 1;
+
+	if (info->flags & SH_FSI_CLK_CPG)
+		fsi->clk_cpg = 1;
+
+	if (info->flags & SH_FSI_ENABLE_STREAM_MODE)
+		fsi->enable_stream = 1;
+}
+
+static void fsi_handler_init(struct fsi_priv *fsi,
+			     struct sh_fsi_port_info *info)
 {
 	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.shdma_slave.slave_id = fsi->info->tx_id;
+	if (info->tx_id) {
+		fsi->playback.slave.shdma_slave.slave_id = info->tx_id;
 		fsi->playback.handler = &fsi_dma_push_handler;
 	}
 }
@@ -1642,10 +2049,16 @@
 	struct fsi_master *master;
 	const struct platform_device_id	*id_entry;
 	struct sh_fsi_platform_info *info = pdev->dev.platform_data;
+	struct sh_fsi_port_info nul_info, *pinfo;
+	struct fsi_priv *fsi;
 	struct resource *res;
 	unsigned int irq;
 	int ret;
 
+	nul_info.flags	= 0;
+	nul_info.tx_id	= 0;
+	nul_info.rx_id	= 0;
+
 	id_entry = pdev->id_entry;
 	if (!id_entry) {
 		dev_err(&pdev->dev, "unknown fsi device\n");
@@ -1678,22 +2091,28 @@
 	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, &pdev->dev);
+	pinfo		= (info) ? &info->port_a : &nul_info;
+	fsi		= &master->fsia;
+	fsi->base	= master->base;
+	fsi->master	= master;
+	fsi->info	= pinfo;
+	fsi_port_info_init(fsi, pinfo);
+	fsi_handler_init(fsi, pinfo);
+	ret = fsi_stream_probe(fsi, &pdev->dev);
 	if (ret < 0) {
 		dev_err(&pdev->dev, "FSIA stream probe failed\n");
 		return ret;
 	}
 
 	/* 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, &pdev->dev);
+	pinfo		= (info) ? &info->port_b : &nul_info;
+	fsi		= &master->fsib;
+	fsi->base	= master->base + 0x40;
+	fsi->master	= master;
+	fsi->info	= pinfo;
+	fsi_port_info_init(fsi, pinfo);
+	fsi_handler_init(fsi, pinfo);
+	ret = fsi_stream_probe(fsi, &pdev->dev);
 	if (ret < 0) {
 		dev_err(&pdev->dev, "FSIB stream probe failed\n");
 		goto exit_fsia;
@@ -1702,7 +2121,7 @@
 	pm_runtime_enable(&pdev->dev);
 	dev_set_drvdata(&pdev->dev, master);
 
-	ret = request_irq(irq, &fsi_interrupt, 0,
+	ret = devm_request_irq(&pdev->dev, irq, &fsi_interrupt, 0,
 			  id_entry->name, master);
 	if (ret) {
 		dev_err(&pdev->dev, "irq request err\n");
@@ -1712,7 +2131,7 @@
 	ret = snd_soc_register_platform(&pdev->dev, &fsi_soc_platform);
 	if (ret < 0) {
 		dev_err(&pdev->dev, "cannot snd soc register\n");
-		goto exit_free_irq;
+		goto exit_fsib;
 	}
 
 	ret = snd_soc_register_dais(&pdev->dev, fsi_soc_dai,
@@ -1726,8 +2145,6 @@
 
 exit_snd_soc:
 	snd_soc_unregister_platform(&pdev->dev);
-exit_free_irq:
-	free_irq(irq, master);
 exit_fsib:
 	pm_runtime_disable(&pdev->dev);
 	fsi_stream_remove(&master->fsib);
@@ -1743,7 +2160,6 @@
 
 	master = dev_get_drvdata(&pdev->dev);
 
-	free_irq(master->irq, master);
 	pm_runtime_disable(&pdev->dev);
 
 	snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(fsi_soc_dai));
@@ -1774,10 +2190,6 @@
 		return;
 
 	fsi_hw_startup(fsi, io, dev);
-
-	if (fsi_is_clk_master(fsi) && fsi->rate)
-		fsi_set_master_clk(dev, fsi, fsi->rate, 1);
-
 	fsi_stream_start(fsi, io);
 }
 
diff --git a/sound/soc/sh/hac.c b/sound/soc/sh/hac.c
index 3474d7b..4cc2d64 100644
--- a/sound/soc/sh/hac.c
+++ b/sound/soc/sh/hac.c
@@ -310,13 +310,13 @@
 #endif
 };
 
-static int __devinit hac_soc_platform_probe(struct platform_device *pdev)
+static int hac_soc_platform_probe(struct platform_device *pdev)
 {
 	return snd_soc_register_dais(&pdev->dev, sh4_hac_dai,
 			ARRAY_SIZE(sh4_hac_dai));
 }
 
-static int __devexit hac_soc_platform_remove(struct platform_device *pdev)
+static int hac_soc_platform_remove(struct platform_device *pdev)
 {
 	snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(sh4_hac_dai));
 	return 0;
@@ -329,7 +329,7 @@
 	},
 
 	.probe = hac_soc_platform_probe,
-	.remove = __devexit_p(hac_soc_platform_remove),
+	.remove = hac_soc_platform_remove,
 };
 
 module_platform_driver(hac_pcm_driver);
diff --git a/sound/soc/sh/siu_dai.c b/sound/soc/sh/siu_dai.c
index 52d4c17..34facdc 100644
--- a/sound/soc/sh/siu_dai.c
+++ b/sound/soc/sh/siu_dai.c
@@ -726,7 +726,7 @@
 	.ops = &siu_dai_ops,
 };
 
-static int __devinit siu_probe(struct platform_device *pdev)
+static int siu_probe(struct platform_device *pdev)
 {
 	const struct firmware *fw_entry;
 	struct resource *res, *region;
@@ -815,7 +815,7 @@
 	return ret;
 }
 
-static int __devexit siu_remove(struct platform_device *pdev)
+static int siu_remove(struct platform_device *pdev)
 {
 	struct siu_info *info = dev_get_drvdata(&pdev->dev);
 	struct resource *res;
@@ -843,7 +843,7 @@
 		.name	= "siu-pcm-audio",
 	},
 	.probe		= siu_probe,
-	.remove		= __devexit_p(siu_remove),
+	.remove		= siu_remove,
 };
 
 module_platform_driver(siu_driver);
diff --git a/sound/soc/sh/ssi.c b/sound/soc/sh/ssi.c
index ff82b56..c8e73a7 100644
--- a/sound/soc/sh/ssi.c
+++ b/sound/soc/sh/ssi.c
@@ -379,13 +379,13 @@
 #endif
 };
 
-static int __devinit sh4_soc_dai_probe(struct platform_device *pdev)
+static int sh4_soc_dai_probe(struct platform_device *pdev)
 {
 	return snd_soc_register_dais(&pdev->dev, sh4_ssi_dai,
 			ARRAY_SIZE(sh4_ssi_dai));
 }
 
-static int __devexit sh4_soc_dai_remove(struct platform_device *pdev)
+static int sh4_soc_dai_remove(struct platform_device *pdev)
 {
 	snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(sh4_ssi_dai));
 	return 0;
@@ -398,7 +398,7 @@
 	},
 
 	.probe = sh4_soc_dai_probe,
-	.remove = __devexit_p(sh4_soc_dai_remove),
+	.remove = sh4_soc_dai_remove,
 };
 
 module_platform_driver(sh4_ssi_driver);
diff --git a/sound/soc/soc-cache.c b/sound/soc/soc-cache.c
index 9d56f02..e72f554 100644
--- a/sound/soc/soc-cache.c
+++ b/sound/soc/soc-cache.c
@@ -88,7 +88,7 @@
 		ret = snd_soc_write(codec, i, val);
 		if (ret)
 			return ret;
-		dev_dbg(codec->dev, "Synced register %#x, value = %#x\n",
+		dev_dbg(codec->dev, "ASoC: Synced register %#x, value = %#x\n",
 			i, val);
 	}
 	return 0;
@@ -156,7 +156,7 @@
 
 	/* Fall back to flat compression */
 	if (i == ARRAY_SIZE(cache_types)) {
-		dev_warn(codec->dev, "Could not match compress type: %d\n",
+		dev_warn(codec->dev, "ASoC: Could not match compress type: %d\n",
 			 codec->compress_type);
 		i = 0;
 	}
@@ -166,7 +166,7 @@
 
 	if (codec->cache_ops->init) {
 		if (codec->cache_ops->name)
-			dev_dbg(codec->dev, "Initializing %s cache for %s codec\n",
+			dev_dbg(codec->dev, "ASoC: Initializing %s cache for %s codec\n",
 				codec->cache_ops->name, codec->name);
 		return codec->cache_ops->init(codec);
 	}
@@ -181,7 +181,7 @@
 {
 	if (codec->cache_ops && codec->cache_ops->exit) {
 		if (codec->cache_ops->name)
-			dev_dbg(codec->dev, "Destroying %s cache for %s codec\n",
+			dev_dbg(codec->dev, "ASoC: Destroying %s cache for %s codec\n",
 				codec->cache_ops->name, codec->name);
 		return codec->cache_ops->exit(codec);
 	}
@@ -265,7 +265,7 @@
 		name = "unknown";
 
 	if (codec->cache_ops->name)
-		dev_dbg(codec->dev, "Syncing %s cache for %s codec\n",
+		dev_dbg(codec->dev, "ASoC: Syncing %s cache for %s codec\n",
 			codec->cache_ops->name, codec->name);
 	trace_snd_soc_cache_sync(codec, name, "start");
 	ret = codec->cache_ops->sync(codec);
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 10d21be..9c768bc 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -271,7 +271,8 @@
 	codec->debugfs_codec_root = debugfs_create_dir(codec->name,
 						       debugfs_card_root);
 	if (!codec->debugfs_codec_root) {
-		dev_warn(codec->dev, "Failed to create codec debugfs directory\n");
+		dev_warn(codec->dev, "ASoC: Failed to create codec debugfs"
+			" directory\n");
 		return;
 	}
 
@@ -284,7 +285,8 @@
 						 codec->debugfs_codec_root,
 						 codec, &codec_reg_fops);
 	if (!codec->debugfs_reg)
-		dev_warn(codec->dev, "Failed to create codec register debugfs file\n");
+		dev_warn(codec->dev, "ASoC: Failed to create codec register"
+			" debugfs file\n");
 
 	snd_soc_dapm_debugfs_init(&codec->dapm, codec->debugfs_codec_root);
 }
@@ -302,7 +304,7 @@
 						       debugfs_card_root);
 	if (!platform->debugfs_platform_root) {
 		dev_warn(platform->dev,
-			"Failed to create platform debugfs directory\n");
+			"ASoC: Failed to create platform debugfs directory\n");
 		return;
 	}
 
@@ -430,7 +432,7 @@
 						    &card->pop_time);
 	if (!card->debugfs_pop_time)
 		dev_warn(card->dev,
-		       "Failed to create pop time debugfs file\n");
+		       "ASoC: Failed to create pop time debugfs file\n");
 }
 
 static void soc_cleanup_card_debugfs(struct snd_soc_card *card)
@@ -475,7 +477,7 @@
 			!strcmp(card->rtd[i].dai_link->name, dai_link))
 			return card->rtd[i].pcm->streams[stream].substream;
 	}
-	dev_dbg(card->dev, "failed to find dai link %s\n", dai_link);
+	dev_dbg(card->dev, "ASoC: failed to find dai link %s\n", dai_link);
 	return NULL;
 }
 EXPORT_SYMBOL_GPL(snd_soc_get_dai_substream);
@@ -489,7 +491,7 @@
 		if (!strcmp(card->rtd[i].dai_link->name, dai_link))
 			return &card->rtd[i];
 	}
-	dev_dbg(card->dev, "failed to find rtd %s\n", dai_link);
+	dev_dbg(card->dev, "ASoC: failed to find rtd %s\n", dai_link);
 	return NULL;
 }
 EXPORT_SYMBOL_GPL(snd_soc_get_pcm_runtime);
@@ -519,7 +521,7 @@
 		     codec->card->snd_card->number, 0, codec->name);
 	err = device_register(&codec->ac97->dev);
 	if (err < 0) {
-		snd_printk(KERN_ERR "Can't register ac97 bus\n");
+		dev_err(codec->dev, "ASoC: Can't register ac97 bus\n");
 		codec->ac97->dev.bus = NULL;
 		return err;
 	}
@@ -628,7 +630,8 @@
 				 */
 				if (codec->dapm.idle_bias_off) {
 					dev_dbg(codec->dev,
-						"idle_bias_off CODEC on over suspend\n");
+						"ASoC: idle_bias_off CODEC on"
+						" over suspend\n");
 					break;
 				}
 			case SND_SOC_BIAS_OFF:
@@ -639,7 +642,8 @@
 					regcache_mark_dirty(codec->control_data);
 				break;
 			default:
-				dev_dbg(codec->dev, "CODEC is on over suspend\n");
+				dev_dbg(codec->dev, "ASoC: CODEC is on"
+					" over suspend\n");
 				break;
 			}
 		}
@@ -676,7 +680,7 @@
 	 * so userspace apps are blocked from touching us
 	 */
 
-	dev_dbg(card->dev, "starting resume work\n");
+	dev_dbg(card->dev, "ASoC: starting resume work\n");
 
 	/* Bring us up into D2 so that DAPM starts enabling things */
 	snd_power_change_state(card->snd_card, SNDRV_CTL_POWER_D2);
@@ -708,7 +712,8 @@
 				codec->suspended = 0;
 				break;
 			default:
-				dev_dbg(codec->dev, "CODEC was on over suspend\n");
+				dev_dbg(codec->dev, "ASoC: CODEC was on over"
+					" suspend\n");
 				break;
 			}
 		}
@@ -758,7 +763,7 @@
 	if (card->resume_post)
 		card->resume_post(card);
 
-	dev_dbg(card->dev, "resume work completed\n");
+	dev_dbg(card->dev, "ASoC: resume work completed\n");
 
 	/* userspace can access us now we are back as we were before */
 	snd_power_change_state(card->snd_card, SNDRV_CTL_POWER_D0);
@@ -790,12 +795,12 @@
 		ac97_control |= cpu_dai->driver->ac97_control;
 	}
 	if (ac97_control) {
-		dev_dbg(dev, "Resuming AC97 immediately\n");
+		dev_dbg(dev, "ASoC: Resuming AC97 immediately\n");
 		soc_resume_deferred(&card->deferred_resume_work);
 	} else {
-		dev_dbg(dev, "Scheduling resume work\n");
+		dev_dbg(dev, "ASoC: Scheduling resume work\n");
 		if (!schedule_work(&card->deferred_resume_work))
-			dev_err(dev, "resume work item may be lost\n");
+			dev_err(dev, "ASoC: resume work item may be lost\n");
 	}
 
 	return 0;
@@ -818,7 +823,7 @@
 	struct snd_soc_dai *codec_dai, *cpu_dai;
 	const char *platform_name;
 
-	dev_dbg(card->dev, "binding %s at idx %d\n", dai_link->name, num);
+	dev_dbg(card->dev, "ASoC: binding %s at idx %d\n", dai_link->name, num);
 
 	/* Find CPU DAI from registered DAIs*/
 	list_for_each_entry(cpu_dai, &dai_list, list) {
@@ -836,7 +841,7 @@
 	}
 
 	if (!rtd->cpu_dai) {
-		dev_err(card->dev, "CPU DAI %s not registered\n",
+		dev_err(card->dev, "ASoC: CPU DAI %s not registered\n",
 			dai_link->cpu_dai_name);
 		return -EPROBE_DEFER;
 	}
@@ -867,14 +872,14 @@
 		}
 
 		if (!rtd->codec_dai) {
-			dev_err(card->dev, "CODEC DAI %s not registered\n",
+			dev_err(card->dev, "ASoC: CODEC DAI %s not registered\n",
 				dai_link->codec_dai_name);
 			return -EPROBE_DEFER;
 		}
 	}
 
 	if (!rtd->codec) {
-		dev_err(card->dev, "CODEC %s not registered\n",
+		dev_err(card->dev, "ASoC: CODEC %s not registered\n",
 			dai_link->codec_name);
 		return -EPROBE_DEFER;
 	}
@@ -898,7 +903,7 @@
 		rtd->platform = platform;
 	}
 	if (!rtd->platform) {
-		dev_err(card->dev, "platform %s not registered\n",
+		dev_err(card->dev, "ASoC: platform %s not registered\n",
 			dai_link->platform_name);
 		return -EPROBE_DEFER;
 	}
@@ -915,8 +920,8 @@
 	if (platform->driver->remove) {
 		ret = platform->driver->remove(platform);
 		if (ret < 0)
-			pr_err("asoc: failed to remove %s: %d\n",
-				platform->name, ret);
+			dev_err(platform->dev, "ASoC: failed to remove %d\n",
+				ret);
 	}
 
 	/* Make sure all DAPM widgets are freed */
@@ -937,9 +942,7 @@
 	if (codec->driver->remove) {
 		err = codec->driver->remove(codec);
 		if (err < 0)
-			dev_err(codec->dev,
-				"asoc: failed to remove %s: %d\n",
-				codec->name, err);
+			dev_err(codec->dev, "ASoC: failed to remove %d\n", err);
 	}
 
 	/* Make sure all DAPM widgets are freed */
@@ -971,8 +974,9 @@
 		if (codec_dai->driver->remove) {
 			err = codec_dai->driver->remove(codec_dai);
 			if (err < 0)
-				pr_err("asoc: failed to remove %s: %d\n",
-							codec_dai->name, err);
+				dev_err(codec_dai->dev,
+					"ASoC: failed to remove %s: %d\n",
+					codec_dai->name, err);
 		}
 		codec_dai->probed = 0;
 		list_del(&codec_dai->card_list);
@@ -984,8 +988,9 @@
 		if (cpu_dai->driver->remove) {
 			err = cpu_dai->driver->remove(cpu_dai);
 			if (err < 0)
-				pr_err("asoc: failed to remove %s: %d\n",
-							cpu_dai->name, err);
+				dev_err(cpu_dai->dev,
+					"ASoC: failed to remove %s: %d\n",
+					cpu_dai->name, err);
 		}
 		cpu_dai->probed = 0;
 		list_del(&cpu_dai->card_list);
@@ -1099,8 +1104,7 @@
 		ret = driver->probe(codec);
 		if (ret < 0) {
 			dev_err(codec->dev,
-				"asoc: failed to probe CODEC %s: %d\n",
-				codec->name, ret);
+				"ASoC: failed to probe CODEC %d\n", ret);
 			goto err_probe;
 		}
 	}
@@ -1163,8 +1167,7 @@
 		ret = driver->probe(platform);
 		if (ret < 0) {
 			dev_err(platform->dev,
-				"asoc: failed to probe platform %s: %d\n",
-				platform->name, ret);
+				"ASoC: failed to probe platform %d\n", ret);
 			goto err_probe;
 		}
 	}
@@ -1229,7 +1232,7 @@
 	else if (dailess && aux_dev->init)
 		ret = aux_dev->init(&codec->dapm);
 	if (ret < 0) {
-		dev_err(card->dev, "asoc: failed to init %s: %d\n", name, ret);
+		dev_err(card->dev, "ASoC: failed to init %s: %d\n", name, ret);
 		return ret;
 	}
 	codec->name_prefix = temp;
@@ -1253,7 +1256,7 @@
 	ret = device_add(rtd->dev);
 	if (ret < 0) {
 		dev_err(card->dev,
-			"asoc: failed to register runtime device: %d\n", ret);
+			"ASoC: failed to register runtime device: %d\n", ret);
 		return ret;
 	}
 	rtd->dev_registered = 1;
@@ -1262,14 +1265,13 @@
 	ret = snd_soc_dapm_sys_add(rtd->dev);
 	if (ret < 0)
 		dev_err(codec->dev,
-			"asoc: failed to add codec dapm sysfs entries: %d\n",
-			ret);
+			"ASoC: failed to add codec dapm sysfs entries: %d\n", ret);
 
 	/* add codec sysfs entries */
 	ret = device_create_file(rtd->dev, &dev_attr_codec_reg);
 	if (ret < 0)
 		dev_err(codec->dev,
-			"asoc: failed to add codec sysfs files: %d\n", ret);
+			"ASoC: failed to add codec sysfs files: %d\n", ret);
 
 #ifdef CONFIG_DEBUG_FS
 	/* add DPCM sysfs entries */
@@ -1278,7 +1280,7 @@
 
 	ret = soc_dpcm_debugfs_add(rtd);
 	if (ret < 0)
-		dev_err(rtd->dev, "asoc: failed to add dpcm sysfs entries: %d\n", ret);
+		dev_err(rtd->dev, "ASoC: failed to add dpcm sysfs entries: %d\n", ret);
 
 out:
 #endif
@@ -1333,7 +1335,7 @@
 	struct snd_soc_dapm_widget *play_w, *capture_w;
 	int ret;
 
-	dev_dbg(card->dev, "probe %s dai link %d late %d\n",
+	dev_dbg(card->dev, "ASoC: probe %s dai link %d late %d\n",
 			card->name, num, order);
 
 	/* config components */
@@ -1359,8 +1361,9 @@
 		if (cpu_dai->driver->probe) {
 			ret = cpu_dai->driver->probe(cpu_dai);
 			if (ret < 0) {
-				pr_err("asoc: failed to probe CPU DAI %s: %d\n",
-							cpu_dai->name, ret);
+				dev_err(cpu_dai->dev,
+					"ASoC: failed to probe CPU DAI %s: %d\n",
+					cpu_dai->name, ret);
 				module_put(cpu_dai->dev->driver->owner);
 				return ret;
 			}
@@ -1375,8 +1378,9 @@
 		if (codec_dai->driver->probe) {
 			ret = codec_dai->driver->probe(codec_dai);
 			if (ret < 0) {
-				pr_err("asoc: failed to probe CODEC DAI %s: %d\n",
-							codec_dai->name, ret);
+				dev_err(codec_dai->dev,
+					"ASoC: failed to probe CODEC DAI %s: %d\n",
+					codec_dai->name, ret);
 				return ret;
 			}
 		}
@@ -1396,13 +1400,14 @@
 
 	ret = device_create_file(rtd->dev, &dev_attr_pmdown_time);
 	if (ret < 0)
-		pr_warn("asoc: failed to add pmdown_time sysfs:%d\n", ret);
+		dev_warn(rtd->dev, "ASoC: failed to add pmdown_time sysfs: %d\n",
+			ret);
 
 	if (cpu_dai->driver->compress_dai) {
 		/*create compress_device"*/
 		ret = soc_new_compress(rtd, num);
 		if (ret < 0) {
-			pr_err("asoc: can't create compress %s\n",
+			dev_err(card->dev, "ASoC: can't create compress %s\n",
 					 dai_link->stream_name);
 			return ret;
 		}
@@ -1412,7 +1417,7 @@
 			/* create the pcm */
 			ret = soc_new_pcm(rtd, num);
 			if (ret < 0) {
-				pr_err("asoc: can't create pcm %s :%d\n",
+				dev_err(card->dev, "ASoC: can't create pcm %s :%d\n",
 				       dai_link->stream_name, ret);
 				return ret;
 			}
@@ -1424,7 +1429,7 @@
 				ret = snd_soc_dapm_new_pcm(card, dai_link->params,
 						   capture_w, play_w);
 				if (ret != 0) {
-					dev_err(card->dev, "Can't link %s to %s: %d\n",
+					dev_err(card->dev, "ASoC: Can't link %s to %s: %d\n",
 						play_w->name, capture_w->name, ret);
 					return ret;
 				}
@@ -1436,7 +1441,7 @@
 				ret = snd_soc_dapm_new_pcm(card, dai_link->params,
 						   capture_w, play_w);
 				if (ret != 0) {
-					dev_err(card->dev, "Can't link %s to %s: %d\n",
+					dev_err(card->dev, "ASoC: Can't link %s to %s: %d\n",
 						play_w->name, capture_w->name, ret);
 					return ret;
 				}
@@ -1473,7 +1478,8 @@
 
 		ret = soc_ac97_dev_register(rtd->codec);
 		if (ret < 0) {
-			pr_err("asoc: AC97 device register failed:%d\n", ret);
+			dev_err(rtd->codec->dev,
+				"ASoC: AC97 device register failed: %d\n", ret);
 			return ret;
 		}
 
@@ -1502,7 +1508,7 @@
 			return 0;
 	}
 
-	dev_err(card->dev, "%s not registered\n", aux_dev->codec_name);
+	dev_err(card->dev, "ASoC: %s not registered\n", aux_dev->codec_name);
 
 	return -EPROBE_DEFER;
 }
@@ -1518,7 +1524,7 @@
 		if (!strcmp(codec->name, aux_dev->codec_name)) {
 			if (codec->probed) {
 				dev_err(codec->dev,
-					"asoc: codec already probed");
+					"ASoC: codec already probed");
 				ret = -EBUSY;
 				goto out;
 			}
@@ -1526,7 +1532,7 @@
 		}
 	}
 	/* codec not found */
-	dev_err(card->dev, "asoc: codec %s not found", aux_dev->codec_name);
+	dev_err(card->dev, "ASoC: codec %s not found", aux_dev->codec_name);
 	return -EPROBE_DEFER;
 
 found:
@@ -1569,8 +1575,8 @@
 		codec->compress_type = compress_type;
 	ret = snd_soc_cache_init(codec);
 	if (ret < 0) {
-		dev_err(codec->dev, "Failed to set cache compression type: %d\n",
-			ret);
+		dev_err(codec->dev, "ASoC: Failed to set cache compression"
+			" type: %d\n", ret);
 		return ret;
 	}
 	codec->cache_init = 1;
@@ -1626,8 +1632,8 @@
 	ret = snd_card_create(SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1,
 			card->owner, 0, &card->snd_card);
 	if (ret < 0) {
-		pr_err("asoc: can't create sound card for card %s: %d\n",
-			card->name, ret);
+		dev_err(card->dev, "ASoC: can't create sound card for"
+			" card %s: %d\n", card->name, ret);
 		goto base_error;
 	}
 	card->snd_card->dev = card->dev;
@@ -1663,8 +1669,9 @@
 		for (i = 0; i < card->num_links; i++) {
 			ret = soc_probe_link_components(card, i, order);
 			if (ret < 0) {
-				pr_err("asoc: failed to instantiate card %s: %d\n",
-				       card->name, ret);
+				dev_err(card->dev,
+					"ASoC: failed to instantiate card %d\n",
+					ret);
 				goto probe_dai_err;
 			}
 		}
@@ -1676,8 +1683,9 @@
 		for (i = 0; i < card->num_links; i++) {
 			ret = soc_probe_link_dais(card, i, order);
 			if (ret < 0) {
-				pr_err("asoc: failed to instantiate card %s: %d\n",
-				       card->name, ret);
+				dev_err(card->dev,
+					"ASoC: failed to instantiate card %d\n",
+					ret);
 				goto probe_dai_err;
 			}
 		}
@@ -1686,8 +1694,9 @@
 	for (i = 0; i < card->num_aux_devs; i++) {
 		ret = soc_probe_aux_dev(card, i);
 		if (ret < 0) {
-			pr_err("asoc: failed to add auxiliary devices %s: %d\n",
-			       card->name, ret);
+			dev_err(card->dev,
+				"ASoC: failed to add auxiliary devices %d\n",
+				ret);
 			goto probe_aux_dev_err;
 		}
 	}
@@ -1712,7 +1721,7 @@
 						  dai_fmt);
 			if (ret != 0 && ret != -ENOTSUPP)
 				dev_warn(card->rtd[i].codec_dai->dev,
-					 "Failed to set DAI format: %d\n",
+					 "ASoC: Failed to set DAI format: %d\n",
 					 ret);
 		}
 
@@ -1723,7 +1732,7 @@
 						  dai_fmt);
 			if (ret != 0 && ret != -ENOTSUPP)
 				dev_warn(card->rtd[i].cpu_dai->dev,
-					 "Failed to set DAI format: %d\n",
+					 "ASoC: Failed to set DAI format: %d\n",
 					 ret);
 		} else if (dai_fmt) {
 			/* Flip the polarity for the "CPU" end */
@@ -1748,7 +1757,7 @@
 						  dai_fmt);
 			if (ret != 0 && ret != -ENOTSUPP)
 				dev_warn(card->rtd[i].cpu_dai->dev,
-					 "Failed to set DAI format: %d\n",
+					 "ASoC: Failed to set DAI format: %d\n",
 					 ret);
 		}
 	}
@@ -1775,7 +1784,7 @@
 	if (card->late_probe) {
 		ret = card->late_probe(card);
 		if (ret < 0) {
-			dev_err(card->dev, "%s late_probe() failed: %d\n",
+			dev_err(card->dev, "ASoC: %s late_probe() failed: %d\n",
 				card->name, ret);
 			goto probe_aux_dev_err;
 		}
@@ -1789,8 +1798,8 @@
 
 	ret = snd_card_register(card->snd_card);
 	if (ret < 0) {
-		pr_err("asoc: failed to register soundcard for %s: %d\n",
-							card->name, ret);
+		dev_err(card->dev, "ASoC: failed to register soundcard %d\n",
+				ret);
 		goto probe_aux_dev_err;
 	}
 
@@ -1799,8 +1808,8 @@
 	for (i = 0; i < card->num_rtd; i++) {
 		ret = soc_register_ac97_dai_link(&card->rtd[i]);
 		if (ret < 0) {
-			pr_err("asoc: failed to register AC97 %s: %d\n",
-							card->name, ret);
+			dev_err(card->dev, "ASoC: failed to register AC97:"
+				" %d\n", ret);
 			while (--i >= 0)
 				soc_unregister_ac97_dai_link(card->rtd[i].codec);
 			goto probe_aux_dev_err;
@@ -1846,7 +1855,7 @@
 		return -EINVAL;
 
 	dev_warn(&pdev->dev,
-		 "ASoC machine %s should use snd_soc_register_card()\n",
+		 "ASoC: machine %s should use snd_soc_register_card()\n",
 		 card->name);
 
 	/* Bodge while we unpick instantiation */
@@ -1996,7 +2005,7 @@
 	unsigned int ret;
 
 	if (!platform->driver->read) {
-		dev_err(platform->dev, "platform has no read back\n");
+		dev_err(platform->dev, "ASoC: platform has no read back\n");
 		return -1;
 	}
 
@@ -2012,7 +2021,7 @@
 					 unsigned int reg, unsigned int val)
 {
 	if (!platform->driver->write) {
-		dev_err(platform->dev, "platform has no write back\n");
+		dev_err(platform->dev, "ASoC: platform has no write back\n");
 		return -1;
 	}
 
@@ -2283,7 +2292,8 @@
 		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);
+			dev_err(dev, "ASoC: Failed to add %s: %d\n",
+				control->name, err);
 			return err;
 		}
 	}
@@ -3534,15 +3544,14 @@
 		 * not both or neither.
 		 */
 		if (!!link->codec_name == !!link->codec_of_node) {
-			dev_err(card->dev,
-				"Neither/both codec name/of_node are set for %s\n",
-				link->name);
+			dev_err(card->dev, "ASoC: Neither/both codec"
+				" name/of_node are set for %s\n", link->name);
 			return -EINVAL;
 		}
 		/* Codec DAI name must be specified */
 		if (!link->codec_dai_name) {
-			dev_err(card->dev, "codec_dai_name not set for %s\n",
-				link->name);
+			dev_err(card->dev, "ASoC: codec_dai_name not"
+				" set for %s\n", link->name);
 			return -EINVAL;
 		}
 
@@ -3551,8 +3560,8 @@
 		 * can be left unspecified, and a dummy platform will be used.
 		 */
 		if (link->platform_name && link->platform_of_node) {
-			dev_err(card->dev,
-				"Both platform name/of_node are set for %s\n", link->name);
+			dev_err(card->dev, "ASoC: Both platform name/of_node"
+				" are set for %s\n", link->name);
 			return -EINVAL;
 		}
 
@@ -3562,9 +3571,8 @@
 		 * name alone..
 		 */
 		if (link->cpu_name && link->cpu_of_node) {
-			dev_err(card->dev,
-				"Neither/both cpu name/of_node are set for %s\n",
-				link->name);
+			dev_err(card->dev, "ASoC: Neither/both "
+				"cpu name/of_node are set for %s\n",link->name);
 			return -EINVAL;
 		}
 		/*
@@ -3573,9 +3581,8 @@
 		 */
 		if (!link->cpu_dai_name &&
 		    !(link->cpu_name || link->cpu_of_node)) {
-			dev_err(card->dev,
-				"Neither cpu_dai_name nor cpu_name/of_node are set for %s\n",
-				link->name);
+			dev_err(card->dev, "ASoC: Neither cpu_dai_name nor "
+				"cpu_name/of_node are set for %s\n", link->name);
 			return -EINVAL;
 		}
 	}
@@ -3622,7 +3629,7 @@
 {
 	if (card->instantiated)
 		soc_cleanup_card_resources(card);
-	dev_dbg(card->dev, "Unregistered card '%s'\n", card->name);
+	dev_dbg(card->dev, "ASoC: Unregistered card '%s'\n", card->name);
 
 	return 0;
 }
@@ -3679,8 +3686,8 @@
 		struct snd_soc_dai_driver *dai_drv)
 {
 	if (dai_drv->name == NULL) {
-		pr_err("asoc: error - multiple DAI %s registered with no name\n",
-				dev_name(dev));
+		dev_err(dev, "ASoC: error - multiple DAI %s registered with"
+				" no name\n", dev_name(dev));
 		return NULL;
 	}
 
@@ -3698,7 +3705,7 @@
 	struct snd_soc_codec *codec;
 	struct snd_soc_dai *dai;
 
-	dev_dbg(dev, "dai register %s\n", dev_name(dev));
+	dev_dbg(dev, "ASoC: dai register %s\n", dev_name(dev));
 
 	dai = kzalloc(sizeof(struct snd_soc_dai), GFP_KERNEL);
 	if (dai == NULL)
@@ -3721,7 +3728,7 @@
 
 	list_for_each_entry(codec, &codec_list, list) {
 		if (codec->dev == dev) {
-			dev_dbg(dev, "Mapped DAI %s to CODEC %s\n",
+			dev_dbg(dev, "ASoC: Mapped DAI %s to CODEC %s\n",
 				dai->name, codec->name);
 			dai->codec = codec;
 			break;
@@ -3735,7 +3742,7 @@
 
 	mutex_unlock(&client_mutex);
 
-	pr_debug("Registered DAI '%s'\n", dai->name);
+	dev_dbg(dev, "ASoC: Registered DAI '%s'\n", dai->name);
 
 	return 0;
 }
@@ -3761,7 +3768,7 @@
 	list_del(&dai->list);
 	mutex_unlock(&client_mutex);
 
-	pr_debug("Unregistered DAI '%s'\n", dai->name);
+	dev_dbg(dev, "ASoC: Unregistered DAI '%s'\n", dai->name);
 	kfree(dai->name);
 	kfree(dai);
 }
@@ -3780,7 +3787,7 @@
 	struct snd_soc_dai *dai;
 	int i, ret = 0;
 
-	dev_dbg(dev, "dai register %s #%Zu\n", dev_name(dev), count);
+	dev_dbg(dev, "ASoC: dai register %s #%Zu\n", dev_name(dev), count);
 
 	for (i = 0; i < count; i++) {
 
@@ -3812,8 +3819,8 @@
 
 		list_for_each_entry(codec, &codec_list, list) {
 			if (codec->dev == dev) {
-				dev_dbg(dev, "Mapped DAI %s to CODEC %s\n",
-					dai->name, codec->name);
+				dev_dbg(dev, "ASoC: Mapped DAI %s to "
+					"CODEC %s\n", dai->name, codec->name);
 				dai->codec = codec;
 				break;
 			}
@@ -3826,7 +3833,7 @@
 
 		mutex_unlock(&client_mutex);
 
-		pr_debug("Registered DAI '%s'\n", dai->name);
+		dev_dbg(dai->dev, "ASoC: Registered DAI '%s'\n", dai->name);
 	}
 
 	return 0;
@@ -3864,7 +3871,7 @@
 {
 	struct snd_soc_platform *platform;
 
-	dev_dbg(dev, "platform register %s\n", dev_name(dev));
+	dev_dbg(dev, "ASoC: platform register %s\n", dev_name(dev));
 
 	platform = kzalloc(sizeof(struct snd_soc_platform), GFP_KERNEL);
 	if (platform == NULL)
@@ -3888,7 +3895,7 @@
 	list_add(&platform->list, &platform_list);
 	mutex_unlock(&client_mutex);
 
-	pr_debug("Registered platform '%s'\n", platform->name);
+	dev_dbg(dev, "ASoC: Registered platform '%s'\n", platform->name);
 
 	return 0;
 }
@@ -3914,7 +3921,7 @@
 	list_del(&platform->list);
 	mutex_unlock(&client_mutex);
 
-	pr_debug("Unregistered platform '%s'\n", platform->name);
+	dev_dbg(dev, "ASoC: Unregistered platform '%s'\n", platform->name);
 	kfree(platform->name);
 	kfree(platform);
 }
@@ -4007,7 +4014,7 @@
 		codec->reg_size = reg_size;
 		/* it is necessary to make a copy of the default register cache
 		 * because in the case of using a compression type that requires
-		 * the default register cache to be marked as __devinitconst the
+		 * the default register cache to be marked as the
 		 * kernel might have freed the array by the time we initialize
 		 * the cache.
 		 */
@@ -4043,11 +4050,11 @@
 	if (num_dai) {
 		ret = snd_soc_register_dais(dev, dai_drv, num_dai);
 		if (ret < 0)
-			dev_err(codec->dev, "Failed to regster DAIs: %d\n",
-				ret);
+			dev_err(codec->dev, "ASoC: Failed to regster"
+				" DAIs: %d\n", ret);
 	}
 
-	pr_debug("Registered codec '%s'\n", codec->name);
+	dev_dbg(codec->dev, "ASoC: Registered codec '%s'\n", codec->name);
 	return 0;
 
 fail:
@@ -4082,7 +4089,7 @@
 	list_del(&codec->list);
 	mutex_unlock(&client_mutex);
 
-	pr_debug("Unregistered codec '%s'\n", codec->name);
+	dev_dbg(codec->dev, "ASoC: Unregistered codec '%s'\n", codec->name);
 
 	snd_soc_cache_exit(codec);
 	kfree(codec->reg_def_copy);
@@ -4106,7 +4113,7 @@
 	 */
 	if (ret < 0 && ret != -EINVAL) {
 		dev_err(card->dev,
-			"Property '%s' could not be read: %d\n",
+			"ASoC: Property '%s' could not be read: %d\n",
 			propname, ret);
 		return ret;
 	}
@@ -4125,15 +4132,13 @@
 
 	num_routes = of_property_count_strings(np, propname);
 	if (num_routes < 0 || num_routes & 1) {
-		dev_err(card->dev,
-		     "Property '%s' does not exist or its length is not even\n",
-		     propname);
+		dev_err(card->dev, "ASoC: Property '%s' does not exist or its"
+			" length is not even\n", propname);
 		return -EINVAL;
 	}
 	num_routes /= 2;
 	if (!num_routes) {
-		dev_err(card->dev,
-			"Property '%s's length is zero\n",
+		dev_err(card->dev, "ASoC: Property '%s's length is zero\n",
 			propname);
 		return -EINVAL;
 	}
@@ -4142,7 +4147,7 @@
 			      GFP_KERNEL);
 	if (!routes) {
 		dev_err(card->dev,
-			"Could not allocate DAPM route table\n");
+			"ASoC: Could not allocate DAPM route table\n");
 		return -EINVAL;
 	}
 
@@ -4150,9 +4155,9 @@
 		ret = of_property_read_string_index(np, propname,
 			2 * i, &routes[i].sink);
 		if (ret) {
-			dev_err(card->dev,
-				"Property '%s' index %d could not be read: %d\n",
-				propname, 2 * i, ret);
+			dev_err(card->dev, "ASoC: Property '%s' index %d"
+				" could not be read: %d\n", propname, 2 * i,
+				ret);
 			kfree(routes);
 			return -EINVAL;
 		}
@@ -4160,8 +4165,8 @@
 			(2 * i) + 1, &routes[i].source);
 		if (ret) {
 			dev_err(card->dev,
-				"Property '%s' index %d could not be read: %d\n",
-				propname, (2 * i) + 1, ret);
+				"ASoC: Property '%s' index %d could not be"
+				" read: %d\n", propname, (2 * i) + 1, ret);
 			kfree(routes);
 			return -EINVAL;
 		}
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index 6e35bca..1e36bc8 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -220,7 +220,7 @@
 	else if (w->platform)
 		return snd_soc_platform_read(w->platform, reg);
 
-	dev_err(w->dapm->dev, "no valid widget read method\n");
+	dev_err(w->dapm->dev, "ASoC: no valid widget read method\n");
 	return -1;
 }
 
@@ -231,7 +231,7 @@
 	else if (w->platform)
 		return snd_soc_platform_write(w->platform, reg, val);
 
-	dev_err(w->dapm->dev, "no valid widget write method\n");
+	dev_err(w->dapm->dev, "ASoC: no valid widget write method\n");
 	return -1;
 }
 
@@ -546,7 +546,7 @@
 			wlist = kzalloc(wlistsize, GFP_KERNEL);
 			if (wlist == NULL) {
 				dev_err(dapm->dev,
-					"asoc: can't allocate widget list for %s\n",
+					"ASoC: can't allocate widget list for %s\n",
 					w->name);
 				return -ENOMEM;
 			}
@@ -595,9 +595,9 @@
 						      prefix);
 			ret = snd_ctl_add(card, path->kcontrol);
 			if (ret < 0) {
-				dev_err(dapm->dev,
-					"asoc: failed to add dapm kcontrol %s: %d\n",
-					path->long_name, ret);
+				dev_err(dapm->dev, "ASoC: failed to add widget"
+					" %s dapm kcontrol %s: %d\n",
+					w->name, path->long_name, ret);
 				kfree(wlist);
 				kfree(path->long_name);
 				path->long_name = NULL;
@@ -626,7 +626,7 @@
 
 	if (w->num_kcontrols != 1) {
 		dev_err(dapm->dev,
-			"asoc: mux %s has incorrect number of controls\n",
+			"ASoC: mux %s has incorrect number of controls\n",
 			w->name);
 		return -EINVAL;
 	}
@@ -645,7 +645,7 @@
 	wlist = krealloc(wlist, wlistsize, GFP_KERNEL);
 	if (wlist == NULL) {
 		dev_err(dapm->dev,
-			"asoc: can't allocate widget list for %s\n", w->name);
+			"ASoC: can't allocate widget list for %s\n", w->name);
 		return -ENOMEM;
 	}
 	wlist->num_widgets = wlistentries;
@@ -677,7 +677,7 @@
 					name + prefix_len, prefix);
 		ret = snd_ctl_add(card, kcontrol);
 		if (ret < 0) {
-			dev_err(dapm->dev, "failed to add kcontrol %s: %d\n",
+			dev_err(dapm->dev, "ASoC: failed to add kcontrol %s: %d\n",
 				w->name, ret);
 			kfree(wlist);
 			return ret;
@@ -699,7 +699,7 @@
 {
 	if (w->num_kcontrols)
 		dev_err(w->dapm->dev,
-			"asoc: PGA controls not supported: '%s'\n", w->name);
+			"ASoC: PGA controls not supported: '%s'\n", w->name);
 
 	return 0;
 }
@@ -725,7 +725,7 @@
 	case SNDRV_CTL_POWER_D3hot:
 	case SNDRV_CTL_POWER_D3cold:
 		if (widget->ignore_suspend)
-			dev_dbg(widget->dapm->dev, "%s ignoring suspend\n",
+			dev_dbg(widget->dapm->dev, "ASoC: %s ignoring suspend\n",
 				widget->name);
 		return widget->ignore_suspend;
 	default:
@@ -757,14 +757,14 @@
 			wlistentries * sizeof(struct snd_soc_dapm_widget *);
 	*list = krealloc(wlist, wlistsize, GFP_KERNEL);
 	if (*list == NULL) {
-		dev_err(w->dapm->dev, "can't allocate widget list for %s\n",
+		dev_err(w->dapm->dev, "ASoC: can't allocate widget list for %s\n",
 			w->name);
 		return -ENOMEM;
 	}
 	wlist = *list;
 
 	/* insert the widget */
-	dev_dbg(w->dapm->dev, "added %s in widget list pos %d\n",
+	dev_dbg(w->dapm->dev, "ASoC: added %s in widget list pos %d\n",
 			w->name, wlist->num_widgets);
 
 	wlist->widgets[wlist->num_widgets] = w;
@@ -844,7 +844,8 @@
 				int err;
 				err = dapm_list_add_widget(list, path->sink);
 				if (err < 0) {
-					dev_err(widget->dapm->dev, "could not add widget %s\n",
+					dev_err(widget->dapm->dev,
+						"ASoC: could not add widget %s\n",
 						widget->name);
 					return con;
 				}
@@ -943,7 +944,8 @@
 				int err;
 				err = dapm_list_add_widget(list, path->source);
 				if (err < 0) {
-					dev_err(widget->dapm->dev, "could not add widget %s\n",
+					dev_err(widget->dapm->dev,
+						"ASoC: could not add widget %s\n",
 						widget->name);
 					return con;
 				}
@@ -1024,7 +1026,7 @@
 			ret = regulator_allow_bypass(w->regulator, true);
 			if (ret != 0)
 				dev_warn(w->dapm->dev,
-					 "Failed to bypass %s: %d\n",
+					 "ASoC: Failed to bypass %s: %d\n",
 					 w->name, ret);
 		}
 
@@ -1034,7 +1036,7 @@
 			ret = regulator_allow_bypass(w->regulator, false);
 			if (ret != 0)
 				dev_warn(w->dapm->dev,
-					 "Failed to unbypass %s: %d\n",
+					 "ASoC: Failed to unbypass %s: %d\n",
 					 w->name, ret);
 		}
 
@@ -1253,7 +1255,7 @@
 		ret = w->event(w, NULL, event);
 		trace_snd_soc_dapm_widget_event_done(w, event);
 		if (ret < 0)
-			pr_err("%s: %s event failed: %d\n",
+			dev_err(dapm->dev, "ASoC: %s: %s event failed: %d\n",
 			       ev_name, w->name, ret);
 	}
 }
@@ -1402,7 +1404,7 @@
 
 		if (ret < 0)
 			dev_err(w->dapm->dev,
-				"Failed to apply widget power: %d\n", ret);
+				"ASoC: Failed to apply widget power: %d\n", ret);
 	}
 
 	if (!list_empty(&pending))
@@ -1431,20 +1433,21 @@
 	    (w->event_flags & SND_SOC_DAPM_PRE_REG)) {
 		ret = w->event(w, update->kcontrol, SND_SOC_DAPM_PRE_REG);
 		if (ret != 0)
-			pr_err("%s DAPM pre-event failed: %d\n",
+			dev_err(dapm->dev, "ASoC: %s DAPM pre-event failed: %d\n",
 			       w->name, ret);
 	}
 
 	ret = soc_widget_update_bits_locked(w, update->reg, update->mask,
 				  update->val);
 	if (ret < 0)
-		pr_err("%s DAPM update failed: %d\n", w->name, ret);
+		dev_err(dapm->dev, "ASoC: %s DAPM update failed: %d\n",
+			w->name, ret);
 
 	if (w->event &&
 	    (w->event_flags & SND_SOC_DAPM_POST_REG)) {
 		ret = w->event(w, update->kcontrol, SND_SOC_DAPM_POST_REG);
 		if (ret != 0)
-			pr_err("%s DAPM post-event failed: %d\n",
+			dev_err(dapm->dev, "ASoC: %s DAPM post-event failed: %d\n",
 			       w->name, ret);
 	}
 }
@@ -1466,7 +1469,7 @@
 		ret = snd_soc_dapm_set_bias_level(d, SND_SOC_BIAS_STANDBY);
 		if (ret != 0)
 			dev_err(d->dev,
-				"Failed to turn on bias: %d\n", ret);
+				"ASoC: Failed to turn on bias: %d\n", ret);
 	}
 
 	/* Prepare for a STADDBY->ON or ON->STANDBY transition */
@@ -1474,7 +1477,7 @@
 		ret = snd_soc_dapm_set_bias_level(d, SND_SOC_BIAS_PREPARE);
 		if (ret != 0)
 			dev_err(d->dev,
-				"Failed to prepare bias: %d\n", ret);
+				"ASoC: Failed to prepare bias: %d\n", ret);
 	}
 }
 
@@ -1492,7 +1495,7 @@
 	     d->target_bias_level == SND_SOC_BIAS_OFF)) {
 		ret = snd_soc_dapm_set_bias_level(d, SND_SOC_BIAS_STANDBY);
 		if (ret != 0)
-			dev_err(d->dev, "Failed to apply standby bias: %d\n",
+			dev_err(d->dev, "ASoC: Failed to apply standby bias: %d\n",
 				ret);
 	}
 
@@ -1501,7 +1504,8 @@
 	    d->target_bias_level == SND_SOC_BIAS_OFF) {
 		ret = snd_soc_dapm_set_bias_level(d, SND_SOC_BIAS_OFF);
 		if (ret != 0)
-			dev_err(d->dev, "Failed to turn off bias: %d\n", ret);
+			dev_err(d->dev, "ASoC: Failed to turn off bias: %d\n",
+				ret);
 
 		if (d->dev)
 			pm_runtime_put(d->dev);
@@ -1512,7 +1516,7 @@
 	    d->target_bias_level == SND_SOC_BIAS_ON) {
 		ret = snd_soc_dapm_set_bias_level(d, SND_SOC_BIAS_ON);
 		if (ret != 0)
-			dev_err(d->dev, "Failed to apply active bias: %d\n",
+			dev_err(d->dev, "ASoC: Failed to apply active bias: %d\n",
 				ret);
 	}
 }
@@ -1838,7 +1842,7 @@
 
 	if (!dapm->debugfs_dapm) {
 		dev_warn(dapm->dev,
-		       "Failed to create DAPM debugfs directory\n");
+		       "ASoC: Failed to create DAPM debugfs directory\n");
 		return;
 	}
 
@@ -2123,7 +2127,7 @@
 	struct snd_soc_dapm_widget *w = dapm_find_widget(dapm, pin, true);
 
 	if (!w) {
-		dev_err(dapm->dev, "dapm: unknown pin %s\n", pin);
+		dev_err(dapm->dev, "ASoC: DAPM unknown pin %s\n", pin);
 		return -EINVAL;
 	}
 
@@ -2212,8 +2216,16 @@
 	if (!wsource)
 		wsource = wtsource;
 
-	if (wsource == NULL || wsink == NULL)
+	if (wsource == NULL) {
+		dev_err(dapm->dev, "ASoC: no source widget found for %s\n",
+			route->source);
 		return -ENODEV;
+	}
+	if (wsink == NULL) {
+		dev_err(dapm->dev, "ASoC: no sink widget found for %s\n",
+			route->sink);
+		return -ENODEV;
+	}
 
 	path = kzalloc(sizeof(struct snd_soc_dapm_path), GFP_KERNEL);
 	if (!path)
@@ -2308,7 +2320,7 @@
 	return 0;
 
 err:
-	dev_warn(dapm->dev, "asoc: no dapm match for %s --> %s --> %s\n",
+	dev_warn(dapm->dev, "ASoC: no dapm match for %s --> %s --> %s\n",
 		 source, control, sink);
 	kfree(path);
 	return ret;
@@ -2325,7 +2337,7 @@
 
 	if (route->control) {
 		dev_err(dapm->dev,
-			"Removal of routes with controls not supported\n");
+			"ASoC: Removal of routes with controls not supported\n");
 		return -EINVAL;
 	}
 
@@ -2360,7 +2372,7 @@
 		list_del(&path->list_source);
 		kfree(path);
 	} else {
-		dev_warn(dapm->dev, "Route %s->%s does not exist\n",
+		dev_warn(dapm->dev, "ASoC: Route %s->%s does not exist\n",
 			 source, sink);
 	}
 
@@ -2389,8 +2401,10 @@
 	for (i = 0; i < num; i++) {
 		r = snd_soc_dapm_add_route(dapm, route);
 		if (r < 0) {
-			dev_err(dapm->dev, "Failed to add route %s->%s\n",
-				route->source, route->sink);
+			dev_err(dapm->dev, "ASoC: Failed to add route %s -> %s -> %s\n",
+				route->source,
+				route->control ? route->control : "direct",
+				route->sink);
 			ret = r;
 		}
 		route++;
@@ -2438,19 +2452,19 @@
 	int count = 0;
 
 	if (!source) {
-		dev_err(dapm->dev, "Unable to find source %s for weak route\n",
+		dev_err(dapm->dev, "ASoC: Unable to find source %s for weak route\n",
 			route->source);
 		return -ENODEV;
 	}
 
 	if (!sink) {
-		dev_err(dapm->dev, "Unable to find sink %s for weak route\n",
+		dev_err(dapm->dev, "ASoC: Unable to find sink %s for weak route\n",
 			route->sink);
 		return -ENODEV;
 	}
 
 	if (route->control || route->connected)
-		dev_warn(dapm->dev, "Ignoring control for weak route %s->%s\n",
+		dev_warn(dapm->dev, "ASoC: Ignoring control for weak route %s->%s\n",
 			 route->source, route->sink);
 
 	list_for_each_entry(path, &source->sinks, list_source) {
@@ -2461,10 +2475,10 @@
 	}
 
 	if (count == 0)
-		dev_err(dapm->dev, "No path found for weak route %s->%s\n",
+		dev_err(dapm->dev, "ASoC: No path found for weak route %s->%s\n",
 			route->source, route->sink);
 	if (count > 1)
-		dev_warn(dapm->dev, "%d paths found for weak route %s->%s\n",
+		dev_warn(dapm->dev, "ASoC: %d paths found for weak route %s->%s\n",
 			 count, route->source, route->sink);
 
 	return 0;
@@ -2601,7 +2615,7 @@
 
 	if (snd_soc_volsw_is_stereo(mc))
 		dev_warn(widget->dapm->dev,
-			 "Control '%s' is stereo, which is not supported\n",
+			 "ASoC: Control '%s' is stereo, which is not supported\n",
 			 kcontrol->id.name);
 
 	ucontrol->value.integer.value[0] =
@@ -2644,7 +2658,7 @@
 
 	if (snd_soc_volsw_is_stereo(mc))
 		dev_warn(widget->dapm->dev,
-			 "Control '%s' is stereo, which is not supported\n",
+			 "ASoC: Control '%s' is stereo, which is not supported\n",
 			 kcontrol->id.name);
 
 	val = (ucontrol->value.integer.value[0] & mask);
@@ -3021,7 +3035,7 @@
 		w->regulator = devm_regulator_get(dapm->dev, w->name);
 		if (IS_ERR(w->regulator)) {
 			ret = PTR_ERR(w->regulator);
-			dev_err(dapm->dev, "Failed to request %s: %d\n",
+			dev_err(dapm->dev, "ASoC: Failed to request %s: %d\n",
 				w->name, ret);
 			return NULL;
 		}
@@ -3031,7 +3045,7 @@
 		w->clk = devm_clk_get(dapm->dev, w->name);
 		if (IS_ERR(w->clk)) {
 			ret = PTR_ERR(w->clk);
-			dev_err(dapm->dev, "Failed to request %s: %d\n",
+			dev_err(dapm->dev, "ASoC: Failed to request %s: %d\n",
 				w->name, ret);
 			return NULL;
 		}
@@ -3182,7 +3196,7 @@
 	if (config->formats) {
 		fmt = ffs(config->formats) - 1;
 	} else {
-		dev_warn(w->dapm->dev, "Invalid format %llx specified\n",
+		dev_warn(w->dapm->dev, "ASoC: Invalid format %llx specified\n",
 			 config->formats);
 		fmt = 0;
 	}
@@ -3215,7 +3229,7 @@
 							     params, source);
 			if (ret != 0) {
 				dev_err(source->dev,
-					"hw_params() failed: %d\n", ret);
+					"ASoC: hw_params() failed: %d\n", ret);
 				goto out;
 			}
 		}
@@ -3226,7 +3240,7 @@
 							   sink);
 			if (ret != 0) {
 				dev_err(sink->dev,
-					"hw_params() failed: %d\n", ret);
+					"ASoC: hw_params() failed: %d\n", ret);
 				goto out;
 			}
 		}
@@ -3235,14 +3249,14 @@
 	case SND_SOC_DAPM_POST_PMU:
 		ret = snd_soc_dai_digital_mute(sink, 0);
 		if (ret != 0 && ret != -ENOTSUPP)
-			dev_warn(sink->dev, "Failed to unmute: %d\n", ret);
+			dev_warn(sink->dev, "ASoC: Failed to unmute: %d\n", ret);
 		ret = 0;
 		break;
 
 	case SND_SOC_DAPM_PRE_PMD:
 		ret = snd_soc_dai_digital_mute(sink, 1);
 		if (ret != 0 && ret != -ENOTSUPP)
-			dev_warn(sink->dev, "Failed to mute: %d\n", ret);
+			dev_warn(sink->dev, "ASoC: Failed to mute: %d\n", ret);
 		ret = 0;
 		break;
 
@@ -3281,11 +3295,11 @@
 	template.event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
 		SND_SOC_DAPM_PRE_PMD;
 
-	dev_dbg(card->dev, "adding %s widget\n", link_name);
+	dev_dbg(card->dev, "ASoC: adding %s widget\n", link_name);
 
 	w = snd_soc_dapm_new_control(&card->dapm, &template);
 	if (!w) {
-		dev_err(card->dev, "Failed to create %s widget\n",
+		dev_err(card->dev, "ASoC: Failed to create %s widget\n",
 			link_name);
 		return -ENOMEM;
 	}
@@ -3319,12 +3333,12 @@
 		template.name = dai->driver->playback.stream_name;
 		template.sname = dai->driver->playback.stream_name;
 
-		dev_dbg(dai->dev, "adding %s widget\n",
+		dev_dbg(dai->dev, "ASoC: 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",
+			dev_err(dapm->dev, "ASoC: Failed to create %s widget\n",
 				dai->driver->playback.stream_name);
 		}
 
@@ -3337,12 +3351,12 @@
 		template.name = dai->driver->capture.stream_name;
 		template.sname = dai->driver->capture.stream_name;
 
-		dev_dbg(dai->dev, "adding %s widget\n",
+		dev_dbg(dai->dev, "ASoC: 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",
+			dev_err(dapm->dev, "ASoC: Failed to create %s widget\n",
 				dai->driver->capture.stream_name);
 		}
 
@@ -3518,11 +3532,11 @@
 	struct snd_soc_dapm_widget *w = dapm_find_widget(dapm, pin, true);
 
 	if (!w) {
-		dev_err(dapm->dev, "dapm: unknown pin %s\n", pin);
+		dev_err(dapm->dev, "ASoC: unknown pin %s\n", pin);
 		return -EINVAL;
 	}
 
-	dev_dbg(w->dapm->dev, "dapm: force enable pin %s\n", pin);
+	dev_dbg(w->dapm->dev, "ASoC: force enable pin %s\n", pin);
 	w->connected = 1;
 	w->force = 1;
 	dapm_mark_dirty(w, "force enable");
@@ -3605,7 +3619,7 @@
 	struct snd_soc_dapm_widget *w = dapm_find_widget(dapm, pin, false);
 
 	if (!w) {
-		dev_err(dapm->dev, "dapm: unknown pin %s\n", pin);
+		dev_err(dapm->dev, "ASoC: unknown pin %s\n", pin);
 		return -EINVAL;
 	}
 
@@ -3664,7 +3678,7 @@
 	struct snd_soc_dapm_context *dapm = &codec->dapm;
 	struct snd_soc_dapm_widget *w;
 
-	dev_dbg(codec->dev, "Auto NC: DAPMs: card:%p codec:%p\n",
+	dev_dbg(codec->dev, "ASoC: Auto NC: DAPMs: card:%p codec:%p\n",
 		&card->dapm, &codec->dapm);
 
 	list_for_each_entry(w, &card->widgets, list) {
@@ -3674,7 +3688,7 @@
 		case snd_soc_dapm_input:
 		case snd_soc_dapm_output:
 		case snd_soc_dapm_micbias:
-			dev_dbg(codec->dev, "Auto NC: Checking widget %s\n",
+			dev_dbg(codec->dev, "ASoC: Auto NC: Checking widget %s\n",
 				w->name);
 			if (!snd_soc_dapm_widget_in_card_paths(card, w)) {
 				dev_dbg(codec->dev,
diff --git a/sound/soc/soc-dmaengine-pcm.c b/sound/soc/soc-dmaengine-pcm.c
index bbc1257..111b7d92 100644
--- a/sound/soc/soc-dmaengine-pcm.c
+++ b/sound/soc/soc-dmaengine-pcm.c
@@ -317,3 +317,5 @@
 	return 0;
 }
 EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_close);
+
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/soc-jack.c b/sound/soc/soc-jack.c
index 1ab5fe0..0bb5cccd 100644
--- a/sound/soc/soc-jack.c
+++ b/sound/soc/soc-jack.c
@@ -66,7 +66,6 @@
 	struct snd_soc_dapm_context *dapm;
 	struct snd_soc_jack_pin *pin;
 	int enable;
-	int oldstatus;
 
 	trace_snd_soc_jack_report(jack, mask, status);
 
@@ -78,8 +77,6 @@
 
 	mutex_lock(&jack->mutex);
 
-	oldstatus = jack->status;
-
 	jack->status &= ~mask;
 	jack->status |= status & mask;
 
@@ -172,12 +169,13 @@
 
 	for (i = 0; i < count; i++) {
 		if (!pins[i].pin) {
-			printk(KERN_ERR "No name for pin %d\n", i);
+			dev_err(jack->codec->dev, "ASoC: No name for pin %d\n",
+				i);
 			return -EINVAL;
 		}
 		if (!pins[i].mask) {
-			printk(KERN_ERR "No mask for pin %d (%s)\n", i,
-			       pins[i].pin);
+			dev_err(jack->codec->dev, "ASoC: No mask for pin %d"
+				" (%s)\n", i, pins[i].pin);
 			return -EINVAL;
 		}
 
@@ -297,13 +295,13 @@
 
 	for (i = 0; i < count; i++) {
 		if (!gpio_is_valid(gpios[i].gpio)) {
-			printk(KERN_ERR "Invalid gpio %d\n",
+			dev_err(jack->codec->dev, "ASoC: Invalid gpio %d\n",
 				gpios[i].gpio);
 			ret = -EINVAL;
 			goto undo;
 		}
 		if (!gpios[i].name) {
-			printk(KERN_ERR "No name for gpio %d\n",
+			dev_err(jack->codec->dev, "ASoC: No name for gpio %d\n",
 				gpios[i].gpio);
 			ret = -EINVAL;
 			goto undo;
@@ -332,7 +330,7 @@
 		if (gpios[i].wake) {
 			ret = irq_set_irq_wake(gpio_to_irq(gpios[i].gpio), 1);
 			if (ret != 0)
-				printk(KERN_ERR
+				dev_err(jack->codec->dev, "ASoC: "
 				  "Failed to mark GPIO %d as wake source: %d\n",
 					gpios[i].gpio, ret);
 		}
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
index ef22d0b..5c3ca2a 100644
--- a/sound/soc/soc-pcm.c
+++ b/sound/soc/soc-pcm.c
@@ -43,7 +43,7 @@
 
 		struct snd_soc_pcm_runtime *be = dpcm->be;
 
-		dev_dbg(be->dev, "pm: BE %s event %d dir %d\n",
+		dev_dbg(be->dev, "ASoC: BE %s event %d dir %d\n",
 				be->dai_link->name, event, dir);
 
 		snd_soc_dapm_stream_event(be, dir, event);
@@ -70,18 +70,19 @@
 	 */
 	if (!soc_dai->rate) {
 		dev_warn(soc_dai->dev,
-			 "Not enforcing symmetric_rates due to race\n");
+			 "ASoC: Not enforcing symmetric_rates due to race\n");
 		return 0;
 	}
 
-	dev_dbg(soc_dai->dev, "Symmetry forces %dHz rate\n", soc_dai->rate);
+	dev_dbg(soc_dai->dev, "ASoC: Symmetry forces %dHz rate\n", soc_dai->rate);
 
 	ret = snd_pcm_hw_constraint_minmax(substream->runtime,
 					   SNDRV_PCM_HW_PARAM_RATE,
 					   soc_dai->rate, soc_dai->rate);
 	if (ret < 0) {
 		dev_err(soc_dai->dev,
-			"Unable to apply rate symmetry constraint: %d\n", ret);
+			"ASoC: Unable to apply rate symmetry constraint: %d\n",
+			ret);
 		return ret;
 	}
 
@@ -118,7 +119,7 @@
 						   sample_sizes[i], bits);
 		if (ret != 0)
 			dev_warn(dai->dev,
-				 "Failed to set MSB %d/%d: %d\n",
+				 "ASoC: Failed to set MSB %d/%d: %d\n",
 				 bits, sample_sizes[i], ret);
 	}
 }
@@ -149,8 +150,8 @@
 	if (cpu_dai->driver->ops->startup) {
 		ret = cpu_dai->driver->ops->startup(substream, cpu_dai);
 		if (ret < 0) {
-			dev_err(cpu_dai->dev, "can't open interface %s: %d\n",
-				cpu_dai->name, ret);
+			dev_err(cpu_dai->dev, "ASoC: can't open interface"
+				" %s: %d\n", cpu_dai->name, ret);
 			goto out;
 		}
 	}
@@ -158,8 +159,8 @@
 	if (platform->driver->ops && platform->driver->ops->open) {
 		ret = platform->driver->ops->open(substream);
 		if (ret < 0) {
-			dev_err(platform->dev, "can't open platform %s: %d\n",
-				platform->name, ret);
+			dev_err(platform->dev, "ASoC: can't open platform"
+				" %s: %d\n", platform->name, ret);
 			goto platform_err;
 		}
 	}
@@ -167,8 +168,8 @@
 	if (codec_dai->driver->ops->startup) {
 		ret = codec_dai->driver->ops->startup(substream, codec_dai);
 		if (ret < 0) {
-			dev_err(codec_dai->dev, "can't open codec %s: %d\n",
-				codec_dai->name, ret);
+			dev_err(codec_dai->dev, "ASoC: can't open codec"
+				" %s: %d\n", codec_dai->name, ret);
 			goto codec_dai_err;
 		}
 	}
@@ -176,7 +177,7 @@
 	if (rtd->dai_link->ops && rtd->dai_link->ops->startup) {
 		ret = rtd->dai_link->ops->startup(substream);
 		if (ret < 0) {
-			pr_err("asoc: %s startup failed: %d\n",
+			pr_err("ASoC: %s startup failed: %d\n",
 			       rtd->dai_link->name, ret);
 			goto machine_err;
 		}
@@ -238,18 +239,18 @@
 	ret = -EINVAL;
 	snd_pcm_limit_hw_rates(runtime);
 	if (!runtime->hw.rates) {
-		printk(KERN_ERR "asoc: %s <-> %s No matching rates\n",
+		printk(KERN_ERR "ASoC: %s <-> %s No matching rates\n",
 			codec_dai->name, cpu_dai->name);
 		goto config_err;
 	}
 	if (!runtime->hw.formats) {
-		printk(KERN_ERR "asoc: %s <-> %s No matching formats\n",
+		printk(KERN_ERR "ASoC: %s <-> %s No matching formats\n",
 			codec_dai->name, cpu_dai->name);
 		goto config_err;
 	}
 	if (!runtime->hw.channels_min || !runtime->hw.channels_max ||
 	    runtime->hw.channels_min > runtime->hw.channels_max) {
-		printk(KERN_ERR "asoc: %s <-> %s No matching channels\n",
+		printk(KERN_ERR "ASoC: %s <-> %s No matching channels\n",
 				codec_dai->name, cpu_dai->name);
 		goto config_err;
 	}
@@ -270,12 +271,12 @@
 			goto config_err;
 	}
 
-	pr_debug("asoc: %s <-> %s info:\n",
+	pr_debug("ASoC: %s <-> %s info:\n",
 			codec_dai->name, cpu_dai->name);
-	pr_debug("asoc: rate mask 0x%x\n", runtime->hw.rates);
-	pr_debug("asoc: min ch %d max ch %d\n", runtime->hw.channels_min,
+	pr_debug("ASoC: rate mask 0x%x\n", runtime->hw.rates);
+	pr_debug("ASoC: min ch %d max ch %d\n", runtime->hw.channels_min,
 		 runtime->hw.channels_max);
-	pr_debug("asoc: min rate %d max rate %d\n", runtime->hw.rate_min,
+	pr_debug("ASoC: min rate %d max rate %d\n", runtime->hw.rate_min,
 		 runtime->hw.rate_max);
 
 dynamic:
@@ -330,7 +331,7 @@
 
 	mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
 
-	pr_debug("pop wq checking: %s status: %s waiting: %s\n",
+	dev_dbg(rtd->dev, "ASoC: pop wq checking: %s status: %s waiting: %s\n",
 		 codec_dai->driver->playback.stream_name,
 		 codec_dai->playback_active ? "active" : "inactive",
 		 codec_dai->pop_wait ? "yes" : "no");
@@ -444,7 +445,8 @@
 	if (rtd->dai_link->ops && rtd->dai_link->ops->prepare) {
 		ret = rtd->dai_link->ops->prepare(substream);
 		if (ret < 0) {
-			pr_err("asoc: machine prepare error: %d\n", ret);
+			dev_err(rtd->card->dev, "ASoC: machine prepare error:"
+				" %d\n", ret);
 			goto out;
 		}
 	}
@@ -452,8 +454,8 @@
 	if (platform->driver->ops && platform->driver->ops->prepare) {
 		ret = platform->driver->ops->prepare(substream);
 		if (ret < 0) {
-			dev_err(platform->dev, "platform prepare error: %d\n",
-				ret);
+			dev_err(platform->dev, "ASoC: platform prepare error:"
+				" %d\n", ret);
 			goto out;
 		}
 	}
@@ -461,7 +463,7 @@
 	if (codec_dai->driver->ops->prepare) {
 		ret = codec_dai->driver->ops->prepare(substream, codec_dai);
 		if (ret < 0) {
-			dev_err(codec_dai->dev, "DAI prepare error: %d\n",
+			dev_err(codec_dai->dev, "ASoC: DAI prepare error: %d\n",
 				ret);
 			goto out;
 		}
@@ -470,7 +472,7 @@
 	if (cpu_dai->driver->ops->prepare) {
 		ret = cpu_dai->driver->ops->prepare(substream, cpu_dai);
 		if (ret < 0) {
-			dev_err(cpu_dai->dev, "DAI prepare error: %d\n",
+			dev_err(cpu_dai->dev, "ASoC: DAI prepare error: %d\n",
 				ret);
 			goto out;
 		}
@@ -512,7 +514,8 @@
 	if (rtd->dai_link->ops && rtd->dai_link->ops->hw_params) {
 		ret = rtd->dai_link->ops->hw_params(substream, params);
 		if (ret < 0) {
-			pr_err("asoc: machine hw_params failed: %d\n", ret);
+			dev_err(rtd->card->dev, "ASoC: machine hw_params"
+				" failed: %d\n", ret);
 			goto out;
 		}
 	}
@@ -520,8 +523,8 @@
 	if (codec_dai->driver->ops->hw_params) {
 		ret = codec_dai->driver->ops->hw_params(substream, params, codec_dai);
 		if (ret < 0) {
-			dev_err(codec_dai->dev, "can't set %s hw params: %d\n",
-				codec_dai->name, ret);
+			dev_err(codec_dai->dev, "ASoC: can't set %s hw params:"
+				" %d\n", codec_dai->name, ret);
 			goto codec_err;
 		}
 	}
@@ -529,7 +532,7 @@
 	if (cpu_dai->driver->ops->hw_params) {
 		ret = cpu_dai->driver->ops->hw_params(substream, params, cpu_dai);
 		if (ret < 0) {
-			dev_err(cpu_dai->dev, "%s hw params failed: %d\n",
+			dev_err(cpu_dai->dev, "ASoC: %s hw params failed: %d\n",
 				cpu_dai->name, ret);
 			goto interface_err;
 		}
@@ -538,7 +541,7 @@
 	if (platform->driver->ops && platform->driver->ops->hw_params) {
 		ret = platform->driver->ops->hw_params(substream, params);
 		if (ret < 0) {
-			dev_err(platform->dev, "%s hw params failed: %d\n",
+			dev_err(platform->dev, "ASoC: %s hw params failed: %d\n",
 			       platform->name, ret);
 			goto platform_err;
 		}
@@ -760,7 +763,7 @@
 	struct snd_soc_dpcm *dpcm, *d;
 
 	list_for_each_entry_safe(dpcm, d, &fe->dpcm[stream].be_clients, list_be) {
-		dev_dbg(fe->dev, "BE %s disconnect check for %s\n",
+		dev_dbg(fe->dev, "ASoC: BE %s disconnect check for %s\n",
 				stream ? "capture" : "playback",
 				dpcm->be->dai_link->name);
 
@@ -815,7 +818,7 @@
 		}
 	}
 
-	dev_err(card->dev, "can't get %s BE for %s\n",
+	dev_err(card->dev, "ASoC: can't get %s BE for %s\n",
 		stream ? "capture" : "playback", widget->name);
 	return NULL;
 }
@@ -866,7 +869,7 @@
 	/* get number of valid DAI paths and their widgets */
 	paths = snd_soc_dapm_dai_get_connected_widgets(cpu_dai, stream, &list);
 
-	dev_dbg(fe->dev, "found %d audio %s paths\n", paths,
+	dev_dbg(fe->dev, "ASoC: found %d audio %s paths\n", paths,
 			stream ? "capture" : "playback");
 
 	*list_ = list;
@@ -903,7 +906,7 @@
 		if (widget && widget_in_list(list, widget))
 			continue;
 
-		dev_dbg(fe->dev, "pruning %s BE %s for %s\n",
+		dev_dbg(fe->dev, "ASoC: pruning %s BE %s for %s\n",
 			stream ? "capture" : "playback",
 			dpcm->be->dai_link->name, fe->dai_link->name);
 		dpcm->state = SND_SOC_DPCM_LINK_STATE_FREE;
@@ -911,7 +914,7 @@
 		prune++;
 	}
 
-	dev_dbg(fe->dev, "found %d old BE paths for pruning\n", prune);
+	dev_dbg(fe->dev, "ASoC: found %d old BE paths for pruning\n", prune);
 	return prune;
 }
 
@@ -932,7 +935,7 @@
 		/* is there a valid BE rtd for this widget */
 		be = dpcm_get_be(card, list->widgets[i], stream);
 		if (!be) {
-			dev_err(fe->dev, "no BE found for %s\n",
+			dev_err(fe->dev, "ASoC: no BE found for %s\n",
 					list->widgets[i]->name);
 			continue;
 		}
@@ -948,7 +951,7 @@
 		/* newly connected FE and BE */
 		err = dpcm_be_connect(fe, be, stream);
 		if (err < 0) {
-			dev_err(fe->dev, "can't connect %s\n",
+			dev_err(fe->dev, "ASoC: can't connect %s\n",
 				list->widgets[i]->name);
 			break;
 		} else if (err == 0) /* already connected */
@@ -959,7 +962,7 @@
 		new++;
 	}
 
-	dev_dbg(fe->dev, "found %d new BE paths\n", new);
+	dev_dbg(fe->dev, "ASoC: found %d new BE paths\n", new);
 	return new;
 }
 
@@ -998,7 +1001,7 @@
 			snd_soc_dpcm_get_substream(be, stream);
 
 		if (be->dpcm[stream].users == 0)
-			dev_err(be->dev, "no users %s at close - state %d\n",
+			dev_err(be->dev, "ASoC: no users %s at close - state %d\n",
 				stream ? "capture" : "playback",
 				be->dpcm[stream].state);
 
@@ -1032,7 +1035,7 @@
 
 		/* first time the dpcm is open ? */
 		if (be->dpcm[stream].users == DPCM_MAX_BE_USERS)
-			dev_err(be->dev, "too many users %s at open %d\n",
+			dev_err(be->dev, "ASoC: too many users %s at open %d\n",
 				stream ? "capture" : "playback",
 				be->dpcm[stream].state);
 
@@ -1043,15 +1046,15 @@
 		    (be->dpcm[stream].state != SND_SOC_DPCM_STATE_CLOSE))
 			continue;
 
-		dev_dbg(be->dev, "dpcm: open BE %s\n", be->dai_link->name);
+		dev_dbg(be->dev, "ASoC: open BE %s\n", be->dai_link->name);
 
 		be_substream->runtime = be->dpcm[stream].runtime;
 		err = soc_pcm_open(be_substream);
 		if (err < 0) {
-			dev_err(be->dev, "BE open failed %d\n", err);
+			dev_err(be->dev, "ASoC: BE open failed %d\n", err);
 			be->dpcm[stream].users--;
 			if (be->dpcm[stream].users < 0)
-				dev_err(be->dev, "no users %s at unwind %d\n",
+				dev_err(be->dev, "ASoC: no users %s at unwind %d\n",
 					stream ? "capture" : "playback",
 					be->dpcm[stream].state);
 
@@ -1076,7 +1079,7 @@
 			continue;
 
 		if (be->dpcm[stream].users == 0)
-			dev_err(be->dev, "no users %s at close %d\n",
+			dev_err(be->dev, "ASoC: no users %s at close %d\n",
 				stream ? "capture" : "playback",
 				be->dpcm[stream].state);
 
@@ -1128,16 +1131,16 @@
 
 	ret = dpcm_be_dai_startup(fe, fe_substream->stream);
 	if (ret < 0) {
-		dev_err(fe->dev,"dpcm: failed to start some BEs %d\n", ret);
+		dev_err(fe->dev,"ASoC: failed to start some BEs %d\n", ret);
 		goto be_err;
 	}
 
-	dev_dbg(fe->dev, "dpcm: open FE %s\n", fe->dai_link->name);
+	dev_dbg(fe->dev, "ASoC: open FE %s\n", fe->dai_link->name);
 
 	/* start the DAI frontend */
 	ret = soc_pcm_open(fe_substream);
 	if (ret < 0) {
-		dev_err(fe->dev,"dpcm: failed to start FE %d\n", ret);
+		dev_err(fe->dev,"ASoC: failed to start FE %d\n", ret);
 		goto unwind;
 	}
 
@@ -1172,7 +1175,7 @@
 			continue;
 
 		if (be->dpcm[stream].users == 0)
-			dev_err(be->dev, "no users %s at close - state %d\n",
+			dev_err(be->dev, "ASoC: no users %s at close - state %d\n",
 				stream ? "capture" : "playback",
 				be->dpcm[stream].state);
 
@@ -1183,7 +1186,7 @@
 		    (be->dpcm[stream].state != SND_SOC_DPCM_STATE_OPEN))
 			continue;
 
-		dev_dbg(be->dev, "dpcm: close BE %s\n",
+		dev_dbg(be->dev, "ASoC: close BE %s\n",
 			dpcm->fe->dai_link->name);
 
 		soc_pcm_close(be_substream);
@@ -1204,7 +1207,7 @@
 	/* shutdown the BEs */
 	dpcm_be_dai_shutdown(fe, substream->stream);
 
-	dev_dbg(fe->dev, "dpcm: close FE %s\n", fe->dai_link->name);
+	dev_dbg(fe->dev, "ASoC: close FE %s\n", fe->dai_link->name);
 
 	/* now shutdown the frontend */
 	soc_pcm_close(substream);
@@ -1243,7 +1246,7 @@
 		    (be->dpcm[stream].state != SND_SOC_DPCM_STATE_STOP))
 			continue;
 
-		dev_dbg(be->dev, "dpcm: hw_free BE %s\n",
+		dev_dbg(be->dev, "ASoC: hw_free BE %s\n",
 			dpcm->fe->dai_link->name);
 
 		soc_pcm_hw_free(be_substream);
@@ -1262,12 +1265,12 @@
 	mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME);
 	fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE;
 
-	dev_dbg(fe->dev, "dpcm: hw_free FE %s\n", fe->dai_link->name);
+	dev_dbg(fe->dev, "ASoC: hw_free FE %s\n", fe->dai_link->name);
 
 	/* call hw_free on the frontend */
 	err = soc_pcm_hw_free(substream);
 	if (err < 0)
-		dev_err(fe->dev,"dpcm: hw_free FE %s failed\n",
+		dev_err(fe->dev,"ASoC: hw_free FE %s failed\n",
 			fe->dai_link->name);
 
 	/* only hw_params backends that are either sinks or sources
@@ -1305,7 +1308,7 @@
 		    (be->dpcm[stream].state != SND_SOC_DPCM_STATE_HW_FREE))
 			continue;
 
-		dev_dbg(be->dev, "dpcm: hw_params BE %s\n",
+		dev_dbg(be->dev, "ASoC: hw_params BE %s\n",
 			dpcm->fe->dai_link->name);
 
 		/* copy params for each dpcm */
@@ -1318,7 +1321,7 @@
 					&dpcm->hw_params);
 			if (ret < 0) {
 				dev_err(be->dev,
-					"dpcm: hw_params BE fixup failed %d\n",
+					"ASoC: hw_params BE fixup failed %d\n",
 					ret);
 				goto unwind;
 			}
@@ -1327,7 +1330,7 @@
 		ret = soc_pcm_hw_params(be_substream, &dpcm->hw_params);
 		if (ret < 0) {
 			dev_err(dpcm->be->dev,
-				"dpcm: hw_params BE failed %d\n", ret);
+				"ASoC: hw_params BE failed %d\n", ret);
 			goto unwind;
 		}
 
@@ -1374,18 +1377,18 @@
 			sizeof(struct snd_pcm_hw_params));
 	ret = dpcm_be_dai_hw_params(fe, substream->stream);
 	if (ret < 0) {
-		dev_err(fe->dev,"dpcm: hw_params BE failed %d\n", ret);
+		dev_err(fe->dev,"ASoC: hw_params BE failed %d\n", ret);
 		goto out;
 	}
 
-	dev_dbg(fe->dev, "dpcm: hw_params FE %s rate %d chan %x fmt %d\n",
+	dev_dbg(fe->dev, "ASoC: hw_params FE %s rate %d chan %x fmt %d\n",
 			fe->dai_link->name, params_rate(params),
 			params_channels(params), params_format(params));
 
 	/* call hw_params on the frontend */
 	ret = soc_pcm_hw_params(substream, params);
 	if (ret < 0) {
-		dev_err(fe->dev,"dpcm: hw_params FE failed %d\n", ret);
+		dev_err(fe->dev,"ASoC: hw_params FE failed %d\n", ret);
 		dpcm_be_dai_hw_free(fe, stream);
 	 } else
 		fe->dpcm[stream].state = SND_SOC_DPCM_STATE_HW_PARAMS;
@@ -1401,12 +1404,12 @@
 {
 	int ret;
 
-	dev_dbg(dpcm->be->dev, "dpcm: trigger BE %s cmd %d\n",
+	dev_dbg(dpcm->be->dev, "ASoC: trigger BE %s cmd %d\n",
 			dpcm->fe->dai_link->name, cmd);
 
 	ret = soc_pcm_trigger(substream, cmd);
 	if (ret < 0)
-		dev_err(dpcm->be->dev,"dpcm: trigger BE failed %d\n", ret);
+		dev_err(dpcm->be->dev,"ASoC: trigger BE failed %d\n", ret);
 
 	return ret;
 }
@@ -1517,12 +1520,12 @@
 	case SND_SOC_DPCM_TRIGGER_PRE:
 		/* call trigger on the frontend before the backend. */
 
-		dev_dbg(fe->dev, "dpcm: pre trigger FE %s cmd %d\n",
+		dev_dbg(fe->dev, "ASoC: pre trigger FE %s cmd %d\n",
 				fe->dai_link->name, cmd);
 
 		ret = soc_pcm_trigger(substream, cmd);
 		if (ret < 0) {
-			dev_err(fe->dev,"dpcm: trigger FE failed %d\n", ret);
+			dev_err(fe->dev,"ASoC: trigger FE failed %d\n", ret);
 			goto out;
 		}
 
@@ -1533,11 +1536,11 @@
 
 		ret = dpcm_be_dai_trigger(fe, substream->stream, cmd);
 		if (ret < 0) {
-			dev_err(fe->dev,"dpcm: trigger FE failed %d\n", ret);
+			dev_err(fe->dev,"ASoC: trigger FE failed %d\n", ret);
 			goto out;
 		}
 
-		dev_dbg(fe->dev, "dpcm: post trigger FE %s cmd %d\n",
+		dev_dbg(fe->dev, "ASoC: post trigger FE %s cmd %d\n",
 				fe->dai_link->name, cmd);
 
 		ret = soc_pcm_trigger(substream, cmd);
@@ -1545,17 +1548,17 @@
 	case SND_SOC_DPCM_TRIGGER_BESPOKE:
 		/* bespoke trigger() - handles both FE and BEs */
 
-		dev_dbg(fe->dev, "dpcm: bespoke trigger FE %s cmd %d\n",
+		dev_dbg(fe->dev, "ASoC: bespoke trigger FE %s cmd %d\n",
 				fe->dai_link->name, cmd);
 
 		ret = soc_pcm_bespoke_trigger(substream, cmd);
 		if (ret < 0) {
-			dev_err(fe->dev,"dpcm: trigger FE failed %d\n", ret);
+			dev_err(fe->dev,"ASoC: trigger FE failed %d\n", ret);
 			goto out;
 		}
 		break;
 	default:
-		dev_err(fe->dev, "dpcm: invalid trigger cmd %d for %s\n", cmd,
+		dev_err(fe->dev, "ASoC: invalid trigger cmd %d for %s\n", cmd,
 				fe->dai_link->name);
 		ret = -EINVAL;
 		goto out;
@@ -1598,12 +1601,12 @@
 		    (be->dpcm[stream].state != SND_SOC_DPCM_STATE_STOP))
 			continue;
 
-		dev_dbg(be->dev, "dpcm: prepare BE %s\n",
+		dev_dbg(be->dev, "ASoC: prepare BE %s\n",
 			dpcm->fe->dai_link->name);
 
 		ret = soc_pcm_prepare(be_substream);
 		if (ret < 0) {
-			dev_err(be->dev, "dpcm: backend prepare failed %d\n",
+			dev_err(be->dev, "ASoC: backend prepare failed %d\n",
 				ret);
 			break;
 		}
@@ -1620,13 +1623,13 @@
 
 	mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME);
 
-	dev_dbg(fe->dev, "dpcm: prepare FE %s\n", fe->dai_link->name);
+	dev_dbg(fe->dev, "ASoC: prepare FE %s\n", fe->dai_link->name);
 
 	fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE;
 
 	/* there is no point preparing this FE if there are no BEs */
 	if (list_empty(&fe->dpcm[stream].be_clients)) {
-		dev_err(fe->dev, "dpcm: no backend DAIs enabled for %s\n",
+		dev_err(fe->dev, "ASoC: no backend DAIs enabled for %s\n",
 				fe->dai_link->name);
 		ret = -EINVAL;
 		goto out;
@@ -1639,7 +1642,7 @@
 	/* call prepare on the frontend */
 	ret = soc_pcm_prepare(substream);
 	if (ret < 0) {
-		dev_err(fe->dev,"dpcm: prepare FE %s failed\n",
+		dev_err(fe->dev,"ASoC: prepare FE %s failed\n",
 			fe->dai_link->name);
 		goto out;
 	}
@@ -1673,33 +1676,33 @@
 	enum snd_soc_dpcm_trigger trigger = fe->dai_link->trigger[stream];
 	int err;
 
-	dev_dbg(fe->dev, "runtime %s close on FE %s\n",
+	dev_dbg(fe->dev, "ASoC: runtime %s close on FE %s\n",
 			stream ? "capture" : "playback", fe->dai_link->name);
 
 	if (trigger == SND_SOC_DPCM_TRIGGER_BESPOKE) {
 		/* call bespoke trigger - FE takes care of all BE triggers */
-		dev_dbg(fe->dev, "dpcm: bespoke trigger FE %s cmd stop\n",
+		dev_dbg(fe->dev, "ASoC: bespoke trigger FE %s cmd stop\n",
 				fe->dai_link->name);
 
 		err = soc_pcm_bespoke_trigger(substream, SNDRV_PCM_TRIGGER_STOP);
 		if (err < 0)
-			dev_err(fe->dev,"dpcm: trigger FE failed %d\n", err);
+			dev_err(fe->dev,"ASoC: trigger FE failed %d\n", err);
 	} else {
-		dev_dbg(fe->dev, "dpcm: trigger FE %s cmd stop\n",
+		dev_dbg(fe->dev, "ASoC: trigger FE %s cmd stop\n",
 			fe->dai_link->name);
 
 		err = dpcm_be_dai_trigger(fe, stream, SNDRV_PCM_TRIGGER_STOP);
 		if (err < 0)
-			dev_err(fe->dev,"dpcm: trigger FE failed %d\n", err);
+			dev_err(fe->dev,"ASoC: trigger FE failed %d\n", err);
 	}
 
 	err = dpcm_be_dai_hw_free(fe, stream);
 	if (err < 0)
-		dev_err(fe->dev,"dpcm: hw_free FE failed %d\n", err);
+		dev_err(fe->dev,"ASoC: hw_free FE failed %d\n", err);
 
 	err = dpcm_be_dai_shutdown(fe, stream);
 	if (err < 0)
-		dev_err(fe->dev,"dpcm: shutdown FE failed %d\n", err);
+		dev_err(fe->dev,"ASoC: shutdown FE failed %d\n", err);
 
 	/* run the stream event for each BE */
 	dpcm_dapm_stream_event(fe, stream, SND_SOC_DAPM_STREAM_NOP);
@@ -1715,7 +1718,7 @@
 	enum snd_soc_dpcm_trigger trigger = fe->dai_link->trigger[stream];
 	int ret;
 
-	dev_dbg(fe->dev, "runtime %s open on FE %s\n",
+	dev_dbg(fe->dev, "ASoC: runtime %s open on FE %s\n",
 			stream ? "capture" : "playback", fe->dai_link->name);
 
 	/* Only start the BE if the FE is ready */
@@ -1761,22 +1764,22 @@
 
 	if (trigger == SND_SOC_DPCM_TRIGGER_BESPOKE) {
 		/* call trigger on the frontend - FE takes care of all BE triggers */
-		dev_dbg(fe->dev, "dpcm: bespoke trigger FE %s cmd start\n",
+		dev_dbg(fe->dev, "ASoC: bespoke trigger FE %s cmd start\n",
 				fe->dai_link->name);
 
 		ret = soc_pcm_bespoke_trigger(substream, SNDRV_PCM_TRIGGER_START);
 		if (ret < 0) {
-			dev_err(fe->dev,"dpcm: bespoke trigger FE failed %d\n", ret);
+			dev_err(fe->dev,"ASoC: bespoke trigger FE failed %d\n", ret);
 			goto hw_free;
 		}
 	} else {
-		dev_dbg(fe->dev, "dpcm: trigger FE %s cmd start\n",
+		dev_dbg(fe->dev, "ASoC: trigger FE %s cmd start\n",
 			fe->dai_link->name);
 
 		ret = dpcm_be_dai_trigger(fe, stream,
 					SNDRV_PCM_TRIGGER_START);
 		if (ret < 0) {
-			dev_err(fe->dev,"dpcm: trigger FE failed %d\n", ret);
+			dev_err(fe->dev,"ASoC: trigger FE failed %d\n", ret);
 			goto hw_free;
 		}
 	}
@@ -1805,7 +1808,7 @@
 	fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_BE;
 	ret = dpcm_run_update_startup(fe, stream);
 	if (ret < 0)
-		dev_err(fe->dev, "failed to startup some BEs\n");
+		dev_err(fe->dev, "ASoC: failed to startup some BEs\n");
 	fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
 
 	return ret;
@@ -1818,7 +1821,7 @@
 	fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_BE;
 	ret = dpcm_run_update_shutdown(fe, stream);
 	if (ret < 0)
-		dev_err(fe->dev, "failed to shutdown some BEs\n");
+		dev_err(fe->dev, "ASoC: failed to shutdown some BEs\n");
 	fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
 
 	return ret;
@@ -1853,7 +1856,7 @@
 			continue;
 
 		/* DAPM sync will call this to update DSP paths */
-		dev_dbg(fe->dev, "DPCM runtime update for FE %s\n",
+		dev_dbg(fe->dev, "ASoC: DPCM runtime update for FE %s\n",
 			fe->dai_link->name);
 
 		/* skip if FE doesn't have playback capability */
@@ -1862,7 +1865,7 @@
 
 		paths = dpcm_path_get(fe, SNDRV_PCM_STREAM_PLAYBACK, &list);
 		if (paths < 0) {
-			dev_warn(fe->dev, "%s no valid %s path\n",
+			dev_warn(fe->dev, "ASoC: %s no valid %s path\n",
 					fe->dai_link->name,  "playback");
 			mutex_unlock(&card->mutex);
 			return paths;
@@ -1891,7 +1894,7 @@
 
 		paths = dpcm_path_get(fe, SNDRV_PCM_STREAM_CAPTURE, &list);
 		if (paths < 0) {
-			dev_warn(fe->dev, "%s no valid %s path\n",
+			dev_warn(fe->dev, "ASoC: %s no valid %s path\n",
 					fe->dai_link->name,  "capture");
 			mutex_unlock(&card->mutex);
 			return paths;
@@ -1934,7 +1937,7 @@
 		if (be->dai_link->ignore_suspend)
 			continue;
 
-		dev_dbg(be->dev, "BE digital mute %s\n", be->dai_link->name);
+		dev_dbg(be->dev, "ASoC: BE digital mute %s\n", be->dai_link->name);
 
 		if (drv->ops->digital_mute && dai->playback_active)
 				drv->ops->digital_mute(dai, mute);
@@ -1955,7 +1958,7 @@
 	fe->dpcm[stream].runtime = fe_substream->runtime;
 
 	if (dpcm_path_get(fe, stream, &list) <= 0) {
-		dev_dbg(fe->dev, "asoc: %s no valid %s route\n",
+		dev_dbg(fe->dev, "ASoC: %s no valid %s route\n",
 			fe->dai_link->name, stream ? "capture" : "playback");
 	}
 
@@ -2039,11 +2042,11 @@
 			capture, &pcm);
 	}
 	if (ret < 0) {
-		dev_err(rtd->card->dev, "can't create pcm for %s\n",
+		dev_err(rtd->card->dev, "ASoC: can't create pcm for %s\n",
 			rtd->dai_link->name);
 		return ret;
 	}
-	dev_dbg(rtd->card->dev, "registered pcm #%d %s\n",num, new_name);
+	dev_dbg(rtd->card->dev, "ASoC: registered pcm #%d %s\n",num, new_name);
 
 	/* DAPM dai link stream work */
 	INIT_DELAYED_WORK(&rtd->delayed_work, close_delayed_work);
@@ -2097,7 +2100,9 @@
 	if (platform->driver->pcm_new) {
 		ret = platform->driver->pcm_new(rtd);
 		if (ret < 0) {
-			dev_err(platform->dev, "pcm constructor failed\n");
+			dev_err(platform->dev,
+				"ASoC: pcm constructor failed: %d\n",
+				ret);
 			return ret;
 		}
 	}
diff --git a/sound/soc/soc-utils.c b/sound/soc/soc-utils.c
index 6005370..fe4541d 100644
--- a/sound/soc/soc-utils.c
+++ b/sound/soc/soc-utils.c
@@ -94,7 +94,7 @@
 	.name = "snd-soc-dummy-dai",
 };
 
-static __devinit int snd_soc_dummy_probe(struct platform_device *pdev)
+static int snd_soc_dummy_probe(struct platform_device *pdev)
 {
 	int ret;
 
@@ -111,7 +111,7 @@
 	return ret;
 }
 
-static __devexit int snd_soc_dummy_remove(struct platform_device *pdev)
+static int snd_soc_dummy_remove(struct platform_device *pdev)
 {
 	snd_soc_unregister_platform(&pdev->dev);
 	snd_soc_unregister_codec(&pdev->dev);
@@ -125,7 +125,7 @@
 		.owner = THIS_MODULE,
 	},
 	.probe = snd_soc_dummy_probe,
-	.remove = __devexit_p(snd_soc_dummy_remove),
+	.remove = snd_soc_dummy_remove,
 };
 
 static struct platform_device *soc_dummy_dev;
diff --git a/sound/soc/spear/spear_pcm.c b/sound/soc/spear/spear_pcm.c
index 8c7f237..9b76cc5 100644
--- a/sound/soc/spear/spear_pcm.c
+++ b/sound/soc/spear/spear_pcm.c
@@ -184,12 +184,12 @@
 	.pcm_free	=	spear_pcm_free,
 };
 
-static int __devinit spear_soc_platform_probe(struct platform_device *pdev)
+static int spear_soc_platform_probe(struct platform_device *pdev)
 {
 	return snd_soc_register_platform(&pdev->dev, &spear_soc_platform);
 }
 
-static int __devexit spear_soc_platform_remove(struct platform_device *pdev)
+static int spear_soc_platform_remove(struct platform_device *pdev)
 {
 	snd_soc_unregister_platform(&pdev->dev);
 
@@ -203,7 +203,7 @@
 	},
 
 	.probe = spear_soc_platform_probe,
-	.remove = __devexit_p(spear_soc_platform_remove),
+	.remove = spear_soc_platform_remove,
 };
 
 module_platform_driver(spear_pcm_driver);
diff --git a/sound/soc/tegra/tegra20_das.c b/sound/soc/tegra/tegra20_das.c
index bf99296..6543184 100644
--- a/sound/soc/tegra/tegra20_das.c
+++ b/sound/soc/tegra/tegra20_das.c
@@ -131,7 +131,7 @@
 	.cache_type = REGCACHE_RBTREE,
 };
 
-static int __devinit tegra20_das_probe(struct platform_device *pdev)
+static int tegra20_das_probe(struct platform_device *pdev)
 {
 	struct resource *res, *region;
 	void __iomem *regs;
@@ -200,7 +200,7 @@
 	return ret;
 }
 
-static int __devexit tegra20_das_remove(struct platform_device *pdev)
+static int tegra20_das_remove(struct platform_device *pdev)
 {
 	if (!das)
 		return -ENODEV;
@@ -210,14 +210,14 @@
 	return 0;
 }
 
-static const struct of_device_id tegra20_das_of_match[] __devinitconst = {
+static const struct of_device_id tegra20_das_of_match[] = {
 	{ .compatible = "nvidia,tegra20-das", },
 	{},
 };
 
 static struct platform_driver tegra20_das_driver = {
 	.probe = tegra20_das_probe,
-	.remove = __devexit_p(tegra20_das_remove),
+	.remove = tegra20_das_remove,
 	.driver = {
 		.name = DRV_NAME,
 		.owner = THIS_MODULE,
diff --git a/sound/soc/tegra/tegra20_i2s.c b/sound/soc/tegra/tegra20_i2s.c
index 0832e8a..caa772de 100644
--- a/sound/soc/tegra/tegra20_i2s.c
+++ b/sound/soc/tegra/tegra20_i2s.c
@@ -331,7 +331,7 @@
 	.cache_type = REGCACHE_RBTREE,
 };
 
-static __devinit int tegra20_i2s_platform_probe(struct platform_device *pdev)
+static int tegra20_i2s_platform_probe(struct platform_device *pdev)
 {
 	struct tegra20_i2s *i2s;
 	struct resource *mem, *memregion, *dmareq;
@@ -447,7 +447,7 @@
 	return ret;
 }
 
-static int __devexit tegra20_i2s_platform_remove(struct platform_device *pdev)
+static int tegra20_i2s_platform_remove(struct platform_device *pdev)
 {
 	struct tegra20_i2s *i2s = dev_get_drvdata(&pdev->dev);
 
@@ -463,12 +463,12 @@
 	return 0;
 }
 
-static const struct of_device_id tegra20_i2s_of_match[] __devinitconst = {
+static const struct of_device_id tegra20_i2s_of_match[] = {
 	{ .compatible = "nvidia,tegra20-i2s", },
 	{},
 };
 
-static const struct dev_pm_ops tegra20_i2s_pm_ops __devinitconst = {
+static const struct dev_pm_ops tegra20_i2s_pm_ops = {
 	SET_RUNTIME_PM_OPS(tegra20_i2s_runtime_suspend,
 			   tegra20_i2s_runtime_resume, NULL)
 };
@@ -481,7 +481,7 @@
 		.pm = &tegra20_i2s_pm_ops,
 	},
 	.probe = tegra20_i2s_platform_probe,
-	.remove = __devexit_p(tegra20_i2s_platform_remove),
+	.remove = tegra20_i2s_platform_remove,
 };
 module_platform_driver(tegra20_i2s_driver);
 
diff --git a/sound/soc/tegra/tegra20_spdif.c b/sound/soc/tegra/tegra20_spdif.c
index 3ebc867..04771d1 100644
--- a/sound/soc/tegra/tegra20_spdif.c
+++ b/sound/soc/tegra/tegra20_spdif.c
@@ -257,7 +257,7 @@
 	.cache_type = REGCACHE_RBTREE,
 };
 
-static __devinit int tegra20_spdif_platform_probe(struct platform_device *pdev)
+static int tegra20_spdif_platform_probe(struct platform_device *pdev)
 {
 	struct tegra20_spdif *spdif;
 	struct resource *mem, *memregion, *dmareq;
@@ -357,7 +357,7 @@
 	return ret;
 }
 
-static int __devexit tegra20_spdif_platform_remove(struct platform_device *pdev)
+static int tegra20_spdif_platform_remove(struct platform_device *pdev)
 {
 	struct tegra20_spdif *spdif = dev_get_drvdata(&pdev->dev);
 
@@ -373,7 +373,7 @@
 	return 0;
 }
 
-static const struct dev_pm_ops tegra20_spdif_pm_ops __devinitconst = {
+static const struct dev_pm_ops tegra20_spdif_pm_ops = {
 	SET_RUNTIME_PM_OPS(tegra20_spdif_runtime_suspend,
 			   tegra20_spdif_runtime_resume, NULL)
 };
@@ -385,7 +385,7 @@
 		.pm = &tegra20_spdif_pm_ops,
 	},
 	.probe = tegra20_spdif_platform_probe,
-	.remove = __devexit_p(tegra20_spdif_platform_remove),
+	.remove = tegra20_spdif_platform_remove,
 };
 
 module_platform_driver(tegra20_spdif_driver);
diff --git a/sound/soc/tegra/tegra30_ahub.c b/sound/soc/tegra/tegra30_ahub.c
index 64b67a3..f354dc3 100644
--- a/sound/soc/tegra/tegra30_ahub.c
+++ b/sound/soc/tegra/tegra30_ahub.c
@@ -287,7 +287,7 @@
 }
 EXPORT_SYMBOL_GPL(tegra30_ahub_unset_rx_cif_source);
 
-static const char * const configlink_clocks[] __devinitconst = {
+static const char * const configlink_clocks[] = {
 	"i2s0",
 	"i2s1",
 	"i2s2",
@@ -299,7 +299,7 @@
 	"spdif_in",
 };
 
-struct of_dev_auxdata ahub_auxdata[] __devinitdata = {
+struct of_dev_auxdata ahub_auxdata[] = {
 	OF_DEV_AUXDATA("nvidia,tegra30-i2s", 0x70080300, "tegra30-i2s.0", NULL),
 	OF_DEV_AUXDATA("nvidia,tegra30-i2s", 0x70080400, "tegra30-i2s.1", NULL),
 	OF_DEV_AUXDATA("nvidia,tegra30-i2s", 0x70080500, "tegra30-i2s.2", NULL),
@@ -433,7 +433,7 @@
 	.cache_type = REGCACHE_RBTREE,
 };
 
-static int __devinit tegra30_ahub_probe(struct platform_device *pdev)
+static int tegra30_ahub_probe(struct platform_device *pdev)
 {
 	struct clk *clk;
 	int i;
@@ -585,7 +585,7 @@
 	return ret;
 }
 
-static int __devexit tegra30_ahub_remove(struct platform_device *pdev)
+static int tegra30_ahub_remove(struct platform_device *pdev)
 {
 	if (!ahub)
 		return -ENODEV;
@@ -602,19 +602,19 @@
 	return 0;
 }
 
-static const struct of_device_id tegra30_ahub_of_match[] __devinitconst = {
+static const struct of_device_id tegra30_ahub_of_match[] = {
 	{ .compatible = "nvidia,tegra30-ahub", },
 	{},
 };
 
-static const struct dev_pm_ops tegra30_ahub_pm_ops __devinitconst = {
+static const struct dev_pm_ops tegra30_ahub_pm_ops = {
 	SET_RUNTIME_PM_OPS(tegra30_ahub_runtime_suspend,
 			   tegra30_ahub_runtime_resume, NULL)
 };
 
 static struct platform_driver tegra30_ahub_driver = {
 	.probe = tegra30_ahub_probe,
-	.remove = __devexit_p(tegra30_ahub_remove),
+	.remove = tegra30_ahub_remove,
 	.driver = {
 		.name = DRV_NAME,
 		.owner = THIS_MODULE,
diff --git a/sound/soc/tegra/tegra30_i2s.c b/sound/soc/tegra/tegra30_i2s.c
index 4418422..27e91dd 100644
--- a/sound/soc/tegra/tegra30_i2s.c
+++ b/sound/soc/tegra/tegra30_i2s.c
@@ -391,7 +391,7 @@
 	.cache_type = REGCACHE_RBTREE,
 };
 
-static __devinit int tegra30_i2s_platform_probe(struct platform_device *pdev)
+static int tegra30_i2s_platform_probe(struct platform_device *pdev)
 {
 	struct tegra30_i2s *i2s;
 	u32 cif_ids[2];
@@ -492,7 +492,7 @@
 	return ret;
 }
 
-static int __devexit tegra30_i2s_platform_remove(struct platform_device *pdev)
+static int tegra30_i2s_platform_remove(struct platform_device *pdev)
 {
 	struct tegra30_i2s *i2s = dev_get_drvdata(&pdev->dev);
 
@@ -508,12 +508,12 @@
 	return 0;
 }
 
-static const struct of_device_id tegra30_i2s_of_match[] __devinitconst = {
+static const struct of_device_id tegra30_i2s_of_match[] = {
 	{ .compatible = "nvidia,tegra30-i2s", },
 	{},
 };
 
-static const struct dev_pm_ops tegra30_i2s_pm_ops __devinitconst = {
+static const struct dev_pm_ops tegra30_i2s_pm_ops = {
 	SET_RUNTIME_PM_OPS(tegra30_i2s_runtime_suspend,
 			   tegra30_i2s_runtime_resume, NULL)
 };
@@ -526,7 +526,7 @@
 		.pm = &tegra30_i2s_pm_ops,
 	},
 	.probe = tegra30_i2s_platform_probe,
-	.remove = __devexit_p(tegra30_i2s_platform_remove),
+	.remove = tegra30_i2s_platform_remove,
 };
 module_platform_driver(tegra30_i2s_driver);
 
diff --git a/sound/soc/tegra/tegra_alc5632.c b/sound/soc/tegra/tegra_alc5632.c
index 76cb1b3..c80adb9 100644
--- a/sound/soc/tegra/tegra_alc5632.c
+++ b/sound/soc/tegra/tegra_alc5632.c
@@ -150,7 +150,7 @@
 	.fully_routed = true,
 };
 
-static __devinit int tegra_alc5632_probe(struct platform_device *pdev)
+static int tegra_alc5632_probe(struct platform_device *pdev)
 {
 	struct device_node *np = pdev->dev.of_node;
 	struct snd_soc_card *card = &snd_soc_tegra_alc5632;
@@ -227,7 +227,7 @@
 	return ret;
 }
 
-static int __devexit tegra_alc5632_remove(struct platform_device *pdev)
+static int tegra_alc5632_remove(struct platform_device *pdev)
 {
 	struct snd_soc_card *card = platform_get_drvdata(pdev);
 	struct tegra_alc5632 *machine = snd_soc_card_get_drvdata(card);
@@ -242,7 +242,7 @@
 	return 0;
 }
 
-static const struct of_device_id tegra_alc5632_of_match[] __devinitconst = {
+static const struct of_device_id tegra_alc5632_of_match[] = {
 	{ .compatible = "nvidia,tegra-audio-alc5632", },
 	{},
 };
@@ -255,7 +255,7 @@
 		.of_match_table = tegra_alc5632_of_match,
 	},
 	.probe = tegra_alc5632_probe,
-	.remove = __devexit_p(tegra_alc5632_remove),
+	.remove = tegra_alc5632_remove,
 };
 module_platform_driver(tegra_alc5632_driver);
 
diff --git a/sound/soc/tegra/tegra_pcm.c b/sound/soc/tegra/tegra_pcm.c
index e187339..c925ab0 100644
--- a/sound/soc/tegra/tegra_pcm.c
+++ b/sound/soc/tegra/tegra_pcm.c
@@ -253,13 +253,13 @@
 	.pcm_free	= tegra_pcm_free,
 };
 
-int __devinit tegra_pcm_platform_register(struct device *dev)
+int tegra_pcm_platform_register(struct device *dev)
 {
 	return snd_soc_register_platform(dev, &tegra_pcm_platform);
 }
 EXPORT_SYMBOL_GPL(tegra_pcm_platform_register);
 
-void __devexit tegra_pcm_platform_unregister(struct device *dev)
+void tegra_pcm_platform_unregister(struct device *dev)
 {
 	snd_soc_unregister_platform(dev);
 }
diff --git a/sound/soc/tegra/tegra_wm8753.c b/sound/soc/tegra/tegra_wm8753.c
index ea9166d..c8ef88a6 100644
--- a/sound/soc/tegra/tegra_wm8753.c
+++ b/sound/soc/tegra/tegra_wm8753.c
@@ -122,7 +122,7 @@
 	.fully_routed = true,
 };
 
-static __devinit int tegra_wm8753_driver_probe(struct platform_device *pdev)
+static int tegra_wm8753_driver_probe(struct platform_device *pdev)
 {
 	struct snd_soc_card *card = &snd_soc_tegra_wm8753;
 	struct tegra_wm8753 *machine;
@@ -188,7 +188,7 @@
 	return ret;
 }
 
-static int __devexit tegra_wm8753_driver_remove(struct platform_device *pdev)
+static int tegra_wm8753_driver_remove(struct platform_device *pdev)
 {
 	struct snd_soc_card *card = platform_get_drvdata(pdev);
 	struct tegra_wm8753 *machine = snd_soc_card_get_drvdata(card);
@@ -200,7 +200,7 @@
 	return 0;
 }
 
-static const struct of_device_id tegra_wm8753_of_match[] __devinitconst = {
+static const struct of_device_id tegra_wm8753_of_match[] = {
 	{ .compatible = "nvidia,tegra-audio-wm8753", },
 	{},
 };
@@ -213,7 +213,7 @@
 		.of_match_table = tegra_wm8753_of_match,
 	},
 	.probe = tegra_wm8753_driver_probe,
-	.remove = __devexit_p(tegra_wm8753_driver_remove),
+	.remove = tegra_wm8753_driver_remove,
 };
 module_platform_driver(tegra_wm8753_driver);
 
diff --git a/sound/soc/tegra/tegra_wm8903.c b/sound/soc/tegra/tegra_wm8903.c
index cee13b7..bbd79bf 100644
--- a/sound/soc/tegra/tegra_wm8903.c
+++ b/sound/soc/tegra/tegra_wm8903.c
@@ -252,7 +252,7 @@
 	.fully_routed = true,
 };
 
-static __devinit int tegra_wm8903_driver_probe(struct platform_device *pdev)
+static int tegra_wm8903_driver_probe(struct platform_device *pdev)
 {
 	struct device_node *np = pdev->dev.of_node;
 	struct snd_soc_card *card = &snd_soc_tegra_wm8903;
@@ -402,7 +402,7 @@
 	return ret;
 }
 
-static int __devexit tegra_wm8903_driver_remove(struct platform_device *pdev)
+static int tegra_wm8903_driver_remove(struct platform_device *pdev)
 {
 	struct snd_soc_card *card = platform_get_drvdata(pdev);
 	struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card);
@@ -417,7 +417,7 @@
 	return 0;
 }
 
-static const struct of_device_id tegra_wm8903_of_match[] __devinitconst = {
+static const struct of_device_id tegra_wm8903_of_match[] = {
 	{ .compatible = "nvidia,tegra-audio-wm8903", },
 	{},
 };
@@ -430,7 +430,7 @@
 		.of_match_table = tegra_wm8903_of_match,
 	},
 	.probe = tegra_wm8903_driver_probe,
-	.remove = __devexit_p(tegra_wm8903_driver_remove),
+	.remove = tegra_wm8903_driver_remove,
 };
 module_platform_driver(tegra_wm8903_driver);
 
diff --git a/sound/soc/tegra/trimslice.c b/sound/soc/tegra/trimslice.c
index e69a4f7..7fcf6c2 100644
--- a/sound/soc/tegra/trimslice.c
+++ b/sound/soc/tegra/trimslice.c
@@ -120,7 +120,7 @@
 	.fully_routed = true,
 };
 
-static __devinit int tegra_snd_trimslice_probe(struct platform_device *pdev)
+static int tegra_snd_trimslice_probe(struct platform_device *pdev)
 {
 	struct snd_soc_card *card = &snd_soc_trimslice;
 	struct tegra_trimslice *trimslice;
@@ -183,7 +183,7 @@
 	return ret;
 }
 
-static int __devexit tegra_snd_trimslice_remove(struct platform_device *pdev)
+static int tegra_snd_trimslice_remove(struct platform_device *pdev)
 {
 	struct snd_soc_card *card = platform_get_drvdata(pdev);
 	struct tegra_trimslice *trimslice = snd_soc_card_get_drvdata(card);
@@ -195,7 +195,7 @@
 	return 0;
 }
 
-static const struct of_device_id trimslice_of_match[] __devinitconst = {
+static const struct of_device_id trimslice_of_match[] = {
 	{ .compatible = "nvidia,tegra-audio-trimslice", },
 	{},
 };
@@ -208,7 +208,7 @@
 		.of_match_table = trimslice_of_match,
 	},
 	.probe = tegra_snd_trimslice_probe,
-	.remove = __devexit_p(tegra_snd_trimslice_remove),
+	.remove = tegra_snd_trimslice_remove,
 };
 module_platform_driver(tegra_snd_trimslice_driver);
 
diff --git a/sound/soc/txx9/txx9aclc-ac97.c b/sound/soc/txx9/txx9aclc-ac97.c
index 28db4ca..16ab696 100644
--- a/sound/soc/txx9/txx9aclc-ac97.c
+++ b/sound/soc/txx9/txx9aclc-ac97.c
@@ -170,7 +170,7 @@
 	},
 };
 
-static int __devinit txx9aclc_ac97_dev_probe(struct platform_device *pdev)
+static int txx9aclc_ac97_dev_probe(struct platform_device *pdev)
 {
 	struct txx9aclc_plat_drvdata *drvdata;
 	struct resource *r;
@@ -208,7 +208,7 @@
 	return snd_soc_register_dai(&pdev->dev, &txx9aclc_ac97_dai);
 }
 
-static int __devexit txx9aclc_ac97_dev_remove(struct platform_device *pdev)
+static int txx9aclc_ac97_dev_remove(struct platform_device *pdev)
 {
 	snd_soc_unregister_dai(&pdev->dev);
 	return 0;
@@ -216,7 +216,7 @@
 
 static struct platform_driver txx9aclc_ac97_driver = {
 	.probe		= txx9aclc_ac97_dev_probe,
-	.remove		= __devexit_p(txx9aclc_ac97_dev_remove),
+	.remove		= txx9aclc_ac97_dev_remove,
 	.driver		= {
 		.name	= "txx9aclc-ac97",
 		.owner	= THIS_MODULE,
diff --git a/sound/soc/txx9/txx9aclc.c b/sound/soc/txx9/txx9aclc.c
index b609d2c..45a6428 100644
--- a/sound/soc/txx9/txx9aclc.c
+++ b/sound/soc/txx9/txx9aclc.c
@@ -417,12 +417,12 @@
 	.pcm_free	= txx9aclc_pcm_free_dma_buffers,
 };
 
-static int __devinit txx9aclc_soc_platform_probe(struct platform_device *pdev)
+static int txx9aclc_soc_platform_probe(struct platform_device *pdev)
 {
 	return snd_soc_register_platform(&pdev->dev, &txx9aclc_soc_platform);
 }
 
-static int __devexit txx9aclc_soc_platform_remove(struct platform_device *pdev)
+static int txx9aclc_soc_platform_remove(struct platform_device *pdev)
 {
 	snd_soc_unregister_platform(&pdev->dev);
 	return 0;
@@ -435,7 +435,7 @@
 	},
 
 	.probe = txx9aclc_soc_platform_probe,
-	.remove = __devexit_p(txx9aclc_soc_platform_remove),
+	.remove = txx9aclc_soc_platform_remove,
 };
 
 module_platform_driver(txx9aclc_pcm_driver);
diff --git a/sound/soc/ux500/mop500.c b/sound/soc/ux500/mop500.c
index 54f7e25..ae69907 100644
--- a/sound/soc/ux500/mop500.c
+++ b/sound/soc/ux500/mop500.c
@@ -33,7 +33,7 @@
 		.stream_name = "ab8500_0",
 		.cpu_dai_name = "ux500-msp-i2s.1",
 		.codec_dai_name = "ab8500-codec-dai.0",
-		.platform_name = "ux500-pcm.0",
+		.platform_name = "ux500-msp-i2s.1",
 		.codec_name = "ab8500-codec.0",
 		.init = mop500_ab8500_machine_init,
 		.ops = mop500_ab8500_ops,
@@ -43,7 +43,7 @@
 		.stream_name = "ab8500_1",
 		.cpu_dai_name = "ux500-msp-i2s.3",
 		.codec_dai_name = "ab8500-codec-dai.1",
-		.platform_name = "ux500-pcm.0",
+		.platform_name = "ux500-msp-i2s.3",
 		.codec_name = "ab8500-codec.0",
 		.init = NULL,
 		.ops = mop500_ab8500_ops,
@@ -71,8 +71,8 @@
 	}
 }
 
-static int __devinit mop500_of_probe(struct platform_device *pdev,
-				struct device_node *np)
+static int mop500_of_probe(struct platform_device *pdev,
+			   struct device_node *np)
 {
 	struct device_node *codec_np, *msp_np[2];
 	int i;
@@ -99,7 +99,7 @@
 	return 0;
 }
 
-static int __devinit mop500_probe(struct platform_device *pdev)
+static int mop500_probe(struct platform_device *pdev)
 {
 	struct device_node *np = pdev->dev.of_node;
 	int ret;
@@ -136,7 +136,7 @@
 	return ret;
 }
 
-static int __devexit mop500_remove(struct platform_device *pdev)
+static int mop500_remove(struct platform_device *pdev)
 {
 	struct snd_soc_card *mop500_card = platform_get_drvdata(pdev);
 
@@ -161,7 +161,7 @@
 		.of_match_table = snd_soc_mop500_match,
 	},
 	.probe = mop500_probe,
-	.remove = __devexit_p(mop500_remove),
+	.remove = mop500_remove,
 };
 
 module_platform_driver(snd_soc_mop500_driver);
diff --git a/sound/soc/ux500/ux500_msp_dai.c b/sound/soc/ux500/ux500_msp_dai.c
index be94bf9..94a3e57 100644
--- a/sound/soc/ux500/ux500_msp_dai.c
+++ b/sound/soc/ux500/ux500_msp_dai.c
@@ -28,6 +28,7 @@
 
 #include "ux500_msp_i2s.h"
 #include "ux500_msp_dai.h"
+#include "ux500_pcm.h"
 
 static int setup_pcm_multichan(struct snd_soc_dai *dai,
 			struct ux500_msp_config *msp_config)
@@ -398,11 +399,28 @@
 		return ret;
 	}
 
-	/* Enable clock */
-	dev_dbg(dai->dev, "%s: Enabling MSP-clock.\n", __func__);
-	clk_enable(drvdata->clk);
+	/* Prepare and enable clocks */
+	dev_dbg(dai->dev, "%s: Enabling MSP-clocks.\n", __func__);
+	ret = clk_prepare_enable(drvdata->pclk);
+	if (ret) {
+		dev_err(drvdata->msp->dev,
+			"%s: Failed to prepare/enable pclk!\n", __func__);
+		goto err_pclk;
+	}
 
-	return 0;
+	ret = clk_prepare_enable(drvdata->clk);
+	if (ret) {
+		dev_err(drvdata->msp->dev,
+			"%s: Failed to prepare/enable clk!\n", __func__);
+		goto err_clk;
+	}
+
+	return ret;
+err_clk:
+	clk_disable_unprepare(drvdata->pclk);
+err_pclk:
+	regulator_disable(drvdata->reg_vape);
+	return ret;
 }
 
 static void ux500_msp_dai_shutdown(struct snd_pcm_substream *substream,
@@ -428,8 +446,9 @@
 			__func__, dai->id, snd_pcm_stream_str(substream));
 	}
 
-	/* Disable clock */
-	clk_disable(drvdata->clk);
+	/* Disable and unprepare clocks */
+	clk_disable_unprepare(drvdata->clk);
+	clk_disable_unprepare(drvdata->pclk);
 
 	/* Disable regulator */
 	ret = regulator_disable(drvdata->reg_vape);
@@ -749,7 +768,7 @@
 	},
 };
 
-static int __devinit ux500_msp_drv_probe(struct platform_device *pdev)
+static int ux500_msp_drv_probe(struct platform_device *pdev)
 {
 	struct ux500_msp_i2s_drvdata *drvdata;
 	int ret = 0;
@@ -780,6 +799,14 @@
 	}
 	prcmu_qos_add_requirement(PRCMU_QOS_APE_OPP, (char *)pdev->name, 50);
 
+	drvdata->pclk = clk_get(&pdev->dev, "apb_pclk");
+	if (IS_ERR(drvdata->pclk)) {
+		ret = (int)PTR_ERR(drvdata->pclk);
+		dev_err(&pdev->dev, "%s: ERROR: clk_get of pclk failed (%d)!\n",
+			__func__, ret);
+		goto err_pclk;
+	}
+
 	drvdata->clk = clk_get(&pdev->dev, NULL);
 	if (IS_ERR(drvdata->clk)) {
 		ret = (int)PTR_ERR(drvdata->clk);
@@ -806,27 +833,41 @@
 		goto err_init_msp;
 	}
 
+	ret = ux500_pcm_register_platform(pdev);
+	if (ret < 0) {
+		dev_err(&pdev->dev,
+			"Error: %s: Failed to register PCM platform device!\n",
+			__func__);
+		goto err_reg_plat;
+	}
+
 	return 0;
 
+err_reg_plat:
+	snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(ux500_msp_dai_drv));
 err_init_msp:
 	clk_put(drvdata->clk);
-
 err_clk:
+	clk_put(drvdata->pclk);
+err_pclk:
 	devm_regulator_put(drvdata->reg_vape);
 
 	return ret;
 }
 
-static int __devexit ux500_msp_drv_remove(struct platform_device *pdev)
+static int ux500_msp_drv_remove(struct platform_device *pdev)
 {
 	struct ux500_msp_i2s_drvdata *drvdata = dev_get_drvdata(&pdev->dev);
 
+	ux500_pcm_unregister_platform(pdev);
+
 	snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(ux500_msp_dai_drv));
 
 	devm_regulator_put(drvdata->reg_vape);
 	prcmu_qos_remove_requirement(PRCMU_QOS_APE_OPP, "ux500_msp_i2s");
 
 	clk_put(drvdata->clk);
+	clk_put(drvdata->pclk);
 
 	ux500_msp_i2s_cleanup_msp(pdev, drvdata->msp);
 
diff --git a/sound/soc/ux500/ux500_msp_dai.h b/sound/soc/ux500/ux500_msp_dai.h
index 98202a3..9c778d9 100644
--- a/sound/soc/ux500/ux500_msp_dai.h
+++ b/sound/soc/ux500/ux500_msp_dai.h
@@ -69,6 +69,7 @@
 	/* Clocks */
 	unsigned int master_clk;
 	struct clk *clk;
+	struct clk *pclk;
 
 	/* Regulators */
 	int vape_opp_constraint;
diff --git a/sound/soc/ux500/ux500_pcm.c b/sound/soc/ux500/ux500_pcm.c
index 1a04e24..846fa82 100644
--- a/sound/soc/ux500/ux500_pcm.c
+++ b/sound/soc/ux500/ux500_pcm.c
@@ -18,8 +18,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/dmaengine.h>
 #include <linux/slab.h>
-
-#include <plat/ste_dma40.h>
+#include <linux/platform_data/dma-ste-dma40.h>
 
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
@@ -282,7 +281,7 @@
 	.pcm_new        = ux500_pcm_new,
 };
 
-static int __devexit ux500_pcm_drv_probe(struct platform_device *pdev)
+int ux500_pcm_register_platform(struct platform_device *pdev)
 {
 	int ret;
 
@@ -296,23 +295,12 @@
 
 	return 0;
 }
+EXPORT_SYMBOL_GPL(ux500_pcm_register_platform);
 
-static int __devinit ux500_pcm_drv_remove(struct platform_device *pdev)
+int ux500_pcm_unregister_platform(struct platform_device *pdev)
 {
 	snd_soc_unregister_platform(&pdev->dev);
 
 	return 0;
 }
-
-static struct platform_driver ux500_pcm_driver = {
-	.driver = {
-		.name = "ux500-pcm",
-		.owner = THIS_MODULE,
-	},
-
-	.probe = ux500_pcm_drv_probe,
-	.remove = __devexit_p(ux500_pcm_drv_remove),
-};
-module_platform_driver(ux500_pcm_driver);
-
-MODULE_LICENSE("GPL v2");
+EXPORT_SYMBOL_GPL(ux500_pcm_unregister_platform);
diff --git a/sound/soc/ux500/ux500_pcm.h b/sound/soc/ux500/ux500_pcm.h
index 77ed44d..76d3444 100644
--- a/sound/soc/ux500/ux500_pcm.h
+++ b/sound/soc/ux500/ux500_pcm.h
@@ -32,4 +32,7 @@
 #define UX500_PLATFORM_PERIODS_MAX		48
 #define UX500_PLATFORM_BUFFER_BYTES_MAX		(2048 * PAGE_SIZE)
 
+int ux500_pcm_register_platform(struct platform_device *pdev);
+int ux500_pcm_unregister_platform(struct platform_device *pdev);
+
 #endif
diff --git a/sound/sparc/amd7930.c b/sound/sparc/amd7930.c
index 5701787..174d21f 100644
--- a/sound/sparc/amd7930.c
+++ b/sound/sparc/amd7930.c
@@ -755,7 +755,7 @@
 	.pointer	=	snd_amd7930_capture_pointer,
 };
 
-static int __devinit snd_amd7930_pcm(struct snd_amd7930 *amd)
+static int snd_amd7930_pcm(struct snd_amd7930 *amd)
 {
 	struct snd_pcm *pcm;
 	int err;
@@ -854,7 +854,7 @@
 	return change;
 }
 
-static struct snd_kcontrol_new amd7930_controls[] __devinitdata = {
+static struct snd_kcontrol_new amd7930_controls[] = {
 	{
 		.iface		=	SNDRV_CTL_ELEM_IFACE_MIXER,
 		.name		=	"Monitor Volume",
@@ -884,7 +884,7 @@
 	},
 };
 
-static int __devinit snd_amd7930_mixer(struct snd_amd7930 *amd)
+static int snd_amd7930_mixer(struct snd_amd7930 *amd)
 {
 	struct snd_card *card;
 	int idx, err;
@@ -933,10 +933,10 @@
 	.dev_free	=	snd_amd7930_dev_free,
 };
 
-static int __devinit snd_amd7930_create(struct snd_card *card,
-					struct platform_device *op,
-					int irq, int dev,
-					struct snd_amd7930 **ramd)
+static int snd_amd7930_create(struct snd_card *card,
+			      struct platform_device *op,
+			      int irq, int dev,
+			      struct snd_amd7930 **ramd)
 {
 	struct snd_amd7930 *amd;
 	unsigned long flags;
@@ -1002,7 +1002,7 @@
 	return 0;
 }
 
-static int __devinit amd7930_sbus_probe(struct platform_device *op)
+static int amd7930_sbus_probe(struct platform_device *op)
 {
 	struct resource *rp = &op->resource[0];
 	static int dev_num;
diff --git a/sound/sparc/cs4231.c b/sound/sparc/cs4231.c
index f2eabd3..54aaad2 100644
--- a/sound/sparc/cs4231.c
+++ b/sound/sparc/cs4231.c
@@ -702,7 +702,7 @@
 	return 0;
 }
 
-static void __devinit snd_cs4231_init(struct snd_cs4231 *chip)
+static void snd_cs4231_init(struct snd_cs4231 *chip)
 {
 	unsigned long flags;
 
@@ -1019,7 +1019,7 @@
 	return bytes_to_frames(substream->runtime, ptr);
 }
 
-static int __devinit snd_cs4231_probe(struct snd_cs4231 *chip)
+static int snd_cs4231_probe(struct snd_cs4231 *chip)
 {
 	unsigned long flags;
 	int i;
@@ -1218,7 +1218,7 @@
 	.pointer	=	snd_cs4231_capture_pointer,
 };
 
-static int __devinit snd_cs4231_pcm(struct snd_card *card)
+static int snd_cs4231_pcm(struct snd_card *card)
 {
 	struct snd_cs4231 *chip = card->private_data;
 	struct snd_pcm *pcm;
@@ -1247,7 +1247,7 @@
 	return 0;
 }
 
-static int __devinit snd_cs4231_timer(struct snd_card *card)
+static int snd_cs4231_timer(struct snd_card *card)
 {
 	struct snd_cs4231 *chip = card->private_data;
 	struct snd_timer *timer;
@@ -1498,7 +1498,7 @@
   .private_value = (left_reg) | ((right_reg) << 8) | ((shift_left) << 16) | \
 		   ((shift_right) << 19) | ((mask) << 24) | ((invert) << 22) }
 
-static struct snd_kcontrol_new snd_cs4231_controls[] __devinitdata = {
+static struct snd_kcontrol_new snd_cs4231_controls[] = {
 CS4231_DOUBLE("PCM Playback Switch", 0, CS4231_LEFT_OUTPUT,
 		CS4231_RIGHT_OUTPUT, 7, 7, 1, 1),
 CS4231_DOUBLE("PCM Playback Volume", 0, CS4231_LEFT_OUTPUT,
@@ -1537,7 +1537,7 @@
 CS4231_SINGLE("Headphone Out Switch", 0, CS4231_PIN_CTRL, 7, 1, 1)
 };
 
-static int __devinit snd_cs4231_mixer(struct snd_card *card)
+static int snd_cs4231_mixer(struct snd_card *card)
 {
 	struct snd_cs4231 *chip = card->private_data;
 	int err, idx;
@@ -1558,7 +1558,7 @@
 
 static int dev;
 
-static int __devinit cs4231_attach_begin(struct snd_card **rcard)
+static int cs4231_attach_begin(struct snd_card **rcard)
 {
 	struct snd_card *card;
 	struct snd_cs4231 *chip;
@@ -1589,7 +1589,7 @@
 	return 0;
 }
 
-static int __devinit cs4231_attach_finish(struct snd_card *card)
+static int cs4231_attach_finish(struct snd_card *card)
 {
 	struct snd_cs4231 *chip = card->private_data;
 	int err;
@@ -1793,9 +1793,9 @@
 	.dev_free	=	snd_cs4231_sbus_dev_free,
 };
 
-static int __devinit snd_cs4231_sbus_create(struct snd_card *card,
-					    struct platform_device *op,
-					    int dev)
+static int snd_cs4231_sbus_create(struct snd_card *card,
+				  struct platform_device *op,
+				  int dev)
 {
 	struct snd_cs4231 *chip = card->private_data;
 	int err;
@@ -1856,7 +1856,7 @@
 	return 0;
 }
 
-static int __devinit cs4231_sbus_probe(struct platform_device *op)
+static int cs4231_sbus_probe(struct platform_device *op)
 {
 	struct resource *rp = &op->resource[0];
 	struct snd_card *card;
@@ -1959,9 +1959,9 @@
 	.dev_free	=	snd_cs4231_ebus_dev_free,
 };
 
-static int __devinit snd_cs4231_ebus_create(struct snd_card *card,
-					    struct platform_device *op,
-					    int dev)
+static int snd_cs4231_ebus_create(struct snd_card *card,
+				  struct platform_device *op,
+				  int dev)
 {
 	struct snd_cs4231 *chip = card->private_data;
 	int err;
@@ -2048,7 +2048,7 @@
 	return 0;
 }
 
-static int __devinit cs4231_ebus_probe(struct platform_device *op)
+static int cs4231_ebus_probe(struct platform_device *op)
 {
 	struct snd_card *card;
 	int err;
@@ -2072,7 +2072,7 @@
 }
 #endif
 
-static int __devinit cs4231_probe(struct platform_device *op)
+static int cs4231_probe(struct platform_device *op)
 {
 #ifdef EBUS_SUPPORT
 	if (!strcmp(op->dev.of_node->parent->name, "ebus"))
@@ -2086,7 +2086,7 @@
 	return -ENODEV;
 }
 
-static int __devexit cs4231_remove(struct platform_device *op)
+static int cs4231_remove(struct platform_device *op)
 {
 	struct snd_cs4231 *chip = dev_get_drvdata(&op->dev);
 
@@ -2115,7 +2115,7 @@
 		.of_match_table = cs4231_match,
 	},
 	.probe		= cs4231_probe,
-	.remove		= __devexit_p(cs4231_remove),
+	.remove		= cs4231_remove,
 };
 
 module_platform_driver(cs4231_driver);
diff --git a/sound/sparc/dbri.c b/sound/sparc/dbri.c
index ae35f53..75e6016 100644
--- a/sound/sparc/dbri.c
+++ b/sound/sparc/dbri.c
@@ -745,7 +745,7 @@
 }
 
 /* Lock must not be held before calling this */
-static void __devinit dbri_initialize(struct snd_dbri *dbri)
+static void dbri_initialize(struct snd_dbri *dbri)
 {
 	s32 *cmd;
 	u32 dma_addr;
@@ -1305,7 +1305,7 @@
  * Lock must not be held before calling it.
 
 */
-static __devinit void cs4215_setup_pipes(struct snd_dbri *dbri)
+static void cs4215_setup_pipes(struct snd_dbri *dbri)
 {
 	unsigned long flags;
 
@@ -1338,7 +1338,7 @@
 	dbri_cmdwait(dbri);
 }
 
-static __devinit int cs4215_init_data(struct cs4215 *mm)
+static int cs4215_init_data(struct cs4215 *mm)
 {
 	/*
 	 * No action, memory resetting only.
@@ -1630,7 +1630,7 @@
 /*
  *
  */
-static __devinit int cs4215_init(struct snd_dbri *dbri)
+static int cs4215_init(struct snd_dbri *dbri)
 {
 	u32 reg2 = sbus_readl(dbri->regs + REG2);
 	dprintk(D_MM, "cs4215_init: reg2=0x%x\n", reg2);
@@ -2217,7 +2217,7 @@
 	.pointer = snd_dbri_pointer,
 };
 
-static int __devinit snd_dbri_pcm(struct snd_card *card)
+static int snd_dbri_pcm(struct snd_card *card)
 {
 	struct snd_pcm *pcm;
 	int err;
@@ -2409,7 +2409,7 @@
   .private_value = (entry) | ((shift) << 8) | ((mask) << 16) |	\
 			((invert) << 24) },
 
-static struct snd_kcontrol_new dbri_controls[] __devinitdata = {
+static struct snd_kcontrol_new dbri_controls[] = {
 	{
 	 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	 .name  = "Playback Volume",
@@ -2436,7 +2436,7 @@
 	CS4215_SINGLE("Mic boost", 4, 4, 1, 1)
 };
 
-static int __devinit snd_dbri_mixer(struct snd_card *card)
+static int snd_dbri_mixer(struct snd_card *card)
 {
 	int idx, err;
 	struct snd_dbri *dbri;
@@ -2500,7 +2500,7 @@
 }
 #endif
 
-static void __devinit snd_dbri_proc(struct snd_card *card)
+static void snd_dbri_proc(struct snd_card *card)
 {
 	struct snd_dbri *dbri = card->private_data;
 	struct snd_info_entry *entry;
@@ -2523,9 +2523,9 @@
 */
 static void snd_dbri_free(struct snd_dbri *dbri);
 
-static int __devinit snd_dbri_create(struct snd_card *card,
-				     struct platform_device *op,
-				     int irq, int dev)
+static int snd_dbri_create(struct snd_card *card,
+			   struct platform_device *op,
+			   int irq, int dev)
 {
 	struct snd_dbri *dbri = card->private_data;
 	int err;
@@ -2593,7 +2593,7 @@
 				  (void *)dbri->dma, dbri->dma_dvma);
 }
 
-static int __devinit dbri_probe(struct platform_device *op)
+static int dbri_probe(struct platform_device *op)
 {
 	struct snd_dbri *dbri;
 	struct resource *rp;
@@ -2663,7 +2663,7 @@
 	return err;
 }
 
-static int __devexit dbri_remove(struct platform_device *op)
+static int dbri_remove(struct platform_device *op)
 {
 	struct snd_card *card = dev_get_drvdata(&op->dev);
 
@@ -2694,7 +2694,7 @@
 		.of_match_table = dbri_match,
 	},
 	.probe		= dbri_probe,
-	.remove		= __devexit_p(dbri_remove),
+	.remove		= dbri_remove,
 };
 
 module_platform_driver(dbri_sbus_driver);
diff --git a/sound/spi/at73c213.c b/sound/spi/at73c213.c
index c6500d0..4dd60d8 100644
--- a/sound/spi/at73c213.c
+++ b/sound/spi/at73c213.c
@@ -330,7 +330,7 @@
 	.pointer	= snd_at73c213_pcm_pointer,
 };
 
-static int __devinit snd_at73c213_pcm_new(struct snd_at73c213 *chip, int device)
+static int snd_at73c213_pcm_new(struct snd_at73c213 *chip, int device)
 {
 	struct snd_pcm *pcm;
 	int retval;
@@ -665,7 +665,7 @@
 			| (mask << 24) | (invert << 22))		\
 }
 
-static struct snd_kcontrol_new snd_at73c213_controls[] __devinitdata = {
+static struct snd_kcontrol_new snd_at73c213_controls[] = {
 AT73C213_STEREO("Master Playback Volume", 0, DAC_LMPG, DAC_RMPG, 0, 0, 0x1f, 1),
 AT73C213_STEREO("Master Playback Switch", 0, DAC_LMPG, DAC_RMPG, 5, 5, 1, 1),
 AT73C213_STEREO("PCM Playback Volume", 0, DAC_LLOG, DAC_RLOG, 0, 0, 0x1f, 1),
@@ -709,7 +709,7 @@
 AT73C213_MONO_SWITCH("Line Capture Switch", 0, DAC_CTRL, 0, 0x03, 0),
 };
 
-static int __devinit snd_at73c213_mixer(struct snd_at73c213 *chip)
+static int snd_at73c213_mixer(struct snd_at73c213 *chip)
 {
 	struct snd_card *card;
 	int errval, idx;
@@ -744,7 +744,7 @@
 /*
  * Device functions
  */
-static int __devinit snd_at73c213_ssc_init(struct snd_at73c213 *chip)
+static int snd_at73c213_ssc_init(struct snd_at73c213 *chip)
 {
 	/*
 	 * Continuous clock output.
@@ -774,7 +774,7 @@
 	return 0;
 }
 
-static int __devinit snd_at73c213_chip_init(struct snd_at73c213 *chip)
+static int snd_at73c213_chip_init(struct snd_at73c213 *chip)
 {
 	int retval;
 	unsigned char dac_ctrl = 0;
@@ -879,8 +879,8 @@
 	return 0;
 }
 
-static int __devinit snd_at73c213_dev_init(struct snd_card *card,
-					 struct spi_device *spi)
+static int snd_at73c213_dev_init(struct snd_card *card,
+				 struct spi_device *spi)
 {
 	static struct snd_device_ops ops = {
 		.dev_free	= snd_at73c213_dev_free,
@@ -940,7 +940,7 @@
 	return retval;
 }
 
-static int __devinit snd_at73c213_probe(struct spi_device *spi)
+static int snd_at73c213_probe(struct spi_device *spi)
 {
 	struct snd_card			*card;
 	struct snd_at73c213		*chip;
@@ -1007,7 +1007,7 @@
 	return retval;
 }
 
-static int __devexit snd_at73c213_remove(struct spi_device *spi)
+static int snd_at73c213_remove(struct spi_device *spi)
 {
 	struct snd_card *card = dev_get_drvdata(&spi->dev);
 	struct snd_at73c213 *chip = card->private_data;
@@ -1109,7 +1109,7 @@
 	.probe		= snd_at73c213_probe,
 	.suspend	= snd_at73c213_suspend,
 	.resume		= snd_at73c213_resume,
-	.remove		= __devexit_p(snd_at73c213_remove),
+	.remove		= snd_at73c213_remove,
 };
 
 module_spi_driver(at73c213_driver);
diff --git a/sound/usb/6fire/chip.c b/sound/usb/6fire/chip.c
index fc8cc82..4394ae7 100644
--- a/sound/usb/6fire/chip.c
+++ b/sound/usb/6fire/chip.c
@@ -82,8 +82,8 @@
 	}
 }
 
-static int __devinit usb6fire_chip_probe(struct usb_interface *intf,
-		const struct usb_device_id *usb_id)
+static int usb6fire_chip_probe(struct usb_interface *intf,
+			       const struct usb_device_id *usb_id)
 {
 	int ret;
 	int i;
diff --git a/sound/usb/6fire/comm.c b/sound/usb/6fire/comm.c
index 6c3d531..9e6e3ff 100644
--- a/sound/usb/6fire/comm.c
+++ b/sound/usb/6fire/comm.c
@@ -125,16 +125,17 @@
 	return usb6fire_comm_send_buffer(buffer, rt->chip->dev);
 }
 
-int __devinit usb6fire_comm_init(struct sfire_chip *chip)
+int usb6fire_comm_init(struct sfire_chip *chip)
 {
 	struct comm_runtime *rt = kzalloc(sizeof(struct comm_runtime),
 			GFP_KERNEL);
-	struct urb *urb = &rt->receiver;
+	struct urb *urb;
 	int ret;
 
 	if (!rt)
 		return -ENOMEM;
 
+	urb = &rt->receiver;
 	rt->serial = 1;
 	rt->chip = chip;
 	usb_init_urb(urb);
diff --git a/sound/usb/6fire/comm.h b/sound/usb/6fire/comm.h
index d2af0a5..6a0840b 100644
--- a/sound/usb/6fire/comm.h
+++ b/sound/usb/6fire/comm.h
@@ -36,7 +36,7 @@
 			u8 vh, u8 vl);
 };
 
-int __devinit usb6fire_comm_init(struct sfire_chip *chip);
+int usb6fire_comm_init(struct sfire_chip *chip);
 void usb6fire_comm_abort(struct sfire_chip *chip);
 void usb6fire_comm_destroy(struct sfire_chip *chip);
 #endif /* USB6FIRE_COMM_H */
diff --git a/sound/usb/6fire/control.c b/sound/usb/6fire/control.c
index 07ed914..f6434c2 100644
--- a/sound/usb/6fire/control.c
+++ b/sound/usb/6fire/control.c
@@ -411,7 +411,7 @@
 	return 0;
 }
 
-static struct __devinitdata snd_kcontrol_new vol_elements[] = {
+static struct snd_kcontrol_new vol_elements[] = {
 	{
 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 		.name = "Analog Playback Volume",
@@ -451,7 +451,7 @@
 	{}
 };
 
-static struct __devinitdata snd_kcontrol_new mute_elements[] = {
+static struct snd_kcontrol_new mute_elements[] = {
 	{
 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 		.name = "Analog Playback Switch",
@@ -485,7 +485,7 @@
 	{}
 };
 
-static struct __devinitdata snd_kcontrol_new elements[] = {
+static struct snd_kcontrol_new elements[] = {
 	{
 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 		.name = "Line/Phono Capture Route",
@@ -561,7 +561,7 @@
 	return 0;
 }
 
-int __devinit usb6fire_control_init(struct sfire_chip *chip)
+int usb6fire_control_init(struct sfire_chip *chip)
 {
 	int i;
 	int ret;
diff --git a/sound/usb/6fire/control.h b/sound/usb/6fire/control.h
index 9a596d9..5a40ba1 100644
--- a/sound/usb/6fire/control.h
+++ b/sound/usb/6fire/control.h
@@ -50,7 +50,7 @@
 	u8 ivol_updated;
 };
 
-int __devinit usb6fire_control_init(struct sfire_chip *chip);
+int usb6fire_control_init(struct sfire_chip *chip);
 void usb6fire_control_abort(struct sfire_chip *chip);
 void usb6fire_control_destroy(struct sfire_chip *chip);
 #endif /* USB6FIRE_CONTROL_H */
diff --git a/sound/usb/6fire/firmware.h b/sound/usb/6fire/firmware.h
index 0085698..c109c4f 100644
--- a/sound/usb/6fire/firmware.h
+++ b/sound/usb/6fire/firmware.h
@@ -22,6 +22,6 @@
 	FW_NOT_READY = 1
 };
 
-int __devinit usb6fire_fw_init(struct usb_interface *intf);
+int usb6fire_fw_init(struct usb_interface *intf);
 #endif /* USB6FIRE_FIRMWARE_H */
 
diff --git a/sound/usb/6fire/midi.c b/sound/usb/6fire/midi.c
index f0e5179..2672242 100644
--- a/sound/usb/6fire/midi.c
+++ b/sound/usb/6fire/midi.c
@@ -146,7 +146,7 @@
 	.trigger = usb6fire_midi_in_trigger
 };
 
-int __devinit usb6fire_midi_init(struct sfire_chip *chip)
+int usb6fire_midi_init(struct sfire_chip *chip)
 {
 	int ret;
 	struct midi_runtime *rt = kzalloc(sizeof(struct midi_runtime),
diff --git a/sound/usb/6fire/midi.h b/sound/usb/6fire/midi.h
index 5114ecc..c321006 100644
--- a/sound/usb/6fire/midi.h
+++ b/sound/usb/6fire/midi.h
@@ -38,7 +38,7 @@
 	void (*in_received)(struct midi_runtime *rt, u8 *data, int length);
 };
 
-int __devinit usb6fire_midi_init(struct sfire_chip *chip);
+int usb6fire_midi_init(struct sfire_chip *chip);
 void usb6fire_midi_abort(struct sfire_chip *chip);
 void usb6fire_midi_destroy(struct sfire_chip *chip);
 #endif /* USB6FIRE_MIDI_H */
diff --git a/sound/usb/6fire/pcm.c b/sound/usb/6fire/pcm.c
index c97d05f..e2ca12f 100644
--- a/sound/usb/6fire/pcm.c
+++ b/sound/usb/6fire/pcm.c
@@ -135,6 +135,9 @@
 	struct control_runtime *ctrl_rt = rt->chip->control;
 
 	if (rt->stream_state != STREAM_DISABLED) {
+
+		rt->stream_state = STREAM_STOPPING;
+
 		for (i = 0; i < PCM_N_URBS; i++) {
 			usb_kill_urb(&rt->in_urbs[i].instance);
 			usb_kill_urb(&rt->out_urbs[i].instance);
@@ -559,9 +562,9 @@
 	.pointer = usb6fire_pcm_pointer,
 };
 
-static void __devinit usb6fire_pcm_init_urb(struct pcm_urb *urb,
-		struct sfire_chip *chip, bool in, int ep,
-		void (*handler)(struct urb *))
+static void usb6fire_pcm_init_urb(struct pcm_urb *urb,
+				  struct sfire_chip *chip, bool in, int ep,
+				  void (*handler)(struct urb *))
 {
 	urb->chip = chip;
 	usb_init_urb(&urb->instance);
@@ -578,7 +581,7 @@
 	urb->instance.number_of_packets = PCM_N_PACKETS_PER_URB;
 }
 
-int __devinit usb6fire_pcm_init(struct sfire_chip *chip)
+int usb6fire_pcm_init(struct sfire_chip *chip)
 {
 	int i;
 	int ret;
diff --git a/sound/usb/6fire/pcm.h b/sound/usb/6fire/pcm.h
index 3104301..9b01133 100644
--- a/sound/usb/6fire/pcm.h
+++ b/sound/usb/6fire/pcm.h
@@ -69,7 +69,7 @@
 	bool stream_wait_cond;
 };
 
-int __devinit usb6fire_pcm_init(struct sfire_chip *chip);
+int usb6fire_pcm_init(struct sfire_chip *chip);
 void usb6fire_pcm_abort(struct sfire_chip *chip);
 void usb6fire_pcm_destroy(struct sfire_chip *chip);
 #endif /* USB6FIRE_PCM_H */
diff --git a/sound/usb/Kconfig b/sound/usb/Kconfig
index ff77b28..225dfd7 100644
--- a/sound/usb/Kconfig
+++ b/sound/usb/Kconfig
@@ -90,7 +90,7 @@
 
 config SND_USB_US122L
 	tristate "Tascam US-122L USB driver"
-	depends on X86 && EXPERIMENTAL
+	depends on X86
 	select SND_HWDEP
 	select SND_RAWMIDI
 	help
diff --git a/sound/usb/caiaq/control.c b/sound/usb/caiaq/control.c
index 00e5d0a..adb8d03 100644
--- a/sound/usb/caiaq/control.c
+++ b/sound/usb/caiaq/control.c
@@ -137,7 +137,7 @@
 	return 1;
 }
 
-static struct snd_kcontrol_new kcontrol_template __devinitdata = {
+static struct snd_kcontrol_new kcontrol_template = {
 	.iface = SNDRV_CTL_ELEM_IFACE_HWDEP,
 	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
 	.index = 0,
@@ -489,8 +489,8 @@
 	{ "LED: FX2: Mode",			133 | CNT_INTVAL },
 };
 
-static int __devinit add_controls(struct caiaq_controller *c, int num,
-				  struct snd_usb_caiaqdev *dev)
+static int add_controls(struct caiaq_controller *c, int num,
+			struct snd_usb_caiaqdev *dev)
 {
 	int i, ret;
 	struct snd_kcontrol *kc;
@@ -507,7 +507,7 @@
 	return 0;
 }
 
-int __devinit snd_usb_caiaq_control_init(struct snd_usb_caiaqdev *dev)
+int snd_usb_caiaq_control_init(struct snd_usb_caiaqdev *dev)
 {
 	int ret = 0;
 
diff --git a/sound/usb/caiaq/device.c b/sound/usb/caiaq/device.c
index 7da0d0a..c828f81 100644
--- a/sound/usb/caiaq/device.c
+++ b/sound/usb/caiaq/device.c
@@ -289,7 +289,7 @@
 					  tmp, sizeof(tmp));
 }
 
-static void __devinit setup_card(struct snd_usb_caiaqdev *dev)
+static void setup_card(struct snd_usb_caiaqdev *dev)
 {
 	int ret;
 	char val[4];
@@ -407,7 +407,7 @@
 	return 0;
 }
 
-static int __devinit init_card(struct snd_usb_caiaqdev *dev)
+static int init_card(struct snd_usb_caiaqdev *dev)
 {
 	char *c, usbpath[32];
 	struct usb_device *usb_dev = dev->chip.dev;
@@ -481,7 +481,7 @@
 	return 0;
 }
 
-static int __devinit snd_probe(struct usb_interface *intf,
+static int snd_probe(struct usb_interface *intf,
 		     const struct usb_device_id *id)
 {
 	int ret;
diff --git a/sound/usb/card.c b/sound/usb/card.c
index dbf7999..ccf95cf 100644
--- a/sound/usb/card.c
+++ b/sound/usb/card.c
@@ -25,9 +25,6 @@
  *
  *  NOTES:
  *
- *   - async unlink should be used for avoiding the sleep inside lock.
- *     2.4.22 usb-uhci seems buggy for async unlinking and results in
- *     oops.  in such a cse, pass async_unlink=0 option.
  *   - the linked URBs would be preferred but not used so far because of
  *     the instability of unlinking.
  *   - type II is not supported properly.  there is no device which supports
@@ -83,7 +80,6 @@
 static int vid[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS-1)] = -1 };
 static int pid[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS-1)] = -1 };
 static int nrpacks = 8;		/* max. number of packets per urb */
-static bool async_unlink = 1;
 static int device_setup[SNDRV_CARDS]; /* device parameter for this card */
 static bool ignore_ctl_error;
 
@@ -99,8 +95,6 @@
 MODULE_PARM_DESC(pid, "Product ID for the USB audio device.");
 module_param(nrpacks, int, 0644);
 MODULE_PARM_DESC(nrpacks, "Max. number of packets per URB.");
-module_param(async_unlink, bool, 0444);
-MODULE_PARM_DESC(async_unlink, "Use async unlink mode.");
 module_param_array(device_setup, int, NULL, 0444);
 MODULE_PARM_DESC(device_setup, "Specific device setup (if needed).");
 module_param(ignore_ctl_error, bool, 0444);
@@ -345,7 +339,6 @@
 	chip->card = card;
 	chip->setup = device_setup[idx];
 	chip->nrpacks = nrpacks;
-	chip->async_unlink = async_unlink;
 	chip->probing = 1;
 
 	chip->usb_id = USB_ID(le16_to_cpu(dev->descriptor.idVendor),
diff --git a/sound/usb/card.h b/sound/usb/card.h
index 814cb35..8a751b4 100644
--- a/sound/usb/card.h
+++ b/sound/usb/card.h
@@ -27,6 +27,7 @@
 	unsigned int nr_rates;		/* number of rate table entries */
 	unsigned int *rate_table;	/* rate table */
 	unsigned char clock;		/* associated clock */
+	struct snd_pcm_chmap_elem *chmap; /* (optional) channel map */
 };
 
 struct snd_usb_substream;
@@ -109,6 +110,7 @@
 	struct audioformat *cur_audiofmt;	/* current audioformat pointer (for hw_params callback) */
 	snd_pcm_format_t pcm_format;	/* current audio format (for hw_params callback) */
 	unsigned int channels;		/* current number of channels (for hw_params callback) */
+	unsigned int channels_max;	/* max channels in the all audiofmts */
 	unsigned int cur_rate;		/* current rate (for hw_params callback) */
 	unsigned int period_bytes;	/* current period bytes (for hw_params callback) */
 	unsigned int altset_idx;     /* USB data format: index of alternate setting */
diff --git a/sound/usb/endpoint.c b/sound/usb/endpoint.c
index 34de6f2..21049b8 100644
--- a/sound/usb/endpoint.c
+++ b/sound/usb/endpoint.c
@@ -485,15 +485,10 @@
 static int wait_clear_urbs(struct snd_usb_endpoint *ep)
 {
 	unsigned long end_time = jiffies + msecs_to_jiffies(1000);
-	unsigned int i;
 	int alive;
 
 	do {
-		alive = 0;
-		for (i = 0; i < ep->nurbs; i++)
-			if (test_bit(i, &ep->active_mask))
-				alive++;
-
+		alive = bitmap_weight(&ep->active_mask, ep->nurbs);
 		if (!alive)
 			break;
 
@@ -520,33 +515,24 @@
 /*
  * unlink active urbs.
  */
-static int deactivate_urbs(struct snd_usb_endpoint *ep, int force, int can_sleep)
+static int deactivate_urbs(struct snd_usb_endpoint *ep, bool force)
 {
 	unsigned int i;
-	int async;
 
 	if (!force && ep->chip->shutdown) /* to be sure... */
 		return -EBADFD;
 
-	async = !can_sleep && ep->chip->async_unlink;
-
 	clear_bit(EP_FLAG_RUNNING, &ep->flags);
 
 	INIT_LIST_HEAD(&ep->ready_playback_urbs);
 	ep->next_packet_read_pos = 0;
 	ep->next_packet_write_pos = 0;
 
-	if (!async && in_interrupt())
-		return 0;
-
 	for (i = 0; i < ep->nurbs; i++) {
 		if (test_bit(i, &ep->active_mask)) {
 			if (!test_and_set_bit(i, &ep->unlink_mask)) {
 				struct urb *u = ep->urb[i].urb;
-				if (async)
-					usb_unlink_urb(u);
-				else
-					usb_kill_urb(u);
+				usb_unlink_urb(u);
 			}
 		}
 	}
@@ -566,7 +552,7 @@
 	ep->prepare_data_urb = NULL;
 
 	/* stop urbs */
-	deactivate_urbs(ep, force, 1);
+	deactivate_urbs(ep, force);
 	wait_clear_urbs(ep);
 
 	for (i = 0; i < ep->nurbs; i++)
@@ -829,7 +815,7 @@
  *
  * Returns an error if the URB submission failed, 0 in all other cases.
  */
-int snd_usb_endpoint_start(struct snd_usb_endpoint *ep, int can_sleep)
+int snd_usb_endpoint_start(struct snd_usb_endpoint *ep, bool can_sleep)
 {
 	int err;
 	unsigned int i;
@@ -842,7 +828,7 @@
 		return 0;
 
 	/* just to be sure */
-	deactivate_urbs(ep, 0, can_sleep);
+	deactivate_urbs(ep, false);
 	if (can_sleep)
 		wait_clear_urbs(ep);
 
@@ -896,7 +882,7 @@
 __error:
 	clear_bit(EP_FLAG_RUNNING, &ep->flags);
 	ep->use_count--;
-	deactivate_urbs(ep, 0, 0);
+	deactivate_urbs(ep, false);
 	return -EPIPE;
 }
 
@@ -910,9 +896,11 @@
  * actually be deactivated.
  *
  * Must be balanced to calls of snd_usb_endpoint_start().
+ *
+ * The caller needs to synchronize the pending stop operation via
+ * snd_usb_endpoint_sync_pending_stop().
  */
-void snd_usb_endpoint_stop(struct snd_usb_endpoint *ep,
-			   int force, int can_sleep, int wait)
+void snd_usb_endpoint_stop(struct snd_usb_endpoint *ep)
 {
 	if (!ep)
 		return;
@@ -921,16 +909,12 @@
 		return;
 
 	if (--ep->use_count == 0) {
-		deactivate_urbs(ep, force, can_sleep);
+		deactivate_urbs(ep, false);
 		ep->data_subs = NULL;
 		ep->sync_slave = NULL;
 		ep->retire_data_urb = NULL;
 		ep->prepare_data_urb = NULL;
-
-		if (wait)
-			wait_clear_urbs(ep);
-		else
-			set_bit(EP_FLAG_STOPPING, &ep->flags);
+		set_bit(EP_FLAG_STOPPING, &ep->flags);
 	}
 }
 
@@ -952,7 +936,7 @@
 	if (!ep)
 		return -EINVAL;
 
-	deactivate_urbs(ep, 1, 1);
+	deactivate_urbs(ep, true);
 	wait_clear_urbs(ep);
 
 	if (ep->use_count != 0)
@@ -1034,15 +1018,18 @@
 		/*
 		 * Iterate through the inbound packet and prepare the lengths
 		 * for the output packet. The OUT packet we are about to send
-		 * will have the same amount of payload bytes than the IN
-		 * packet we just received.
+		 * will have the same amount of payload bytes per stride as the
+		 * IN packet we just received. Since the actual size is scaled
+		 * by the stride, use the sender stride to calculate the length
+		 * in case the number of channels differ between the implicitly
+		 * fed-back endpoint and the synchronizing endpoint.
 		 */
 
 		out_packet->packets = in_ctx->packets;
 		for (i = 0; i < in_ctx->packets; i++) {
 			if (urb->iso_frame_desc[i].status == 0)
 				out_packet->packet_size[i] =
-					urb->iso_frame_desc[i].actual_length / ep->stride;
+					urb->iso_frame_desc[i].actual_length / sender->stride;
 			else
 				out_packet->packet_size[i] = 0;
 		}
diff --git a/sound/usb/endpoint.h b/sound/usb/endpoint.h
index 3d4c970..447902d 100644
--- a/sound/usb/endpoint.h
+++ b/sound/usb/endpoint.h
@@ -16,9 +16,8 @@
 				struct audioformat *fmt,
 				struct snd_usb_endpoint *sync_ep);
 
-int  snd_usb_endpoint_start(struct snd_usb_endpoint *ep, int can_sleep);
-void snd_usb_endpoint_stop(struct snd_usb_endpoint *ep,
-			   int force, int can_sleep, int wait);
+int  snd_usb_endpoint_start(struct snd_usb_endpoint *ep, bool can_sleep);
+void snd_usb_endpoint_stop(struct snd_usb_endpoint *ep);
 void snd_usb_endpoint_sync_pending_stop(struct snd_usb_endpoint *ep);
 int  snd_usb_endpoint_activate(struct snd_usb_endpoint *ep);
 int  snd_usb_endpoint_deactivate(struct snd_usb_endpoint *ep);
diff --git a/sound/usb/format.c b/sound/usb/format.c
index ddfef57..e831ee4 100644
--- a/sound/usb/format.c
+++ b/sound/usb/format.c
@@ -155,7 +155,7 @@
 	if (fmt[0] < offset + 1 + 3 * (nr_rates ? nr_rates : 2)) {
 		snd_printk(KERN_ERR "%d:%u:%d : invalid UAC_FORMAT_TYPE desc\n",
 				   chip->dev->devnum, fp->iface, fp->altsetting);
-		return -1;
+		return -EINVAL;
 	}
 
 	if (nr_rates) {
@@ -167,7 +167,7 @@
 		fp->rate_table = kmalloc(sizeof(int) * nr_rates, GFP_KERNEL);
 		if (fp->rate_table == NULL) {
 			snd_printk(KERN_ERR "cannot malloc\n");
-			return -1;
+			return -ENOMEM;
 		}
 
 		fp->nr_rates = 0;
@@ -198,7 +198,7 @@
 		}
 		if (!fp->nr_rates) {
 			hwc_debug("All rates were zero. Skipping format!\n");
-			return -1;
+			return -EINVAL;
 		}
 	} else {
 		/* continuous rates */
@@ -383,7 +383,7 @@
 		fp->formats = parse_audio_format_i_type(chip, fp, format,
 							fmt, protocol);
 		if (!fp->formats)
-			return -1;
+			return -EINVAL;
 	}
 
 	/* gather possible sample rates */
@@ -409,7 +409,7 @@
 	if (fp->channels < 1) {
 		snd_printk(KERN_ERR "%d:%u:%d : invalid channels %d\n",
 			   chip->dev->devnum, fp->iface, fp->altsetting, fp->channels);
-		return -1;
+		return -EINVAL;
 	}
 
 	return ret;
diff --git a/sound/usb/midi.c b/sound/usb/midi.c
index eeefbce..34b9bb7 100644
--- a/sound/usb/midi.c
+++ b/sound/usb/midi.c
@@ -116,6 +116,7 @@
 	struct list_head list;
 	struct timer_list error_timer;
 	spinlock_t disc_lock;
+	struct rw_semaphore disc_rwsem;
 	struct mutex mutex;
 	u32 usb_id;
 	int next_midi_device;
@@ -125,8 +126,10 @@
 		struct snd_usb_midi_in_endpoint *in;
 	} endpoints[MIDI_MAX_ENDPOINTS];
 	unsigned long input_triggered;
-	unsigned int opened;
+	bool autopm_reference;
+	unsigned int opened[2];
 	unsigned char disconnected;
+	unsigned char input_running;
 
 	struct snd_kcontrol *roland_load_ctl;
 };
@@ -148,7 +151,6 @@
 		struct snd_usb_midi_out_endpoint* ep;
 		struct snd_rawmidi_substream *substream;
 		int active;
-		bool autopm_reference;
 		uint8_t cable;		/* cable number << 4 */
 		uint8_t state;
 #define STATE_UNKNOWN	0
@@ -1033,29 +1035,58 @@
 	snd_usbmidi_input_start(&umidi->list);
 }
 
-static void substream_open(struct snd_rawmidi_substream *substream, int open)
+static int substream_open(struct snd_rawmidi_substream *substream, int dir,
+			  int open)
 {
 	struct snd_usb_midi* umidi = substream->rmidi->private_data;
 	struct snd_kcontrol *ctl;
+	int err;
+
+	down_read(&umidi->disc_rwsem);
+	if (umidi->disconnected) {
+		up_read(&umidi->disc_rwsem);
+		return open ? -ENODEV : 0;
+	}
 
 	mutex_lock(&umidi->mutex);
 	if (open) {
-		if (umidi->opened++ == 0 && umidi->roland_load_ctl) {
-			ctl = umidi->roland_load_ctl;
-			ctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE;
-			snd_ctl_notify(umidi->card,
+		if (!umidi->opened[0] && !umidi->opened[1]) {
+			err = usb_autopm_get_interface(umidi->iface);
+			umidi->autopm_reference = err >= 0;
+			if (err < 0 && err != -EACCES) {
+				mutex_unlock(&umidi->mutex);
+				up_read(&umidi->disc_rwsem);
+				return -EIO;
+			}
+			if (umidi->roland_load_ctl) {
+				ctl = umidi->roland_load_ctl;
+				ctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE;
+				snd_ctl_notify(umidi->card,
 				       SNDRV_CTL_EVENT_MASK_INFO, &ctl->id);
-			update_roland_altsetting(umidi);
+				update_roland_altsetting(umidi);
+			}
 		}
+		umidi->opened[dir]++;
+		if (umidi->opened[1])
+			snd_usbmidi_input_start(&umidi->list);
 	} else {
-		if (--umidi->opened == 0 && umidi->roland_load_ctl) {
-			ctl = umidi->roland_load_ctl;
-			ctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
-			snd_ctl_notify(umidi->card,
+		umidi->opened[dir]--;
+		if (!umidi->opened[1])
+			snd_usbmidi_input_stop(&umidi->list);
+		if (!umidi->opened[0] && !umidi->opened[1]) {
+			if (umidi->roland_load_ctl) {
+				ctl = umidi->roland_load_ctl;
+				ctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
+				snd_ctl_notify(umidi->card,
 				       SNDRV_CTL_EVENT_MASK_INFO, &ctl->id);
+			}
+			if (umidi->autopm_reference)
+				usb_autopm_put_interface(umidi->iface);
 		}
 	}
 	mutex_unlock(&umidi->mutex);
+	up_read(&umidi->disc_rwsem);
+	return 0;
 }
 
 static int snd_usbmidi_output_open(struct snd_rawmidi_substream *substream)
@@ -1063,7 +1094,6 @@
 	struct snd_usb_midi* umidi = substream->rmidi->private_data;
 	struct usbmidi_out_port* port = NULL;
 	int i, j;
-	int err;
 
 	for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i)
 		if (umidi->endpoints[i].out)
@@ -1076,25 +1106,15 @@
 		snd_BUG();
 		return -ENXIO;
 	}
-	err = usb_autopm_get_interface(umidi->iface);
-	port->autopm_reference = err >= 0;
-	if (err < 0 && err != -EACCES)
-		return -EIO;
+
 	substream->runtime->private_data = port;
 	port->state = STATE_UNKNOWN;
-	substream_open(substream, 1);
-	return 0;
+	return substream_open(substream, 0, 1);
 }
 
 static int snd_usbmidi_output_close(struct snd_rawmidi_substream *substream)
 {
-	struct snd_usb_midi* umidi = substream->rmidi->private_data;
-	struct usbmidi_out_port *port = substream->runtime->private_data;
-
-	substream_open(substream, 0);
-	if (port->autopm_reference)
-		usb_autopm_put_interface(umidi->iface);
-	return 0;
+	return substream_open(substream, 0, 0);
 }
 
 static void snd_usbmidi_output_trigger(struct snd_rawmidi_substream *substream, int up)
@@ -1147,14 +1167,12 @@
 
 static int snd_usbmidi_input_open(struct snd_rawmidi_substream *substream)
 {
-	substream_open(substream, 1);
-	return 0;
+	return substream_open(substream, 1, 1);
 }
 
 static int snd_usbmidi_input_close(struct snd_rawmidi_substream *substream)
 {
-	substream_open(substream, 0);
-	return 0;
+	return substream_open(substream, 1, 0);
 }
 
 static void snd_usbmidi_input_trigger(struct snd_rawmidi_substream *substream, int up)
@@ -1403,9 +1421,12 @@
 	 * a timer may submit an URB. To reliably break the cycle
 	 * a flag under lock must be used
 	 */
+	down_write(&umidi->disc_rwsem);
 	spin_lock_irq(&umidi->disc_lock);
 	umidi->disconnected = 1;
 	spin_unlock_irq(&umidi->disc_lock);
+	up_write(&umidi->disc_rwsem);
+
 	for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i) {
 		struct snd_usb_midi_endpoint* ep = &umidi->endpoints[i];
 		if (ep->out)
@@ -2060,12 +2081,15 @@
 	unsigned int i, j;
 
 	umidi = list_entry(p, struct snd_usb_midi, list);
+	if (!umidi->input_running)
+		return;
 	for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i) {
 		struct snd_usb_midi_endpoint* ep = &umidi->endpoints[i];
 		if (ep->in)
 			for (j = 0; j < INPUT_URBS; ++j)
 				usb_kill_urb(ep->in->urbs[j]);
 	}
+	umidi->input_running = 0;
 }
 
 static void snd_usbmidi_input_start_ep(struct snd_usb_midi_in_endpoint* ep)
@@ -2090,8 +2114,11 @@
 	int i;
 
 	umidi = list_entry(p, struct snd_usb_midi, list);
+	if (umidi->input_running || !umidi->opened[1])
+		return;
 	for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i)
 		snd_usbmidi_input_start_ep(umidi->endpoints[i].in);
+	umidi->input_running = 1;
 }
 
 /*
@@ -2117,6 +2144,7 @@
 	umidi->usb_protocol_ops = &snd_usbmidi_standard_ops;
 	init_timer(&umidi->error_timer);
 	spin_lock_init(&umidi->disc_lock);
+	init_rwsem(&umidi->disc_rwsem);
 	mutex_init(&umidi->mutex);
 	umidi->usb_id = USB_ID(le16_to_cpu(umidi->dev->descriptor.idVendor),
 			       le16_to_cpu(umidi->dev->descriptor.idProduct));
@@ -2229,9 +2257,6 @@
 	}
 
 	list_add_tail(&umidi->list, midi_list);
-
-	for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i)
-		snd_usbmidi_input_start_ep(umidi->endpoints[i].in);
 	return 0;
 }
 
diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c
index 298070e..ed4d89c8 100644
--- a/sound/usb/mixer.c
+++ b/sound/usb/mixer.c
@@ -382,6 +382,8 @@
 
 static int get_ctl_value(struct usb_mixer_elem_info *cval, int request, int validx, int *value_ret)
 {
+	validx += cval->idx_off;
+
 	return (cval->mixer->protocol == UAC_VERSION_1) ?
 		get_ctl_value_v1(cval, request, validx, value_ret) :
 		get_ctl_value_v2(cval, request, validx, value_ret);
@@ -432,6 +434,8 @@
 	unsigned char buf[2];
 	int idx = 0, val_len, err, timeout = 10;
 
+	validx += cval->idx_off;
+
 	if (cval->mixer->protocol == UAC_VERSION_1) {
 		val_len = cval->val_type >= USB_MIXER_S16 ? 2 : 1;
 	} else { /* UAC_VERSION_2 */
@@ -719,8 +723,19 @@
 			return 0;
 		}
 		case UAC1_PROCESSING_UNIT:
-		case UAC1_EXTENSION_UNIT: {
+		case UAC1_EXTENSION_UNIT:
+		/* UAC2_PROCESSING_UNIT_V2 */
+		/* UAC2_EFFECT_UNIT */ {
 			struct uac_processing_unit_descriptor *d = p1;
+
+			if (state->mixer->protocol == UAC_VERSION_2 &&
+				hdr[2] == UAC2_EFFECT_UNIT) {
+				/* UAC2/UAC1 unit IDs overlap here in an
+				 * uncompatible way. Ignore this unit for now.
+				 */
+				return 0;
+			}
+
 			if (d->bNrInPins) {
 				id = d->baSourceID[0];
 				break; /* continue to parse */
@@ -791,6 +806,33 @@
 				  struct snd_kcontrol *kctl)
 {
 	switch (cval->mixer->chip->usb_id) {
+	case USB_ID(0x0763, 0x2030): /* M-Audio Fast Track C400 */
+		if (strcmp(kctl->id.name, "Effect Duration") == 0) {
+			cval->min = 0x0000;
+			cval->max = 0xffff;
+			cval->res = 0x00e6;
+			break;
+		}
+		if (strcmp(kctl->id.name, "Effect Volume") == 0 ||
+		    strcmp(kctl->id.name, "Effect Feedback Volume") == 0) {
+			cval->min = 0x00;
+			cval->max = 0xff;
+			break;
+		}
+		if (strstr(kctl->id.name, "Effect Return") != NULL) {
+			cval->min = 0xb706;
+			cval->max = 0xff7b;
+			cval->res = 0x0073;
+			break;
+		}
+		if ((strstr(kctl->id.name, "Playback Volume") != NULL) ||
+			(strstr(kctl->id.name, "Effect Send") != NULL)) {
+			cval->min = 0xb5fb; /* -73 dB = 0xb6ff */
+			cval->max = 0xfcfe;
+			cval->res = 0x0073;
+		}
+		break;
+
 	case USB_ID(0x0763, 0x2081): /* M-Audio Fast Track Ultra 8R */
 	case USB_ID(0x0763, 0x2080): /* M-Audio Fast Track Ultra */
 		if (strcmp(kctl->id.name, "Effect Duration") == 0) {
@@ -1094,6 +1136,32 @@
 	return strlcat(kctl->id.name, str, sizeof(kctl->id.name));
 }
 
+/* A lot of headsets/headphones have a "Speaker" mixer. Make sure we
+   rename it to "Headphone". We determine if something is a headphone
+   similar to how udev determines form factor. */
+static void check_no_speaker_on_headset(struct snd_kcontrol *kctl,
+					struct snd_card *card)
+{
+	const char *names_to_check[] = {
+		"Headset", "headset", "Headphone", "headphone", NULL};
+	const char **s;
+	bool found = 0;
+
+	if (strcmp("Speaker", kctl->id.name))
+		return;
+
+	for (s = names_to_check; *s; s++)
+		if (strstr(card->shortname, *s)) {
+			found = 1;
+			break;
+		}
+
+	if (!found)
+		return;
+
+	strlcpy(kctl->id.name, "Headphone", sizeof(kctl->id.name));
+}
+
 static void build_feature_ctl(struct mixer_build *state, void *raw_desc,
 			      unsigned int ctl_mask, int control,
 			      struct usb_audio_term *iterm, int unitid,
@@ -1180,6 +1248,10 @@
 				len = snprintf(kctl->id.name, sizeof(kctl->id.name),
 					       "Feature %d", unitid);
 		}
+
+		if (!mapped_name)
+			check_no_speaker_on_headset(kctl, state->mixer->chip->card);
+
 		/* determine the stream direction:
 		 * if the connected output is USB stream, then it's likely a
 		 * capture stream.  otherwise it should be playback (hopefully :)
diff --git a/sound/usb/mixer.h b/sound/usb/mixer.h
index a7f3d45..aab80df 100644
--- a/sound/usb/mixer.h
+++ b/sound/usb/mixer.h
@@ -43,6 +43,7 @@
 	unsigned int id;
 	unsigned int control;	/* CS or ICN (high byte) */
 	unsigned int cmask; /* channel mask bitmap: 0 = master */
+	unsigned int idx_off; /* Control index offset */
 	unsigned int ch_readonly;
 	unsigned int master_readonly;
 	int channels;
diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c
index ae2b714..0422b13 100644
--- a/sound/usb/mixer_quirks.c
+++ b/sound/usb/mixer_quirks.c
@@ -63,11 +63,12 @@
  * Since there doesn't seem to be a devices that needs a multichannel
  * version, we keep it mono for simplicity.
  */
-static int snd_create_std_mono_ctl(struct usb_mixer_interface *mixer,
+static int snd_create_std_mono_ctl_offset(struct usb_mixer_interface *mixer,
 				unsigned int unitid,
 				unsigned int control,
 				unsigned int cmask,
 				int val_type,
+				unsigned int idx_off,
 				const char *name,
 				snd_kcontrol_tlv_rw_t *tlv_callback)
 {
@@ -85,6 +86,7 @@
 	cval->channels = 1;
 	cval->control = control;
 	cval->cmask = cmask;
+	cval->idx_off = idx_off;
 
 	/* get_min_max() is called only for integer volumes later,
 	 * so provide a short-cut for booleans */
@@ -120,6 +122,18 @@
 	return 0;
 }
 
+static int snd_create_std_mono_ctl(struct usb_mixer_interface *mixer,
+				unsigned int unitid,
+				unsigned int control,
+				unsigned int cmask,
+				int val_type,
+				const char *name,
+				snd_kcontrol_tlv_rw_t *tlv_callback)
+{
+	return snd_create_std_mono_ctl_offset(mixer, unitid, control, cmask,
+		val_type, 0 /* Offset */, name, tlv_callback);
+}
+
 /*
  * Create a set of standard UAC controls from a table
  */
@@ -416,6 +430,8 @@
 	}
 }
 
+/* ASUS Xonar U1 / U3 controls */
+
 static int snd_xonar_u1_switch_get(struct snd_kcontrol *kcontrol,
 				   struct snd_ctl_elem_value *ucontrol)
 {
@@ -621,11 +637,13 @@
 }
 
 /* M-Audio FastTrack Ultra quirks */
-/* FTU Effect switch */
+/* FTU Effect switch (also used by C400) */
 struct snd_ftu_eff_switch_priv_val {
 	struct usb_mixer_interface *mixer;
 	int cached_value;
 	int is_cached;
+	int bUnitID;
+	int validx;
 };
 
 static int snd_ftu_eff_switch_info(struct snd_kcontrol *kcontrol,
@@ -660,9 +678,8 @@
 	struct snd_ftu_eff_switch_priv_val *pval;
 	int err;
 	unsigned char value[2];
+	int id, validx;
 
-	const int id = 6;
-	const int validx = 1;
 	const int val_len = 2;
 
 	value[0] = 0x00;
@@ -684,6 +701,8 @@
 	if (snd_BUG_ON(!chip))
 		return -EINVAL;
 
+	id = pval->bUnitID;
+	validx = pval->validx;
 
 	down_read(&mixer->chip->shutdown_rwsem);
 	if (mixer->chip->shutdown)
@@ -714,10 +733,8 @@
 	struct usb_mixer_interface *mixer;
 	int changed, cur_val, err, new_val;
 	unsigned char value[2];
+	int id, validx;
 
-
-	const int id = 6;
-	const int validx = 1;
 	const int val_len = 2;
 
 	changed = 0;
@@ -735,6 +752,9 @@
 	if (snd_BUG_ON(!chip))
 		return -EINVAL;
 
+	id = pval->bUnitID;
+	validx = pval->validx;
+
 	if (!pval->is_cached) {
 		/* Read current value */
 		down_read(&mixer->chip->shutdown_rwsem);
@@ -779,7 +799,8 @@
 	return changed;
 }
 
-static int snd_ftu_create_effect_switch(struct usb_mixer_interface *mixer)
+static int snd_ftu_create_effect_switch(struct usb_mixer_interface *mixer,
+	int validx, int bUnitID)
 {
 	static struct snd_kcontrol_new template = {
 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
@@ -802,6 +823,8 @@
 	pval->cached_value = 0;
 	pval->is_cached = 0;
 	pval->mixer = mixer;
+	pval->bUnitID = bUnitID;
+	pval->validx = validx;
 
 	template.private_value = (unsigned long) pval;
 	kctl = snd_ctl_new1(&template, mixer->chip);
@@ -960,9 +983,10 @@
 	if (err < 0)
 		return err;
 
-	err = snd_ftu_create_effect_switch(mixer);
+	err = snd_ftu_create_effect_switch(mixer, 1, 6);
 	if (err < 0)
 		return err;
+
 	err = snd_ftu_create_effect_volume_ctl(mixer);
 	if (err < 0)
 		return err;
@@ -1005,6 +1029,178 @@
 	}
 }
 
+/* M-Audio Fast Track C400 */
+/* C400 volume controls, this control needs a volume quirk, see mixer.c */
+static int snd_c400_create_vol_ctls(struct usb_mixer_interface *mixer)
+{
+	char name[64];
+	unsigned int cmask, offset;
+	int out, chan, err;
+
+	const unsigned int id = 0x40;
+	const int val_type = USB_MIXER_S16;
+	const int control = 1;
+
+	for (chan = 0; chan < 10; chan++) {
+		for (out = 0; out < 6; out++) {
+			if (chan < 6) {
+				snprintf(name, sizeof(name),
+					"PCM%d-Out%d Playback Volume",
+					chan + 1, out + 1);
+			} else {
+				snprintf(name, sizeof(name),
+					"In%d-Out%d Playback Volume",
+					chan - 5, out + 1);
+			}
+
+			cmask = (out == 0) ? 0 : 1 << (out - 1);
+			offset = chan * 6;
+			err = snd_create_std_mono_ctl_offset(mixer, id, control,
+						cmask, val_type, offset, name,
+						&snd_usb_mixer_vol_tlv);
+			if (err < 0)
+				return err;
+		}
+	}
+
+	return 0;
+}
+
+/* This control needs a volume quirk, see mixer.c */
+static int snd_c400_create_effect_volume_ctl(struct usb_mixer_interface *mixer)
+{
+	static const char name[] = "Effect Volume";
+	const unsigned int id = 0x43;
+	const int val_type = USB_MIXER_U8;
+	const unsigned int control = 3;
+	const unsigned int cmask = 0;
+
+	return snd_create_std_mono_ctl(mixer, id, control, cmask, val_type,
+					name, snd_usb_mixer_vol_tlv);
+}
+
+/* This control needs a volume quirk, see mixer.c */
+static int snd_c400_create_effect_duration_ctl(struct usb_mixer_interface *mixer)
+{
+	static const char name[] = "Effect Duration";
+	const unsigned int id = 0x43;
+	const int val_type = USB_MIXER_S16;
+	const unsigned int control = 4;
+	const unsigned int cmask = 0;
+
+	return snd_create_std_mono_ctl(mixer, id, control, cmask, val_type,
+					name, snd_usb_mixer_vol_tlv);
+}
+
+/* This control needs a volume quirk, see mixer.c */
+static int snd_c400_create_effect_feedback_ctl(struct usb_mixer_interface *mixer)
+{
+	static const char name[] = "Effect Feedback Volume";
+	const unsigned int id = 0x43;
+	const int val_type = USB_MIXER_U8;
+	const unsigned int control = 5;
+	const unsigned int cmask = 0;
+
+	return snd_create_std_mono_ctl(mixer, id, control, cmask, val_type,
+					name, NULL);
+}
+
+static int snd_c400_create_effect_vol_ctls(struct usb_mixer_interface *mixer)
+{
+	char name[64];
+	unsigned int cmask;
+	int chan, err;
+
+	const unsigned int id = 0x42;
+	const int val_type = USB_MIXER_S16;
+	const int control = 1;
+
+	for (chan = 0; chan < 10; chan++) {
+		if (chan < 6) {
+			snprintf(name, sizeof(name),
+				"Effect Send DOut%d",
+				chan + 1);
+		} else {
+			snprintf(name, sizeof(name),
+				"Effect Send AIn%d",
+				chan - 5);
+		}
+
+		cmask = (chan == 0) ? 0 : 1 << (chan - 1);
+		err = snd_create_std_mono_ctl(mixer, id, control,
+						cmask, val_type, name,
+						&snd_usb_mixer_vol_tlv);
+		if (err < 0)
+			return err;
+	}
+
+	return 0;
+}
+
+static int snd_c400_create_effect_ret_vol_ctls(struct usb_mixer_interface *mixer)
+{
+	char name[64];
+	unsigned int cmask;
+	int chan, err;
+
+	const unsigned int id = 0x40;
+	const int val_type = USB_MIXER_S16;
+	const int control = 1;
+	const int chan_id[6] = { 0, 7, 2, 9, 4, 0xb };
+	const unsigned int offset = 0x3c;
+				/* { 0x3c, 0x43, 0x3e, 0x45, 0x40, 0x47 } */
+
+	for (chan = 0; chan < 6; chan++) {
+		snprintf(name, sizeof(name),
+			"Effect Return %d",
+			chan + 1);
+
+		cmask = (chan_id[chan] == 0) ? 0 : 1 << (chan_id[chan] - 1);
+		err = snd_create_std_mono_ctl_offset(mixer, id, control,
+						cmask, val_type, offset, name,
+						&snd_usb_mixer_vol_tlv);
+		if (err < 0)
+			return err;
+	}
+
+	return 0;
+}
+
+static int snd_c400_create_mixer(struct usb_mixer_interface *mixer)
+{
+	int err;
+
+	err = snd_c400_create_vol_ctls(mixer);
+	if (err < 0)
+		return err;
+
+	err = snd_c400_create_effect_vol_ctls(mixer);
+	if (err < 0)
+		return err;
+
+	err = snd_c400_create_effect_ret_vol_ctls(mixer);
+	if (err < 0)
+		return err;
+
+	err = snd_ftu_create_effect_switch(mixer, 2, 0x43);
+	if (err < 0)
+		return err;
+
+	err = snd_c400_create_effect_volume_ctl(mixer);
+	if (err < 0)
+		return err;
+
+	err = snd_c400_create_effect_duration_ctl(mixer);
+	if (err < 0)
+		return err;
+
+	err = snd_c400_create_effect_feedback_ctl(mixer);
+	if (err < 0)
+		return err;
+
+	return 0;
+}
+
 /*
  * The mixer units for Ebox-44 are corrupt, and even where they
  * are valid they presents mono controls as L and R channels of
@@ -1102,13 +1298,18 @@
 					      snd_audigy2nx_proc_read);
 		break;
 
+	case USB_ID(0x0763, 0x2030): /* M-Audio Fast Track C400 */
+		err = snd_c400_create_mixer(mixer);
+		break;
+
 	case USB_ID(0x0763, 0x2080): /* M-Audio Fast Track Ultra */
 	case USB_ID(0x0763, 0x2081): /* M-Audio Fast Track Ultra 8R */
 		err = snd_ftu_create_mixer(mixer);
 		break;
 
-	case USB_ID(0x0b05, 0x1739):
-	case USB_ID(0x0b05, 0x1743):
+	case USB_ID(0x0b05, 0x1739): /* ASUS Xonar U1 */
+	case USB_ID(0x0b05, 0x1743): /* ASUS Xonar U1 (2) */
+	case USB_ID(0x0b05, 0x17a0): /* ASUS Xonar U3 */
 		err = snd_xonar_u1_controls_create(mixer);
 		break;
 
diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c
index ef6fa24..c659310 100644
--- a/sound/usb/pcm.c
+++ b/sound/usb/pcm.c
@@ -46,6 +46,9 @@
 	int frame_diff;
 	int est_delay;
 
+	if (!subs->last_delay)
+		return 0; /* short path */
+
 	current_frame_number = usb_get_current_frame_number(subs->dev);
 	/*
 	 * HCD implementations use different widths, use lower 8 bits.
@@ -75,7 +78,8 @@
 		return SNDRV_PCM_POS_XRUN;
 	spin_lock(&subs->lock);
 	hwptr_done = subs->hwptr_done;
-	substream->runtime->delay = snd_usb_pcm_delay(subs,
+	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+		substream->runtime->delay = snd_usb_pcm_delay(subs,
 						substream->runtime->rate);
 	spin_unlock(&subs->lock);
 	return hwptr_done / (substream->runtime->frame_bits >> 3);
@@ -173,11 +177,8 @@
 {
 	struct usb_device *dev = chip->dev;
 	unsigned char data[1];
-	unsigned int ep;
 	int err;
 
-	ep = get_endpoint(alts, 0)->bEndpointAddress;
-
 	data[0] = 1;
 	if ((err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC2_CS_CUR,
 				   USB_TYPE_CLASS | USB_RECIP_ENDPOINT | USB_DIR_OUT,
@@ -214,7 +215,7 @@
 	}
 }
 
-static int start_endpoints(struct snd_usb_substream *subs, int can_sleep)
+static int start_endpoints(struct snd_usb_substream *subs, bool can_sleep)
 {
 	int err;
 
@@ -266,16 +267,18 @@
 	return 0;
 }
 
-static void stop_endpoints(struct snd_usb_substream *subs,
-			   int force, int can_sleep, int wait)
+static void stop_endpoints(struct snd_usb_substream *subs, bool wait)
 {
 	if (test_and_clear_bit(SUBSTREAM_FLAG_SYNC_EP_STARTED, &subs->flags))
-		snd_usb_endpoint_stop(subs->sync_endpoint,
-				      force, can_sleep, wait);
+		snd_usb_endpoint_stop(subs->sync_endpoint);
 
 	if (test_and_clear_bit(SUBSTREAM_FLAG_DATA_EP_STARTED, &subs->flags))
-		snd_usb_endpoint_stop(subs->data_endpoint,
-				      force, can_sleep, wait);
+		snd_usb_endpoint_stop(subs->data_endpoint);
+
+	if (wait) {
+		snd_usb_endpoint_sync_pending_stop(subs->sync_endpoint);
+		snd_usb_endpoint_sync_pending_stop(subs->data_endpoint);
+	}
 }
 
 static int deactivate_endpoints(struct snd_usb_substream *subs)
@@ -359,6 +362,19 @@
 	attr = fmt->ep_attr & USB_ENDPOINT_SYNCTYPE;
 
 	switch (subs->stream->chip->usb_id) {
+	case USB_ID(0x0763, 0x2030): /* M-Audio Fast Track C400 */
+		if (is_playback) {
+			implicit_fb = 1;
+			ep = 0x81;
+			iface = usb_ifnum_to_if(dev, 3);
+
+			if (!iface || iface->num_altsetting == 0)
+				return -EINVAL;
+
+			alts = &iface->altsetting[1];
+			goto add_sync_ep;
+		}
+		break;
 	case USB_ID(0x0763, 0x2080): /* M-Audio FastTrack Ultra */
 	case USB_ID(0x0763, 0x2081):
 		if (is_playback) {
@@ -381,7 +397,7 @@
 		/* ... and check descriptor size before accessing bSynchAddress
 		   because there is a version of the SB Audigy 2 NX firmware lacking
 		   the audio fields in the endpoint descriptors */
-		if ((get_endpoint(alts, 1)->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != 0x01 ||
+		if ((get_endpoint(alts, 1)->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_ISOC ||
 		    (get_endpoint(alts, 1)->bLength >= USB_DT_ENDPOINT_AUDIO_SIZE &&
 		     get_endpoint(alts, 1)->bSynchAddress != 0 &&
 		     !implicit_fb)) {
@@ -438,6 +454,103 @@
 }
 
 /*
+ * Return the score of matching two audioformats.
+ * Veto the audioformat if:
+ * - It has no channels for some reason.
+ * - Requested PCM format is not supported.
+ * - Requested sample rate is not supported.
+ */
+static int match_endpoint_audioformats(struct audioformat *fp,
+	struct audioformat *match, int rate,
+	snd_pcm_format_t pcm_format)
+{
+	int i;
+	int score = 0;
+
+	if (fp->channels < 1) {
+		snd_printdd("%s: (fmt @%p) no channels\n", __func__, fp);
+		return 0;
+	}
+
+	if (!(fp->formats & (1ULL << pcm_format))) {
+		snd_printdd("%s: (fmt @%p) no match for format %d\n", __func__,
+			fp, pcm_format);
+		return 0;
+	}
+
+	for (i = 0; i < fp->nr_rates; i++) {
+		if (fp->rate_table[i] == rate) {
+			score++;
+			break;
+		}
+	}
+	if (!score) {
+		snd_printdd("%s: (fmt @%p) no match for rate %d\n", __func__,
+			fp, rate);
+		return 0;
+	}
+
+	if (fp->channels == match->channels)
+		score++;
+
+	snd_printdd("%s: (fmt @%p) score %d\n", __func__, fp, score);
+
+	return score;
+}
+
+/*
+ * Configure the sync ep using the rate and pcm format of the data ep.
+ */
+static int configure_sync_endpoint(struct snd_usb_substream *subs)
+{
+	int ret;
+	struct audioformat *fp;
+	struct audioformat *sync_fp = NULL;
+	int cur_score = 0;
+	int sync_period_bytes = subs->period_bytes;
+	struct snd_usb_substream *sync_subs =
+		&subs->stream->substream[subs->direction ^ 1];
+
+	/* Try to find the best matching audioformat. */
+	list_for_each_entry(fp, &sync_subs->fmt_list, list) {
+		int score = match_endpoint_audioformats(fp, subs->cur_audiofmt,
+			subs->cur_rate, subs->pcm_format);
+
+		if (score > cur_score) {
+			sync_fp = fp;
+			cur_score = score;
+		}
+	}
+
+	if (unlikely(sync_fp == NULL)) {
+		snd_printk(KERN_ERR "%s: no valid audioformat for sync ep %x found\n",
+			__func__, sync_subs->ep_num);
+		return -EINVAL;
+	}
+
+	/*
+	 * Recalculate the period bytes if channel number differ between
+	 * data and sync ep audioformat.
+	 */
+	if (sync_fp->channels != subs->channels) {
+		sync_period_bytes = (subs->period_bytes / subs->channels) *
+			sync_fp->channels;
+		snd_printdd("%s: adjusted sync ep period bytes (%d -> %d)\n",
+			__func__, subs->period_bytes, sync_period_bytes);
+	}
+
+	ret = snd_usb_endpoint_set_params(subs->sync_endpoint,
+					  subs->pcm_format,
+					  sync_fp->channels,
+					  sync_period_bytes,
+					  subs->cur_rate,
+					  sync_fp,
+					  NULL);
+
+	return ret;
+}
+
+/*
  * configure endpoint params
  *
  * called  during initial setup and upon resume
@@ -447,7 +560,7 @@
 	int ret;
 
 	/* format changed */
-	stop_endpoints(subs, 0, 0, 0);
+	stop_endpoints(subs, true);
 	ret = snd_usb_endpoint_set_params(subs->data_endpoint,
 					  subs->pcm_format,
 					  subs->channels,
@@ -459,13 +572,8 @@
 		return ret;
 
 	if (subs->sync_endpoint)
-		ret = snd_usb_endpoint_set_params(subs->sync_endpoint,
-						  subs->pcm_format,
-						  subs->channels,
-						  subs->period_bytes,
-						  subs->cur_rate,
-						  subs->cur_audiofmt,
-						  NULL);
+		ret = configure_sync_endpoint(subs);
+
 	return ret;
 }
 
@@ -533,7 +641,7 @@
 	subs->period_bytes = 0;
 	down_read(&subs->stream->chip->shutdown_rwsem);
 	if (!subs->stream->chip->shutdown) {
-		stop_endpoints(subs, 0, 1, 1);
+		stop_endpoints(subs, true);
 		deactivate_endpoints(subs);
 	}
 	up_read(&subs->stream->chip->shutdown_rwsem);
@@ -608,7 +716,7 @@
 	/* for playback, submit the URBs now; otherwise, the first hwptr_done
 	 * updates for all URBs would happen at the same time when starting */
 	if (subs->direction == SNDRV_PCM_STREAM_PLAYBACK)
-		ret = start_endpoints(subs, 1);
+		ret = start_endpoints(subs, true);
 
  unlock:
 	up_read(&subs->stream->chip->shutdown_rwsem);
@@ -1013,7 +1121,7 @@
 	struct snd_usb_stream *as = snd_pcm_substream_chip(substream);
 	struct snd_usb_substream *subs = &as->substream[direction];
 
-	stop_endpoints(subs, 0, 0, 0);
+	stop_endpoints(subs, true);
 
 	if (!as->chip->shutdown && subs->interface >= 0) {
 		usb_set_interface(subs->dev, subs->interface, 0);
@@ -1195,6 +1303,9 @@
 		return;
 
 	spin_lock_irqsave(&subs->lock, flags);
+	if (!subs->last_delay)
+		goto out; /* short path */
+
 	est_delay = snd_usb_pcm_delay(subs, runtime->rate);
 	/* update delay with exact number of samples played */
 	if (processed > subs->last_delay)
@@ -1212,6 +1323,15 @@
 		snd_printk(KERN_DEBUG "delay: estimated %d, actual %d\n",
 			est_delay, subs->last_delay);
 
+	if (!subs->running) {
+		/* update last_frame_number for delay counting here since
+		 * prepare_playback_urb won't be called during pause
+		 */
+		subs->last_frame_number =
+			usb_get_current_frame_number(subs->dev) & 0xff;
+	}
+
+ out:
 	spin_unlock_irqrestore(&subs->lock, flags);
 }
 
@@ -1248,12 +1368,13 @@
 		subs->running = 1;
 		return 0;
 	case SNDRV_PCM_TRIGGER_STOP:
-		stop_endpoints(subs, 0, 0, 0);
+		stop_endpoints(subs, false);
 		subs->running = 0;
 		return 0;
 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
 		subs->data_endpoint->prepare_data_urb = NULL;
-		subs->data_endpoint->retire_data_urb = NULL;
+		/* keep retire_data_urb for delay calculation */
+		subs->data_endpoint->retire_data_urb = retire_playback_urb;
 		subs->running = 0;
 		return 0;
 	}
@@ -1269,7 +1390,7 @@
 
 	switch (cmd) {
 	case SNDRV_PCM_TRIGGER_START:
-		err = start_endpoints(subs, 0);
+		err = start_endpoints(subs, false);
 		if (err < 0)
 			return err;
 
@@ -1277,7 +1398,7 @@
 		subs->running = 1;
 		return 0;
 	case SNDRV_PCM_TRIGGER_STOP:
-		stop_endpoints(subs, 0, 0, 0);
+		stop_endpoints(subs, false);
 		subs->running = 0;
 		return 0;
 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h
index 88d8ceb..49f9af9 100644
--- a/sound/usb/quirks-table.h
+++ b/sound/usb/quirks-table.h
@@ -1457,6 +1457,40 @@
 	}
 },
 {
+	/* Advanced mode of the Roland VG-99, with MIDI and 24-bit PCM at 44.1
+	 * kHz. In standard mode, the device has ID 0582:00b3, and offers
+	 * 16-bit PCM at 44.1 kHz with no MIDI.
+	 */
+	USB_DEVICE(0x0582, 0x00b2),
+	.driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
+		.vendor_name = "Roland",
+		.product_name = "VG-99",
+		.ifnum = QUIRK_ANY_INTERFACE,
+		.type = QUIRK_COMPOSITE,
+		.data = (const struct snd_usb_audio_quirk[]) {
+			{
+				.ifnum = 0,
+				.type = QUIRK_AUDIO_STANDARD_INTERFACE
+			},
+			{
+				.ifnum = 1,
+				.type = QUIRK_AUDIO_STANDARD_INTERFACE
+			},
+			{
+				.ifnum = 2,
+				.type = QUIRK_MIDI_FIXED_ENDPOINT,
+				.data = & (const struct snd_usb_midi_endpoint_info) {
+					.out_cables = 0x0003,
+					.in_cables  = 0x0003
+				}
+			},
+			{
+				.ifnum = -1
+			}
+		}
+	}
+},
+{
 	/* Roland SonicCell */
 	USB_DEVICE(0x0582, 0x00c2),
 	.driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
@@ -2163,6 +2197,77 @@
 	}
 },
 {
+	USB_DEVICE_VENDOR_SPEC(0x0763, 0x2030),
+	.driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
+		/* .vendor_name = "M-Audio", */
+		/* .product_name = "Fast Track C400", */
+		.ifnum = QUIRK_ANY_INTERFACE,
+		.type = QUIRK_COMPOSITE,
+		.data = &(const struct snd_usb_audio_quirk[]) {
+			{
+				.ifnum = 1,
+				.type = QUIRK_AUDIO_STANDARD_MIXER,
+			},
+			/* Playback */
+			{
+				.ifnum = 2,
+				.type = QUIRK_AUDIO_FIXED_ENDPOINT,
+				.data = &(const struct audioformat) {
+					.formats = SNDRV_PCM_FMTBIT_S24_3LE,
+					.channels = 6,
+					.iface = 2,
+					.altsetting = 1,
+					.altset_idx = 1,
+					.attributes = UAC_EP_CS_ATTR_SAMPLE_RATE,
+					.endpoint = 0x01,
+					.ep_attr = 0x09,
+					.rates = SNDRV_PCM_RATE_44100 |
+						 SNDRV_PCM_RATE_48000 |
+						 SNDRV_PCM_RATE_88200 |
+						 SNDRV_PCM_RATE_96000,
+					.rate_min = 44100,
+					.rate_max = 96000,
+					.nr_rates = 4,
+					.rate_table = (unsigned int[]) {
+							44100, 48000, 88200, 96000
+					},
+					.clock = 0x81,
+				}
+			},
+			/* Capture */
+			{
+				.ifnum = 3,
+				.type = QUIRK_AUDIO_FIXED_ENDPOINT,
+				.data = &(const struct audioformat) {
+					.formats = SNDRV_PCM_FMTBIT_S24_3LE,
+					.channels = 4,
+					.iface = 3,
+					.altsetting = 1,
+					.altset_idx = 1,
+					.attributes = UAC_EP_CS_ATTR_SAMPLE_RATE,
+					.endpoint = 0x81,
+					.ep_attr = 0x05,
+					.rates = SNDRV_PCM_RATE_44100 |
+						 SNDRV_PCM_RATE_48000 |
+						 SNDRV_PCM_RATE_88200 |
+						 SNDRV_PCM_RATE_96000,
+					.rate_min = 44100,
+					.rate_max = 96000,
+					.nr_rates = 4,
+					.rate_table = (unsigned int[]) {
+						44100, 48000, 88200, 96000
+					},
+					.clock = 0x81,
+				}
+			},
+			/* MIDI */
+			{
+				.ifnum = -1 /* Interface = 4 */
+			}
+		}
+	}
+},
+{
 	USB_DEVICE_VENDOR_SPEC(0x0763, 0x2080),
 	.driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
 		/* .vendor_name = "M-Audio", */
@@ -2880,6 +2985,99 @@
 	}
 },
 
+/* Reloop Play */
+{
+	USB_DEVICE(0x200c, 0x100b),
+	.bInterfaceClass = USB_CLASS_PER_INTERFACE,
+	.driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
+		.ifnum = QUIRK_ANY_INTERFACE,
+		.type = QUIRK_COMPOSITE,
+		.data = &(const struct snd_usb_audio_quirk[]) {
+			{
+				.ifnum = 0,
+				.type = QUIRK_AUDIO_STANDARD_MIXER,
+			},
+			{
+				.ifnum = 1,
+				.type = QUIRK_AUDIO_FIXED_ENDPOINT,
+				.data = &(const struct audioformat) {
+					.formats = SNDRV_PCM_FMTBIT_S24_3LE,
+					.channels = 4,
+					.iface = 1,
+					.altsetting = 1,
+					.altset_idx = 1,
+					.attributes = UAC_EP_CS_ATTR_SAMPLE_RATE,
+					.endpoint = 0x01,
+					.ep_attr = USB_ENDPOINT_SYNC_ADAPTIVE,
+					.rates = SNDRV_PCM_RATE_44100 |
+						 SNDRV_PCM_RATE_48000,
+					.rate_min = 44100,
+					.rate_max = 48000,
+					.nr_rates = 2,
+					.rate_table = (unsigned int[]) {
+						44100, 48000
+					}
+				}
+			},
+			{
+				.ifnum = -1
+			}
+		}
+	}
+},
+
+{
+	/*
+	 * Focusrite Scarlett 18i6
+	 *
+	 * Avoid mixer creation, which otherwise fails because some of
+	 * the interface descriptor subtypes for interface 0 are
+	 * unknown.  That should be fixed or worked-around but this at
+	 * least allows the device to be used successfully with a DAW
+	 * and an external mixer.  See comments below about other
+	 * ignored interfaces.
+	 */
+	USB_DEVICE(0x1235, 0x8004),
+	.driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
+		.vendor_name = "Focusrite",
+		.product_name = "Scarlett 18i6",
+		.ifnum = QUIRK_ANY_INTERFACE,
+		.type = QUIRK_COMPOSITE,
+		.data = & (const struct snd_usb_audio_quirk[]) {
+			{
+				/* InterfaceSubClass 1 (Control Device) */
+				.ifnum = 0,
+				.type = QUIRK_IGNORE_INTERFACE
+			},
+			{
+				.ifnum = 1,
+				.type = QUIRK_AUDIO_STANDARD_INTERFACE
+			},
+			{
+				.ifnum = 2,
+				.type = QUIRK_AUDIO_STANDARD_INTERFACE
+			},
+			{
+				/* InterfaceSubClass 1 (Control Device) */
+				.ifnum = 3,
+				.type = QUIRK_IGNORE_INTERFACE
+			},
+			{
+				.ifnum = 4,
+				.type = QUIRK_MIDI_STANDARD_INTERFACE
+			},
+			{
+				/* InterfaceSubClass 1 (Device Firmware Update) */
+				.ifnum = 5,
+				.type = QUIRK_IGNORE_INTERFACE
+			},
+			{
+				.ifnum = -1
+			}
+		}
+	}
+},
+
 {
 	/*
 	 * Some USB MIDI devices don't have an audio control interface,
diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c
index 0f58b4b..007fcec 100644
--- a/sound/usb/quirks.c
+++ b/sound/usb/quirks.c
@@ -675,7 +675,7 @@
  */
 int snd_usb_is_big_endian_format(struct snd_usb_audio *chip, struct audioformat *fp)
 {
-	/* it depends on altsetting wether the device is big-endian or not */
+	/* it depends on altsetting whether the device is big-endian or not */
 	switch (chip->usb_id) {
 	case USB_ID(0x0763, 0x2001): /* M-Audio Quattro: captured data only */
 		if (fp->altsetting == 2 || fp->altsetting == 3 ||
diff --git a/sound/usb/stream.c b/sound/usb/stream.c
index 1de0c8c..ad181d5 100644
--- a/sound/usb/stream.c
+++ b/sound/usb/stream.c
@@ -23,6 +23,8 @@
 
 #include <sound/core.h>
 #include <sound/pcm.h>
+#include <sound/control.h>
+#include <sound/tlv.h>
 
 #include "usbaudio.h"
 #include "card.h"
@@ -47,6 +49,7 @@
 	list_for_each_safe(p, n, &subs->fmt_list) {
 		struct audioformat *fp = list_entry(p, struct audioformat, list);
 		kfree(fp->rate_table);
+		kfree(fp->chmap);
 		kfree(fp);
 	}
 	kfree(subs->rate_list.list);
@@ -99,6 +102,206 @@
 	subs->num_formats++;
 	subs->fmt_type = fp->fmt_type;
 	subs->ep_num = fp->endpoint;
+	if (fp->channels > subs->channels_max)
+		subs->channels_max = fp->channels;
+}
+
+/* kctl callbacks for usb-audio channel maps */
+static int usb_chmap_ctl_info(struct snd_kcontrol *kcontrol,
+			      struct snd_ctl_elem_info *uinfo)
+{
+	struct snd_pcm_chmap *info = snd_kcontrol_chip(kcontrol);
+	struct snd_usb_substream *subs = info->private_data;
+
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+	uinfo->count = subs->channels_max;
+	uinfo->value.integer.min = 0;
+	uinfo->value.integer.max = SNDRV_CHMAP_LAST;
+	return 0;
+}
+
+/* check whether a duplicated entry exists in the audiofmt list */
+static bool have_dup_chmap(struct snd_usb_substream *subs,
+			   struct audioformat *fp)
+{
+	struct list_head *p;
+
+	for (p = fp->list.prev; p != &subs->fmt_list; p = p->prev) {
+		struct audioformat *prev;
+		prev = list_entry(p, struct audioformat, list);
+		if (prev->chmap &&
+		    !memcmp(prev->chmap, fp->chmap, sizeof(*fp->chmap)))
+			return true;
+	}
+	return false;
+}
+
+static int usb_chmap_ctl_tlv(struct snd_kcontrol *kcontrol, int op_flag,
+			     unsigned int size, unsigned int __user *tlv)
+{
+	struct snd_pcm_chmap *info = snd_kcontrol_chip(kcontrol);
+	struct snd_usb_substream *subs = info->private_data;
+	struct audioformat *fp;
+	unsigned int __user *dst;
+	int count = 0;
+
+	if (size < 8)
+		return -ENOMEM;
+	if (put_user(SNDRV_CTL_TLVT_CONTAINER, tlv))
+		return -EFAULT;
+	size -= 8;
+	dst = tlv + 2;
+	list_for_each_entry(fp, &subs->fmt_list, list) {
+		int i, ch_bytes;
+
+		if (!fp->chmap)
+			continue;
+		if (have_dup_chmap(subs, fp))
+			continue;
+		/* copy the entry */
+		ch_bytes = fp->chmap->channels * 4;
+		if (size < 8 + ch_bytes)
+			return -ENOMEM;
+		if (put_user(SNDRV_CTL_TLVT_CHMAP_FIXED, dst) ||
+		    put_user(ch_bytes, dst + 1))
+			return -EFAULT;
+		dst += 2;
+		for (i = 0; i < fp->chmap->channels; i++, dst++) {
+			if (put_user(fp->chmap->map[i], dst))
+				return -EFAULT;
+		}
+
+		count += 8 + ch_bytes;
+		size -= 8 + ch_bytes;
+	}
+	if (put_user(count, tlv + 1))
+		return -EFAULT;
+	return 0;
+}
+
+static int usb_chmap_ctl_get(struct snd_kcontrol *kcontrol,
+			     struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_pcm_chmap *info = snd_kcontrol_chip(kcontrol);
+	struct snd_usb_substream *subs = info->private_data;
+	struct snd_pcm_chmap_elem *chmap = NULL;
+	int i;
+
+	memset(ucontrol->value.integer.value, 0,
+	       sizeof(ucontrol->value.integer.value));
+	if (subs->cur_audiofmt)
+		chmap = subs->cur_audiofmt->chmap;
+	if (chmap) {
+		for (i = 0; i < chmap->channels; i++)
+			ucontrol->value.integer.value[i] = chmap->map[i];
+	}
+	return 0;
+}
+
+/* create a chmap kctl assigned to the given USB substream */
+static int add_chmap(struct snd_pcm *pcm, int stream,
+		     struct snd_usb_substream *subs)
+{
+	struct audioformat *fp;
+	struct snd_pcm_chmap *chmap;
+	struct snd_kcontrol *kctl;
+	int err;
+
+	list_for_each_entry(fp, &subs->fmt_list, list)
+		if (fp->chmap)
+			goto ok;
+	/* no chmap is found */
+	return 0;
+
+ ok:
+	err = snd_pcm_add_chmap_ctls(pcm, stream, NULL, 0, 0, &chmap);
+	if (err < 0)
+		return err;
+
+	/* override handlers */
+	chmap->private_data = subs;
+	kctl = chmap->kctl;
+	kctl->info = usb_chmap_ctl_info;
+	kctl->get = usb_chmap_ctl_get;
+	kctl->tlv.c = usb_chmap_ctl_tlv;
+
+	return 0;
+}
+
+/* convert from USB ChannelConfig bits to ALSA chmap element */
+static struct snd_pcm_chmap_elem *convert_chmap(int channels, unsigned int bits,
+						int protocol)
+{
+	static unsigned int uac1_maps[] = {
+		SNDRV_CHMAP_FL,		/* left front */
+		SNDRV_CHMAP_FR,		/* right front */
+		SNDRV_CHMAP_FC,		/* center front */
+		SNDRV_CHMAP_LFE,	/* LFE */
+		SNDRV_CHMAP_SL,		/* left surround */
+		SNDRV_CHMAP_SR,		/* right surround */
+		SNDRV_CHMAP_FLC,	/* left of center */
+		SNDRV_CHMAP_FRC,	/* right of center */
+		SNDRV_CHMAP_RC,		/* surround */
+		SNDRV_CHMAP_SL,		/* side left */
+		SNDRV_CHMAP_SR,		/* side right */
+		SNDRV_CHMAP_TC,		/* top */
+		0 /* terminator */
+	};
+	static unsigned int uac2_maps[] = {
+		SNDRV_CHMAP_FL,		/* front left */
+		SNDRV_CHMAP_FR,		/* front right */
+		SNDRV_CHMAP_FC,		/* front center */
+		SNDRV_CHMAP_LFE,	/* LFE */
+		SNDRV_CHMAP_RL,		/* back left */
+		SNDRV_CHMAP_RR,		/* back right */
+		SNDRV_CHMAP_FLC,	/* front left of center */
+		SNDRV_CHMAP_FRC,	/* front right of center */
+		SNDRV_CHMAP_RC,		/* back center */
+		SNDRV_CHMAP_SL,		/* side left */
+		SNDRV_CHMAP_SR,		/* side right */
+		SNDRV_CHMAP_TC,		/* top center */
+		SNDRV_CHMAP_TFL,	/* top front left */
+		SNDRV_CHMAP_TFC,	/* top front center */
+		SNDRV_CHMAP_TFR,	/* top front right */
+		SNDRV_CHMAP_TRL,	/* top back left */
+		SNDRV_CHMAP_TRC,	/* top back center */
+		SNDRV_CHMAP_TRR,	/* top back right */
+		SNDRV_CHMAP_TFLC,	/* top front left of center */
+		SNDRV_CHMAP_TFRC,	/* top front right of center */
+		SNDRV_CHMAP_LLFE,	/* left LFE */
+		SNDRV_CHMAP_RLFE,	/* right LFE */
+		SNDRV_CHMAP_TSL,	/* top side left */
+		SNDRV_CHMAP_TSR,	/* top side right */
+		SNDRV_CHMAP_BC,		/* bottom center */
+		SNDRV_CHMAP_BLC,	/* bottom left center */
+		SNDRV_CHMAP_BRC,	/* bottom right center */
+		0 /* terminator */
+	};
+	struct snd_pcm_chmap_elem *chmap;
+	const unsigned int *maps;
+	int c;
+
+	if (!bits)
+		return NULL;
+	if (channels > ARRAY_SIZE(chmap->map))
+		return NULL;
+
+	chmap = kzalloc(sizeof(*chmap), GFP_KERNEL);
+	if (!chmap)
+		return NULL;
+
+	maps = protocol == UAC_VERSION_2 ? uac2_maps : uac1_maps;
+	chmap->channels = channels;
+	c = 0;
+	for (; bits && *maps; maps++, bits >>= 1) {
+		if (bits & 1)
+			chmap->map[c++] = *maps;
+	}
+
+	for (; c < channels; c++)
+		chmap->map[c] = SNDRV_CHMAP_UNKNOWN;
+
+	return chmap;
 }
 
 /*
@@ -140,7 +343,7 @@
 		if (err < 0)
 			return err;
 		snd_usb_init_substream(as, stream, fp);
-		return 0;
+		return add_chmap(as->pcm, stream, subs);
 	}
 
 	/* create a new pcm */
@@ -174,7 +377,7 @@
 
 	snd_usb_proc_pcm_format_add(as);
 
-	return 0;
+	return add_chmap(pcm, stream, &as->substream[stream]);
 }
 
 static int parse_uac_endpoint_attributes(struct snd_usb_audio *chip,
@@ -218,8 +421,11 @@
 	return attributes;
 }
 
-static struct uac2_input_terminal_descriptor *
-	snd_usb_find_input_terminal_descriptor(struct usb_host_interface *ctrl_iface,
+/* find an input terminal descriptor (either UAC1 or UAC2) with the given
+ * terminal id
+ */
+static void *
+snd_usb_find_input_terminal_descriptor(struct usb_host_interface *ctrl_iface,
 					       int terminal_id)
 {
 	struct uac2_input_terminal_descriptor *term = NULL;
@@ -261,6 +467,7 @@
 	struct audioformat *fp = NULL;
 	int num, protocol, clock = 0;
 	struct uac_format_type_i_continuous_descriptor *fmt;
+	unsigned int chconfig;
 
 	dev = chip->dev;
 
@@ -300,6 +507,7 @@
 		if (snd_usb_apply_interface_quirk(chip, iface_no, altno))
 			continue;
 
+		chconfig = 0;
 		/* get audio formats */
 		switch (protocol) {
 		default:
@@ -311,6 +519,7 @@
 		case UAC_VERSION_1: {
 			struct uac1_as_header_descriptor *as =
 				snd_usb_find_csint_desc(alts->extra, alts->extralen, NULL, UAC_AS_GENERAL);
+			struct uac_input_terminal_descriptor *iterm;
 
 			if (!as) {
 				snd_printk(KERN_ERR "%d:%u:%d : UAC_AS_GENERAL descriptor not found\n",
@@ -325,6 +534,14 @@
 			}
 
 			format = le16_to_cpu(as->wFormatTag); /* remember the format value */
+
+			iterm = snd_usb_find_input_terminal_descriptor(chip->ctrl_intf,
+								       as->bTerminalLink);
+			if (iterm) {
+				num_channels = iterm->bNrChannels;
+				chconfig = le16_to_cpu(iterm->wChannelConfig);
+			}
+
 			break;
 		}
 
@@ -355,6 +572,7 @@
 									    as->bTerminalLink);
 			if (input_term) {
 				clock = input_term->bCSourceID;
+				chconfig = le32_to_cpu(input_term->bmChannelConfig);
 				break;
 			}
 
@@ -413,13 +631,13 @@
 		fp->ep_attr = get_endpoint(alts, 0)->bmAttributes;
 		fp->datainterval = snd_usb_parse_datainterval(chip, alts);
 		fp->maxpacksize = le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize);
-		/* num_channels is only set for v2 interfaces */
 		fp->channels = num_channels;
 		if (snd_usb_get_speed(dev) == USB_SPEED_HIGH)
 			fp->maxpacksize = (((fp->maxpacksize >> 11) & 3) + 1)
 					* (fp->maxpacksize & 0x7ff);
 		fp->attributes = parse_uac_endpoint_attributes(chip, alts, protocol, iface_no);
 		fp->clock = clock;
+		fp->chmap = convert_chmap(num_channels, chconfig, protocol);
 
 		/* some quirks for attributes here */
 
@@ -455,6 +673,7 @@
 		/* ok, let's parse further... */
 		if (snd_usb_parse_audio_format(chip, fp, format, fmt, stream, alts) < 0) {
 			kfree(fp->rate_table);
+			kfree(fp->chmap);
 			kfree(fp);
 			fp = NULL;
 			continue;
@@ -464,6 +683,7 @@
 		err = snd_usb_add_audio_stream(chip, stream, fp);
 		if (err < 0) {
 			kfree(fp->rate_table);
+			kfree(fp->chmap);
 			kfree(fp);
 			return err;
 		}
diff --git a/sound/usb/usbaudio.h b/sound/usb/usbaudio.h
index ef42797..1ac3fd9 100644
--- a/sound/usb/usbaudio.h
+++ b/sound/usb/usbaudio.h
@@ -56,7 +56,6 @@
 
 	int setup;			/* from the 'device_setup' module param */
 	int nrpacks;			/* from the 'nrpacks' module param */
-	int async_unlink;		/* from the 'async_unlink' module param */
 
 	struct usb_host_interface *ctrl_intf;	/* the audio control interface */
 };
diff --git a/tools/firewire/nosy-dump.c b/tools/firewire/nosy-dump.c
index f93b776..3179c71 100644
--- a/tools/firewire/nosy-dump.c
+++ b/tools/firewire/nosy-dump.c
@@ -150,6 +150,8 @@
 
 	/* we put the ack in the subaction struct for easy access. */
 	sa = malloc(sizeof *sa - sizeof sa->packet + length);
+	if (!sa)
+		exit(EXIT_FAILURE);
 	sa->ack = data[length / 4 - 1];
 	sa->length = length;
 	memcpy(&sa->packet, data, length);
@@ -180,6 +182,8 @@
 	}
 
 	t = malloc(sizeof *t);
+	if (!t)
+		exit(EXIT_FAILURE);
 	t->request_node = request_node;
 	t->response_node = response_node;
 	t->tlabel = tlabel;
diff --git a/tools/perf/Documentation/perf-record.txt b/tools/perf/Documentation/perf-record.txt
index b38a1f9..938e890 100644
--- a/tools/perf/Documentation/perf-record.txt
+++ b/tools/perf/Documentation/perf-record.txt
@@ -175,7 +175,7 @@
 
 +
 The option requires at least one branch type among any, any_call, any_ret, ind_call.
-The privilege levels may be ommitted, in which case, the privilege levels of the associated
+The privilege levels may be omitted, in which case, the privilege levels of the associated
 event are applied to the branch filter. Both kernel (k) and hypervisor (hv) privilege
 levels are subject to permissions.  When sampling on multiple events, branch stack sampling
 is enabled for all the sampling events. The sampled branch type is the same for all events.
diff --git a/usr/gen_init_cpio.c b/usr/gen_init_cpio.c
index aca6edc..af8c925 100644
--- a/usr/gen_init_cpio.c
+++ b/usr/gen_init_cpio.c
@@ -405,7 +405,6 @@
 	return new_location;
 }
 
-
 static int cpio_mkfile_line(const char *line)
 {
 	char name[PATH_MAX + 1];